From f96d00029925d43291231a6dce9a490057fc5c33 Mon Sep 17 00:00:00 2001 From: edgelessci Date: Mon, 4 Nov 2024 13:49:03 +0000 Subject: [PATCH] =?UTF-8?q?Deploy=20preview=20for=20PR=20976=20?= =?UTF-8?q?=F0=9F=9B=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pr-preview/pr-976/0.5.html | 44 + pr-preview/pr-976/0.5/architecture.html | 24 + .../architecture/attestation/coordinator.html | 22 + .../architecture/attestation/hardware.html | 22 + .../architecture/attestation/manifest.html | 22 + .../0.5/architecture/attestation/pod-vm.html | 22 + .../attestation/runtime-policies.html | 22 + .../certificates-and-identities/pki.html | 22 + .../0.5/architecture/components/cli.html | 22 + .../architecture/components/coordinator.html | 22 + .../components/init-container.html | 22 + .../architecture/confidential-containers.html | 22 + .../protocols-and-keys.html | 22 + .../network-encryption/sidecar.html | 22 + .../0.5/basics/confidential-containers.html | 45 + pr-preview/pr-976/0.5/basics/features.html | 39 + .../pr-976/0.5/basics/security-benefits.html | 22 + .../pr-976/0.5/category/attestation.html | 22 + .../category/certificates-and-identities.html | 22 + .../pr-976/0.5/category/components.html | 22 + .../0.5/category/network-encryption.html | 22 + pr-preview/pr-976/0.5/deployment.html | 75 + pr-preview/pr-976/0.5/examples.html | 24 + pr-preview/pr-976/0.5/examples/emojivoto.html | 134 ++ pr-preview/pr-976/0.5/getting-started.html | 24 + .../0.5/getting-started/cluster-setup.html | 63 + .../0.5/getting-started/first-steps.html | 22 + .../pr-976/0.5/getting-started/install.html | 25 + pr-preview/pr-976/0.6.html | 44 + pr-preview/pr-976/0.6/about.html | 24 + pr-preview/pr-976/0.6/about/telemetry.html | 36 + pr-preview/pr-976/0.6/architecture.html | 24 + .../pr-976/0.6/architecture/attestation.html | 104 + .../pr-976/0.6/architecture/certificates.html | 84 + .../0.6/basics/confidential-containers.html | 45 + pr-preview/pr-976/0.6/basics/features.html | 39 + .../pr-976/0.6/basics/security-benefits.html | 125 ++ pr-preview/pr-976/0.6/components.html | 68 + .../pr-976/0.6/components/policies.html | 77 + pr-preview/pr-976/0.6/components/runtime.html | 72 + .../pr-976/0.6/components/service-mesh.html | 79 + pr-preview/pr-976/0.6/deployment.html | 102 + pr-preview/pr-976/0.6/examples.html | 24 + pr-preview/pr-976/0.6/examples/emojivoto.html | 148 ++ pr-preview/pr-976/0.6/getting-started.html | 24 + .../0.6/getting-started/cluster-setup.html | 63 + .../pr-976/0.6/getting-started/install.html | 26 + pr-preview/pr-976/0.6/known-limitations.html | 46 + pr-preview/pr-976/0.7.html | 45 + pr-preview/pr-976/0.7/about.html | 24 + pr-preview/pr-976/0.7/about/telemetry.html | 36 + pr-preview/pr-976/0.7/architecture.html | 24 + .../pr-976/0.7/architecture/attestation.html | 104 + .../pr-976/0.7/architecture/certificates.html | 84 + .../0.7/architecture/observability.html | 66 + .../0.7/basics/confidential-containers.html | 45 + pr-preview/pr-976/0.7/basics/features.html | 39 + .../pr-976/0.7/basics/security-benefits.html | 125 ++ pr-preview/pr-976/0.7/components.html | 68 + .../pr-976/0.7/components/policies.html | 77 + pr-preview/pr-976/0.7/components/runtime.html | 72 + .../pr-976/0.7/components/service-mesh.html | 97 + pr-preview/pr-976/0.7/deployment.html | 115 ++ pr-preview/pr-976/0.7/examples.html | 24 + pr-preview/pr-976/0.7/examples/emojivoto.html | 148 ++ .../pr-976/0.7/features-limitations.html | 46 + pr-preview/pr-976/0.7/getting-started.html | 24 + .../0.7/getting-started/cluster-setup.html | 67 + .../pr-976/0.7/getting-started/install.html | 26 + pr-preview/pr-976/0.8.html | 45 + pr-preview/pr-976/0.8/about/telemetry.html | 36 + .../pr-976/0.8/architecture/attestation.html | 104 + .../pr-976/0.8/architecture/certificates.html | 84 + .../0.8/architecture/observability.html | 65 + .../pr-976/0.8/architecture/secrets.html | 39 + .../0.8/basics/confidential-containers.html | 45 + pr-preview/pr-976/0.8/basics/features.html | 39 + .../pr-976/0.8/basics/security-benefits.html | 125 ++ .../pr-976/0.8/components/overview.html | 68 + .../pr-976/0.8/components/policies.html | 77 + pr-preview/pr-976/0.8/components/runtime.html | 72 + .../pr-976/0.8/components/service-mesh.html | 97 + pr-preview/pr-976/0.8/deployment.html | 130 ++ pr-preview/pr-976/0.8/examples/emojivoto.html | 148 ++ .../pr-976/0.8/features-limitations.html | 50 + .../0.8/getting-started/cluster-setup.html | 67 + .../pr-976/0.8/getting-started/install.html | 26 + pr-preview/pr-976/0.8/troubleshooting.html | 100 + pr-preview/pr-976/0.9.html | 45 + pr-preview/pr-976/0.9/about/telemetry.html | 36 + .../pr-976/0.9/architecture/attestation.html | 104 + .../pr-976/0.9/architecture/certificates.html | 84 + .../0.9/architecture/observability.html | 65 + .../pr-976/0.9/architecture/secrets.html | 39 + .../0.9/basics/confidential-containers.html | 45 + pr-preview/pr-976/0.9/basics/features.html | 39 + .../pr-976/0.9/basics/security-benefits.html | 125 ++ .../pr-976/0.9/components/overview.html | 68 + .../pr-976/0.9/components/policies.html | 77 + pr-preview/pr-976/0.9/components/runtime.html | 72 + .../pr-976/0.9/components/service-mesh.html | 97 + pr-preview/pr-976/0.9/deployment.html | 130 ++ pr-preview/pr-976/0.9/examples/emojivoto.html | 148 ++ .../pr-976/0.9/features-limitations.html | 50 + .../0.9/getting-started/cluster-setup.html | 67 + .../pr-976/0.9/getting-started/install.html | 26 + pr-preview/pr-976/0.9/troubleshooting.html | 100 + pr-preview/pr-976/1.0.html | 45 + pr-preview/pr-976/1.0/about/telemetry.html | 36 + .../pr-976/1.0/architecture/attestation.html | 104 + .../pr-976/1.0/architecture/certificates.html | 84 + .../1.0/architecture/observability.html | 65 + .../pr-976/1.0/architecture/secrets.html | 45 + .../1.0/basics/confidential-containers.html | 45 + pr-preview/pr-976/1.0/basics/features.html | 39 + .../pr-976/1.0/basics/security-benefits.html | 125 ++ .../pr-976/1.0/components/overview.html | 68 + .../pr-976/1.0/components/policies.html | 77 + pr-preview/pr-976/1.0/components/runtime.html | 72 + .../pr-976/1.0/components/service-mesh.html | 97 + pr-preview/pr-976/1.0/deployment.html | 130 ++ pr-preview/pr-976/1.0/examples/emojivoto.html | 148 ++ .../pr-976/1.0/features-limitations.html | 50 + .../1.0/getting-started/cluster-setup.html | 67 + .../pr-976/1.0/getting-started/install.html | 26 + pr-preview/pr-976/1.0/troubleshooting.html | 100 + pr-preview/pr-976/404.html | 22 + pr-preview/pr-976/about/telemetry.html | 36 + .../pr-976/architecture/attestation.html | 104 + .../pr-976/architecture/certificates.html | 84 + .../pr-976/architecture/observability.html | 65 + pr-preview/pr-976/architecture/secrets.html | 45 + .../architecture/security-considerations.html | 68 + .../pr-976/assets/css/styles.b5828750.css | 1 + ...evice-b91e917a07f0f2bb082989317a9b053f.svg | 1127 +++++++++++ ...n-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg | 1737 +++++++++++++++++ ...cture-1a05fc2165e5c75a171e7b7832186bc3.svg | 1417 ++++++++++++++ ...nents-dd64f006e7d6b6facb9eb16f1af59d39.svg | 798 ++++++++ ...nents-ea3fb9800d5718d6ab96607ee817c104.svg | 766 ++++++++ ...ncept-c1792eb1b8f3959308512d1e518b0176.svg | 127 ++ ...rawio-a2442a1eeb081612c5ad587a58589ad4.svg | 4 + ...jvoto-3fb48da575d6d4adf76cc90caa35d762.png | Bin 0 -> 269322 bytes ...sonas-0d51d0cc03b37c9f45b914bbea163646.svg | 568 ++++++ ...sonas-1c9f2b217e0b94e0c3057df96d96b3f0.svg | 573 ++++++ ...ntime-c41c29928f42a90474f03213074a5f97.svg | 1376 +++++++++++++ .../tcb-eebc94816125417eaf55b0e5e96bba37.svg | 547 ++++++ .../pr-976/assets/js/014daffb.28613203.js | 1 + .../pr-976/assets/js/018595b3.560dae8b.js | 1 + .../pr-976/assets/js/04102e85.745c04f7.js | 1 + .../pr-976/assets/js/06354bbe.4db69232.js | 1 + .../pr-976/assets/js/06eada7a.0ffd2db0.js | 1 + .../pr-976/assets/js/078f57bf.b2f92c81.js | 1 + .../pr-976/assets/js/098bf236.fb47b956.js | 1 + .../pr-976/assets/js/0a09f1f2.af458bba.js | 1 + .../pr-976/assets/js/0a7a212e.4bfb0b6f.js | 1 + .../pr-976/assets/js/0b1c872d.c7834956.js | 1 + .../pr-976/assets/js/0ba7602a.85a7f1d2.js | 1 + .../pr-976/assets/js/0c24bc66.085b04d6.js | 1 + .../pr-976/assets/js/0e384e19.651e3adc.js | 1 + .../pr-976/assets/js/10257d90.7ee2f98c.js | 1 + .../pr-976/assets/js/1057c3b3.114828df.js | 1 + pr-preview/pr-976/assets/js/1186.8726fdba.js | 1 + .../pr-976/assets/js/137fbf80.8c6cd314.js | 1 + pr-preview/pr-976/assets/js/1477.b147cf3f.js | 1 + .../pr-976/assets/js/14a9ce33.fc32993b.js | 1 + .../pr-976/assets/js/14eb3368.8cb6f0b4.js | 1 + pr-preview/pr-976/assets/js/155.48c4e908.js | 1 + .../pr-976/assets/js/15b9bf06.b97730a3.js | 1 + pr-preview/pr-976/assets/js/165.8f94caaa.js | 2 + .../assets/js/165.8f94caaa.js.LICENSE.txt | 9 + pr-preview/pr-976/assets/js/1689.251eba58.js | 1 + pr-preview/pr-976/assets/js/1711.0c8f9a6a.js | 1 + .../pr-976/assets/js/173fd1a8.8751a104.js | 1 + .../pr-976/assets/js/17896441.7a01a35f.js | 1 + .../pr-976/assets/js/1ab97833.9e49478d.js | 1 + .../pr-976/assets/js/1c9b88ee.ba0039db.js | 1 + .../pr-976/assets/js/1e7c9753.02e56af3.js | 1 + .../pr-976/assets/js/1ea8f7a3.d2d50582.js | 1 + .../pr-976/assets/js/20382dd7.20e8921f.js | 1 + .../pr-976/assets/js/207bb774.442bb435.js | 1 + .../pr-976/assets/js/20e0cfa9.1b701e80.js | 1 + pr-preview/pr-976/assets/js/2130.a7c31b12.js | 1 + .../pr-976/assets/js/21d7c4d4.59195010.js | 1 + pr-preview/pr-976/assets/js/2247.7219b8c6.js | 1 + pr-preview/pr-976/assets/js/2334.619d7d41.js | 1 + pr-preview/pr-976/assets/js/2387.7f9ca256.js | 1 + .../pr-976/assets/js/2496d21b.1c09cf80.js | 1 + .../pr-976/assets/js/250ffcdd.e9b01620.js | 1 + .../pr-976/assets/js/259f95a2.0c3a0ee9.js | 1 + .../pr-976/assets/js/26742c3b.ead769cd.js | 1 + .../pr-976/assets/js/27004ef7.ee187533.js | 1 + .../pr-976/assets/js/270470f6.2a97a5fd.js | 1 + pr-preview/pr-976/assets/js/2763.b71509e9.js | 1 + .../pr-976/assets/js/27a940ba.2b4c52be.js | 1 + .../pr-976/assets/js/27d05faa.4fff9fb7.js | 1 + .../pr-976/assets/js/2a2a0c40.fc2cf12c.js | 1 + .../pr-976/assets/js/2dbe31cc.19015d41.js | 1 + .../pr-976/assets/js/2df6ad32.0df42417.js | 1 + .../pr-976/assets/js/2e82b444.dd4ac86b.js | 1 + .../pr-976/assets/js/327db732.9cf7a097.js | 1 + .../pr-976/assets/js/327e592d.77873d5f.js | 1 + pr-preview/pr-976/assets/js/3364.d54f19c0.js | 1 + .../pr-976/assets/js/35dd9928.876c8b6d.js | 1 + pr-preview/pr-976/assets/js/3624.631ec2ee.js | 1 + .../pr-976/assets/js/3683601e.e3d4185e.js | 1 + pr-preview/pr-976/assets/js/3840.510aef0e.js | 1 + .../pr-976/assets/js/39db4684.7504d8d4.js | 1 + .../pr-976/assets/js/3a77bb3e.ae0e3a69.js | 1 + .../pr-976/assets/js/3d96af17.ef1ae4be.js | 1 + .../pr-976/assets/js/3d9be0cc.1005a9e5.js | 1 + .../pr-976/assets/js/3e02a241.10a2e2ba.js | 1 + .../pr-976/assets/js/41b31679.7dba08fd.js | 1 + pr-preview/pr-976/assets/js/4445.3811e3c0.js | 1 + pr-preview/pr-976/assets/js/4449.bb76b6fa.js | 1 + .../pr-976/assets/js/44b49990.29d0eb8e.js | 1 + .../pr-976/assets/js/45c98560.977c2d08.js | 1 + pr-preview/pr-976/assets/js/484.808d13de.js | 1 + .../pr-976/assets/js/48f2f8ef.3afa4ead.js | 1 + .../pr-976/assets/js/4ce6baab.ddbc3709.js | 1 + .../pr-976/assets/js/4cf3063f.ffa75230.js | 1 + .../pr-976/assets/js/4eec459c.883ecb5e.js | 1 + .../pr-976/assets/js/4f453872.072c6bcc.js | 1 + .../pr-976/assets/js/4fb24623.4962c99a.js | 1 + .../pr-976/assets/js/50474e10.3e18d095.js | 1 + .../pr-976/assets/js/51513a8d.cdeb6e9c.js | 1 + .../pr-976/assets/js/54c6367b.8cc47335.js | 1 + pr-preview/pr-976/assets/js/5606.5910c299.js | 1 + .../pr-976/assets/js/567e04ee.8a836253.js | 1 + .../pr-976/assets/js/5aa90309.c36a9a65.js | 1 + .../pr-976/assets/js/5c6fa5d3.98b892e1.js | 1 + .../pr-976/assets/js/5e95c892.c959e509.js | 1 + .../pr-976/assets/js/5eab7755.b121b0e1.js | 1 + .../pr-976/assets/js/5ecc20d3.560917b7.js | 1 + .../pr-976/assets/js/5f998a2f.761e3939.js | 1 + .../pr-976/assets/js/6009a9aa.e37420d5.js | 1 + .../pr-976/assets/js/6100b425.8c972462.js | 1 + .../pr-976/assets/js/640cb024.2e039806.js | 1 + .../pr-976/assets/js/642ed902.37cf76bd.js | 1 + pr-preview/pr-976/assets/js/6452.9f5d0a8d.js | 1 + .../pr-976/assets/js/6478b99f.23cfdac2.js | 1 + .../pr-976/assets/js/64d58a39.1a4a9610.js | 1 + .../pr-976/assets/js/6507182a.417f4320.js | 1 + pr-preview/pr-976/assets/js/6790.b101800c.js | 1 + .../pr-976/assets/js/68be920e.9f8df8ee.js | 1 + .../pr-976/assets/js/6903d0da.aed38602.js | 1 + pr-preview/pr-976/assets/js/6912.4cd2abc1.js | 2 + .../assets/js/6912.4cd2abc1.js.LICENSE.txt | 7 + .../pr-976/assets/js/69ec948c.89847346.js | 1 + .../pr-976/assets/js/6a46f748.9218759d.js | 1 + .../pr-976/assets/js/6fc50b39.46b4da2f.js | 1 + pr-preview/pr-976/assets/js/7032.dded9666.js | 1 + pr-preview/pr-976/assets/js/7060.28ce0df1.js | 1 + pr-preview/pr-976/assets/js/7357.6aa95f42.js | 1 + .../pr-976/assets/js/75100f0d.9f8f9b89.js | 1 + .../pr-976/assets/js/75d659e1.2d71da15.js | 1 + .../pr-976/assets/js/7680d80e.2894bfc5.js | 1 + pr-preview/pr-976/assets/js/7723.83dacf97.js | 1 + .../pr-976/assets/js/790f17e8.a5baddba.js | 1 + .../pr-976/assets/js/7bd8db71.3f1b000d.js | 1 + .../pr-976/assets/js/7d1602ac.42782481.js | 1 + .../pr-976/assets/js/7edb0f0d.85693ccb.js | 1 + .../pr-976/assets/js/7f3f1ff7.009aeec6.js | 1 + .../pr-976/assets/js/8132774f.2680af68.js | 1 + pr-preview/pr-976/assets/js/8159.4e759f62.js | 1 + pr-preview/pr-976/assets/js/8174.61ff22d1.js | 1 + pr-preview/pr-976/assets/js/8379.c80faf06.js | 1 + pr-preview/pr-976/assets/js/8496.19c721e5.js | 1 + pr-preview/pr-976/assets/js/8731.c272170f.js | 1 + pr-preview/pr-976/assets/js/890.8531ec8c.js | 1 + .../pr-976/assets/js/89486910.2245dcd7.js | 1 + .../pr-976/assets/js/8965cb1f.7fa15643.js | 1 + .../pr-976/assets/js/896da145.a1a53ce3.js | 1 + pr-preview/pr-976/assets/js/8998.5c85576b.js | 1 + .../pr-976/assets/js/89a4f0ca.91bcaa30.js | 1 + .../pr-976/assets/js/8c9a8791.46416e05.js | 1 + .../pr-976/assets/js/8dca39c2.b4b59560.js | 1 + .../pr-976/assets/js/8f09b871.5bb7d3d7.js | 1 + .../pr-976/assets/js/9040bbc8.06d43bf0.js | 1 + .../pr-976/assets/js/90af0d0d.00afd3dd.js | 1 + .../pr-976/assets/js/9152dfbd.3bdd0a61.js | 1 + pr-preview/pr-976/assets/js/921.5ff0c680.js | 1 + .../pr-976/assets/js/927cf76e.6f4c28bf.js | 1 + pr-preview/pr-976/assets/js/9368.5da20e84.js | 1 + .../pr-976/assets/js/9397123b.2f0b3891.js | 1 + .../pr-976/assets/js/9620adf5.133d730b.js | 1 + pr-preview/pr-976/assets/js/9664.5583cedf.js | 1 + .../pr-976/assets/js/966b9f47.b375a919.js | 1 + .../pr-976/assets/js/969019ea.32517b56.js | 1 + pr-preview/pr-976/assets/js/9720.8e4604d2.js | 1 + pr-preview/pr-976/assets/js/9802.bb09c288.js | 1 + .../pr-976/assets/js/98367cce.28290f99.js | 1 + pr-preview/pr-976/assets/js/9875.78d2cec3.js | 1 + .../pr-976/assets/js/989c6d03.4ac694c4.js | 1 + .../pr-976/assets/js/9a06ae3d.046ea467.js | 1 + .../pr-976/assets/js/9a28f5c4.01963c55.js | 1 + .../pr-976/assets/js/9a99019d.7c69ee4c.js | 1 + .../pr-976/assets/js/9c8ec574.c337425b.js | 1 + .../pr-976/assets/js/9ccb1fc6.873740e8.js | 1 + .../pr-976/assets/js/9ce1fd56.9821471c.js | 1 + .../pr-976/assets/js/9d9e06f4.34f01e43.js | 1 + .../pr-976/assets/js/9d9f8394.950345c7.js | 1 + .../pr-976/assets/js/a0a1fd3b.d49c396c.js | 1 + .../pr-976/assets/js/a0a4ec6e.e66a8111.js | 1 + .../pr-976/assets/js/a161c24f.491f18fc.js | 1 + .../pr-976/assets/js/a2899f6e.7ec951c7.js | 1 + .../pr-976/assets/js/a3713279.cb16cfe2.js | 1 + .../pr-976/assets/js/a66d714b.bad912b3.js | 1 + .../pr-976/assets/js/a71cbd8f.fee2c6c8.js | 1 + .../pr-976/assets/js/a7bd4aaa.3effeeae.js | 1 + .../pr-976/assets/js/a86a94ce.db57590c.js | 1 + .../pr-976/assets/js/a94703ab.e63edbb7.js | 1 + .../pr-976/assets/js/aa0f7abf.62cf75e4.js | 1 + .../pr-976/assets/js/aaec90ae.14899e6c.js | 1 + .../pr-976/assets/js/aafa6b90.3f7af2d6.js | 1 + .../pr-976/assets/js/ab09c42c.54be6c5a.js | 1 + .../pr-976/assets/js/aba21aa0.0f4e95f1.js | 1 + .../pr-976/assets/js/abfbdc79.2729a342.js | 1 + .../pr-976/assets/js/ac3e6feb.c8d4aa8b.js | 1 + .../pr-976/assets/js/ae6c0c68.92c1ee41.js | 1 + .../pr-976/assets/js/b0cb3eb4.99a5cbf3.js | 1 + .../pr-976/assets/js/b20d32fc.e428ea64.js | 1 + .../pr-976/assets/js/b27c3275.a5dbc455.js | 1 + .../pr-976/assets/js/b3916dd3.30abb5e2.js | 1 + .../pr-976/assets/js/b3a88889.ef306daa.js | 1 + .../pr-976/assets/js/b451d7c3.99a4d0de.js | 1 + .../pr-976/assets/js/ba2406d8.4e6c54c4.js | 1 + .../pr-976/assets/js/baef5027.95910e40.js | 1 + .../pr-976/assets/js/bced0f3c.110450d8.js | 1 + .../pr-976/assets/js/bd029836.96853ab4.js | 1 + .../pr-976/assets/js/bd625abb.43f2f678.js | 1 + .../pr-976/assets/js/bde25e2b.2917f0f7.js | 1 + .../pr-976/assets/js/bf823012.0ed024b4.js | 1 + .../pr-976/assets/js/c09e49b9.9ff206ce.js | 1 + .../pr-976/assets/js/c1fac065.af80720c.js | 1 + .../pr-976/assets/js/c2ce05d5.83575dcd.js | 1 + .../pr-976/assets/js/c3a9f66a.6efdd9fb.js | 1 + .../pr-976/assets/js/c4b4ced0.cc4aaa5d.js | 1 + .../pr-976/assets/js/c7462af2.8edc4250.js | 1 + .../pr-976/assets/js/ca5b6702.a3b16546.js | 1 + .../pr-976/assets/js/cdb2b1a5.cee59a12.js | 1 + .../pr-976/assets/js/cf49aa2b.89d9d490.js | 1 + .../pr-976/assets/js/d1a11e04.8df8afb2.js | 1 + .../pr-976/assets/js/d2630e76.be1d4782.js | 1 + .../pr-976/assets/js/d580a1fd.d3605f1d.js | 1 + .../pr-976/assets/js/d77304ba.f1bec1ec.js | 1 + .../pr-976/assets/js/dacf14a0.c33c9e89.js | 1 + .../pr-976/assets/js/de615ffd.ef11da9f.js | 1 + .../pr-976/assets/js/dfd9c366.af676094.js | 1 + .../pr-976/assets/js/e1e441c9.d7ad6ed8.js | 1 + .../pr-976/assets/js/e277c26a.364edfbf.js | 1 + .../pr-976/assets/js/e2b3b970.151dea1f.js | 1 + .../pr-976/assets/js/e446d98f.5906d2b8.js | 1 + .../pr-976/assets/js/e55aefba.57f034d8.js | 1 + .../pr-976/assets/js/e8480491.72a2b553.js | 1 + .../pr-976/assets/js/e9dbdd13.305d71e2.js | 1 + .../pr-976/assets/js/edcfcef8.efca5aef.js | 1 + .../pr-976/assets/js/ee8b52db.b69e4030.js | 1 + .../pr-976/assets/js/f2348f57.3db099bc.js | 1 + .../pr-976/assets/js/f31967d8.71b71235.js | 1 + .../pr-976/assets/js/f36abd57.48e08f44.js | 1 + .../pr-976/assets/js/f47dd6e5.ecf0ed95.js | 1 + .../pr-976/assets/js/f5272de0.78413199.js | 1 + .../pr-976/assets/js/f593d43a.93a070a0.js | 1 + .../pr-976/assets/js/f65fea7a.7a92e4f1.js | 1 + .../pr-976/assets/js/fbad2ec0.afc757e3.js | 1 + .../pr-976/assets/js/fbad79f4.6e49be6a.js | 1 + .../pr-976/assets/js/fbcf0d59.08f1ee86.js | 1 + .../pr-976/assets/js/fda633d9.f148ee0b.js | 1 + pr-preview/pr-976/assets/js/main.bd30bfc7.js | 2 + .../assets/js/main.bd30bfc7.js.LICENSE.txt | 133 ++ .../pr-976/assets/js/runtime~main.7d4c04c9.js | 1 + .../basics/confidential-containers.html | 45 + pr-preview/pr-976/basics/features.html | 39 + .../pr-976/basics/security-benefits.html | 125 ++ pr-preview/pr-976/components/overview.html | 68 + pr-preview/pr-976/components/policies.html | 85 + pr-preview/pr-976/components/runtime.html | 77 + .../pr-976/components/service-mesh.html | 97 + pr-preview/pr-976/deployment.html | 140 ++ pr-preview/pr-976/examples/emojivoto.html | 146 ++ pr-preview/pr-976/features-limitations.html | 50 + .../pr-976/getting-started/bare-metal.html | 36 + .../pr-976/getting-started/cluster-setup.html | 64 + .../pr-976/getting-started/install.html | 26 + .../img/GitHub-Banner_Contrast_2024.gif | Bin 0 -> 1683202 bytes pr-preview/pr-976/img/concept.svg | 127 ++ pr-preview/pr-976/img/favicon.ico | Bin 0 -> 935 bytes pr-preview/pr-976/img/logos/contrast_icon.svg | 18 + pr-preview/pr-976/index.html | 45 + pr-preview/pr-976/next.html | 45 + pr-preview/pr-976/next/about/telemetry.html | 36 + .../pr-976/next/architecture/attestation.html | 104 + .../next/architecture/certificates.html | 84 + .../next/architecture/observability.html | 65 + .../pr-976/next/architecture/secrets.html | 56 + .../architecture/security-considerations.html | 68 + .../next/basics/confidential-containers.html | 45 + pr-preview/pr-976/next/basics/features.html | 39 + .../pr-976/next/basics/security-benefits.html | 125 ++ .../pr-976/next/components/overview.html | 68 + .../pr-976/next/components/policies.html | 85 + .../pr-976/next/components/runtime.html | 77 + .../pr-976/next/components/service-mesh.html | 97 + pr-preview/pr-976/next/deployment.html | 140 ++ .../pr-976/next/examples/emojivoto.html | 146 ++ .../pr-976/next/features-limitations.html | 51 + .../next/getting-started/bare-metal.html | 36 + .../next/getting-started/cluster-setup.html | 64 + .../pr-976/next/getting-started/install.html | 26 + pr-preview/pr-976/next/troubleshooting.html | 100 + .../pr-976/search-index-docs-default-0.5.json | 1 + .../pr-976/search-index-docs-default-0.6.json | 1 + .../pr-976/search-index-docs-default-0.7.json | 1 + .../pr-976/search-index-docs-default-0.8.json | 1 + .../pr-976/search-index-docs-default-0.9.json | 1 + .../pr-976/search-index-docs-default-1.0.json | 1 + .../pr-976/search-index-docs-default-1.1.json | 1 + .../search-index-docs-default-current.json | 1 + pr-preview/pr-976/sitemap.xml | 1 + pr-preview/pr-976/troubleshooting.html | 100 + 420 files changed, 20453 insertions(+) create mode 100644 pr-preview/pr-976/0.5.html create mode 100644 pr-preview/pr-976/0.5/architecture.html create mode 100644 pr-preview/pr-976/0.5/architecture/attestation/coordinator.html create mode 100644 pr-preview/pr-976/0.5/architecture/attestation/hardware.html create mode 100644 pr-preview/pr-976/0.5/architecture/attestation/manifest.html create mode 100644 pr-preview/pr-976/0.5/architecture/attestation/pod-vm.html create mode 100644 pr-preview/pr-976/0.5/architecture/attestation/runtime-policies.html create mode 100644 pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki.html create mode 100644 pr-preview/pr-976/0.5/architecture/components/cli.html create mode 100644 pr-preview/pr-976/0.5/architecture/components/coordinator.html create mode 100644 pr-preview/pr-976/0.5/architecture/components/init-container.html create mode 100644 pr-preview/pr-976/0.5/architecture/confidential-containers.html create mode 100644 pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys.html create mode 100644 pr-preview/pr-976/0.5/architecture/network-encryption/sidecar.html create mode 100644 pr-preview/pr-976/0.5/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/0.5/basics/features.html create mode 100644 pr-preview/pr-976/0.5/basics/security-benefits.html create mode 100644 pr-preview/pr-976/0.5/category/attestation.html create mode 100644 pr-preview/pr-976/0.5/category/certificates-and-identities.html create mode 100644 pr-preview/pr-976/0.5/category/components.html create mode 100644 pr-preview/pr-976/0.5/category/network-encryption.html create mode 100644 pr-preview/pr-976/0.5/deployment.html create mode 100644 pr-preview/pr-976/0.5/examples.html create mode 100644 pr-preview/pr-976/0.5/examples/emojivoto.html create mode 100644 pr-preview/pr-976/0.5/getting-started.html create mode 100644 pr-preview/pr-976/0.5/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/0.5/getting-started/first-steps.html create mode 100644 pr-preview/pr-976/0.5/getting-started/install.html create mode 100644 pr-preview/pr-976/0.6.html create mode 100644 pr-preview/pr-976/0.6/about.html create mode 100644 pr-preview/pr-976/0.6/about/telemetry.html create mode 100644 pr-preview/pr-976/0.6/architecture.html create mode 100644 pr-preview/pr-976/0.6/architecture/attestation.html create mode 100644 pr-preview/pr-976/0.6/architecture/certificates.html create mode 100644 pr-preview/pr-976/0.6/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/0.6/basics/features.html create mode 100644 pr-preview/pr-976/0.6/basics/security-benefits.html create mode 100644 pr-preview/pr-976/0.6/components.html create mode 100644 pr-preview/pr-976/0.6/components/policies.html create mode 100644 pr-preview/pr-976/0.6/components/runtime.html create mode 100644 pr-preview/pr-976/0.6/components/service-mesh.html create mode 100644 pr-preview/pr-976/0.6/deployment.html create mode 100644 pr-preview/pr-976/0.6/examples.html create mode 100644 pr-preview/pr-976/0.6/examples/emojivoto.html create mode 100644 pr-preview/pr-976/0.6/getting-started.html create mode 100644 pr-preview/pr-976/0.6/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/0.6/getting-started/install.html create mode 100644 pr-preview/pr-976/0.6/known-limitations.html create mode 100644 pr-preview/pr-976/0.7.html create mode 100644 pr-preview/pr-976/0.7/about.html create mode 100644 pr-preview/pr-976/0.7/about/telemetry.html create mode 100644 pr-preview/pr-976/0.7/architecture.html create mode 100644 pr-preview/pr-976/0.7/architecture/attestation.html create mode 100644 pr-preview/pr-976/0.7/architecture/certificates.html create mode 100644 pr-preview/pr-976/0.7/architecture/observability.html create mode 100644 pr-preview/pr-976/0.7/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/0.7/basics/features.html create mode 100644 pr-preview/pr-976/0.7/basics/security-benefits.html create mode 100644 pr-preview/pr-976/0.7/components.html create mode 100644 pr-preview/pr-976/0.7/components/policies.html create mode 100644 pr-preview/pr-976/0.7/components/runtime.html create mode 100644 pr-preview/pr-976/0.7/components/service-mesh.html create mode 100644 pr-preview/pr-976/0.7/deployment.html create mode 100644 pr-preview/pr-976/0.7/examples.html create mode 100644 pr-preview/pr-976/0.7/examples/emojivoto.html create mode 100644 pr-preview/pr-976/0.7/features-limitations.html create mode 100644 pr-preview/pr-976/0.7/getting-started.html create mode 100644 pr-preview/pr-976/0.7/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/0.7/getting-started/install.html create mode 100644 pr-preview/pr-976/0.8.html create mode 100644 pr-preview/pr-976/0.8/about/telemetry.html create mode 100644 pr-preview/pr-976/0.8/architecture/attestation.html create mode 100644 pr-preview/pr-976/0.8/architecture/certificates.html create mode 100644 pr-preview/pr-976/0.8/architecture/observability.html create mode 100644 pr-preview/pr-976/0.8/architecture/secrets.html create mode 100644 pr-preview/pr-976/0.8/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/0.8/basics/features.html create mode 100644 pr-preview/pr-976/0.8/basics/security-benefits.html create mode 100644 pr-preview/pr-976/0.8/components/overview.html create mode 100644 pr-preview/pr-976/0.8/components/policies.html create mode 100644 pr-preview/pr-976/0.8/components/runtime.html create mode 100644 pr-preview/pr-976/0.8/components/service-mesh.html create mode 100644 pr-preview/pr-976/0.8/deployment.html create mode 100644 pr-preview/pr-976/0.8/examples/emojivoto.html create mode 100644 pr-preview/pr-976/0.8/features-limitations.html create mode 100644 pr-preview/pr-976/0.8/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/0.8/getting-started/install.html create mode 100644 pr-preview/pr-976/0.8/troubleshooting.html create mode 100644 pr-preview/pr-976/0.9.html create mode 100644 pr-preview/pr-976/0.9/about/telemetry.html create mode 100644 pr-preview/pr-976/0.9/architecture/attestation.html create mode 100644 pr-preview/pr-976/0.9/architecture/certificates.html create mode 100644 pr-preview/pr-976/0.9/architecture/observability.html create mode 100644 pr-preview/pr-976/0.9/architecture/secrets.html create mode 100644 pr-preview/pr-976/0.9/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/0.9/basics/features.html create mode 100644 pr-preview/pr-976/0.9/basics/security-benefits.html create mode 100644 pr-preview/pr-976/0.9/components/overview.html create mode 100644 pr-preview/pr-976/0.9/components/policies.html create mode 100644 pr-preview/pr-976/0.9/components/runtime.html create mode 100644 pr-preview/pr-976/0.9/components/service-mesh.html create mode 100644 pr-preview/pr-976/0.9/deployment.html create mode 100644 pr-preview/pr-976/0.9/examples/emojivoto.html create mode 100644 pr-preview/pr-976/0.9/features-limitations.html create mode 100644 pr-preview/pr-976/0.9/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/0.9/getting-started/install.html create mode 100644 pr-preview/pr-976/0.9/troubleshooting.html create mode 100644 pr-preview/pr-976/1.0.html create mode 100644 pr-preview/pr-976/1.0/about/telemetry.html create mode 100644 pr-preview/pr-976/1.0/architecture/attestation.html create mode 100644 pr-preview/pr-976/1.0/architecture/certificates.html create mode 100644 pr-preview/pr-976/1.0/architecture/observability.html create mode 100644 pr-preview/pr-976/1.0/architecture/secrets.html create mode 100644 pr-preview/pr-976/1.0/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/1.0/basics/features.html create mode 100644 pr-preview/pr-976/1.0/basics/security-benefits.html create mode 100644 pr-preview/pr-976/1.0/components/overview.html create mode 100644 pr-preview/pr-976/1.0/components/policies.html create mode 100644 pr-preview/pr-976/1.0/components/runtime.html create mode 100644 pr-preview/pr-976/1.0/components/service-mesh.html create mode 100644 pr-preview/pr-976/1.0/deployment.html create mode 100644 pr-preview/pr-976/1.0/examples/emojivoto.html create mode 100644 pr-preview/pr-976/1.0/features-limitations.html create mode 100644 pr-preview/pr-976/1.0/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/1.0/getting-started/install.html create mode 100644 pr-preview/pr-976/1.0/troubleshooting.html create mode 100644 pr-preview/pr-976/404.html create mode 100644 pr-preview/pr-976/about/telemetry.html create mode 100644 pr-preview/pr-976/architecture/attestation.html create mode 100644 pr-preview/pr-976/architecture/certificates.html create mode 100644 pr-preview/pr-976/architecture/observability.html create mode 100644 pr-preview/pr-976/architecture/secrets.html create mode 100644 pr-preview/pr-976/architecture/security-considerations.html create mode 100644 pr-preview/pr-976/assets/css/styles.b5828750.css create mode 100644 pr-preview/pr-976/assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg create mode 100644 pr-preview/pr-976/assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg create mode 100644 pr-preview/pr-976/assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg create mode 100644 pr-preview/pr-976/assets/images/components-dd64f006e7d6b6facb9eb16f1af59d39.svg create mode 100644 pr-preview/pr-976/assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg create mode 100644 pr-preview/pr-976/assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg create mode 100644 pr-preview/pr-976/assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg create mode 100644 pr-preview/pr-976/assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png create mode 100644 pr-preview/pr-976/assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg create mode 100644 pr-preview/pr-976/assets/images/personas-1c9f2b217e0b94e0c3057df96d96b3f0.svg create mode 100644 pr-preview/pr-976/assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg create mode 100644 pr-preview/pr-976/assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg create mode 100644 pr-preview/pr-976/assets/js/014daffb.28613203.js create mode 100644 pr-preview/pr-976/assets/js/018595b3.560dae8b.js create mode 100644 pr-preview/pr-976/assets/js/04102e85.745c04f7.js create mode 100644 pr-preview/pr-976/assets/js/06354bbe.4db69232.js create mode 100644 pr-preview/pr-976/assets/js/06eada7a.0ffd2db0.js create mode 100644 pr-preview/pr-976/assets/js/078f57bf.b2f92c81.js create mode 100644 pr-preview/pr-976/assets/js/098bf236.fb47b956.js create mode 100644 pr-preview/pr-976/assets/js/0a09f1f2.af458bba.js create mode 100644 pr-preview/pr-976/assets/js/0a7a212e.4bfb0b6f.js create mode 100644 pr-preview/pr-976/assets/js/0b1c872d.c7834956.js create mode 100644 pr-preview/pr-976/assets/js/0ba7602a.85a7f1d2.js create mode 100644 pr-preview/pr-976/assets/js/0c24bc66.085b04d6.js create mode 100644 pr-preview/pr-976/assets/js/0e384e19.651e3adc.js create mode 100644 pr-preview/pr-976/assets/js/10257d90.7ee2f98c.js create mode 100644 pr-preview/pr-976/assets/js/1057c3b3.114828df.js create mode 100644 pr-preview/pr-976/assets/js/1186.8726fdba.js create mode 100644 pr-preview/pr-976/assets/js/137fbf80.8c6cd314.js create mode 100644 pr-preview/pr-976/assets/js/1477.b147cf3f.js create mode 100644 pr-preview/pr-976/assets/js/14a9ce33.fc32993b.js create mode 100644 pr-preview/pr-976/assets/js/14eb3368.8cb6f0b4.js create mode 100644 pr-preview/pr-976/assets/js/155.48c4e908.js create mode 100644 pr-preview/pr-976/assets/js/15b9bf06.b97730a3.js create mode 100644 pr-preview/pr-976/assets/js/165.8f94caaa.js create mode 100644 pr-preview/pr-976/assets/js/165.8f94caaa.js.LICENSE.txt create mode 100644 pr-preview/pr-976/assets/js/1689.251eba58.js create mode 100644 pr-preview/pr-976/assets/js/1711.0c8f9a6a.js create mode 100644 pr-preview/pr-976/assets/js/173fd1a8.8751a104.js create mode 100644 pr-preview/pr-976/assets/js/17896441.7a01a35f.js create mode 100644 pr-preview/pr-976/assets/js/1ab97833.9e49478d.js create mode 100644 pr-preview/pr-976/assets/js/1c9b88ee.ba0039db.js create mode 100644 pr-preview/pr-976/assets/js/1e7c9753.02e56af3.js create mode 100644 pr-preview/pr-976/assets/js/1ea8f7a3.d2d50582.js create mode 100644 pr-preview/pr-976/assets/js/20382dd7.20e8921f.js create mode 100644 pr-preview/pr-976/assets/js/207bb774.442bb435.js create mode 100644 pr-preview/pr-976/assets/js/20e0cfa9.1b701e80.js create mode 100644 pr-preview/pr-976/assets/js/2130.a7c31b12.js create mode 100644 pr-preview/pr-976/assets/js/21d7c4d4.59195010.js create mode 100644 pr-preview/pr-976/assets/js/2247.7219b8c6.js create mode 100644 pr-preview/pr-976/assets/js/2334.619d7d41.js create mode 100644 pr-preview/pr-976/assets/js/2387.7f9ca256.js create mode 100644 pr-preview/pr-976/assets/js/2496d21b.1c09cf80.js create mode 100644 pr-preview/pr-976/assets/js/250ffcdd.e9b01620.js create mode 100644 pr-preview/pr-976/assets/js/259f95a2.0c3a0ee9.js create mode 100644 pr-preview/pr-976/assets/js/26742c3b.ead769cd.js create mode 100644 pr-preview/pr-976/assets/js/27004ef7.ee187533.js create mode 100644 pr-preview/pr-976/assets/js/270470f6.2a97a5fd.js create mode 100644 pr-preview/pr-976/assets/js/2763.b71509e9.js create mode 100644 pr-preview/pr-976/assets/js/27a940ba.2b4c52be.js create mode 100644 pr-preview/pr-976/assets/js/27d05faa.4fff9fb7.js create mode 100644 pr-preview/pr-976/assets/js/2a2a0c40.fc2cf12c.js create mode 100644 pr-preview/pr-976/assets/js/2dbe31cc.19015d41.js create mode 100644 pr-preview/pr-976/assets/js/2df6ad32.0df42417.js create mode 100644 pr-preview/pr-976/assets/js/2e82b444.dd4ac86b.js create mode 100644 pr-preview/pr-976/assets/js/327db732.9cf7a097.js create mode 100644 pr-preview/pr-976/assets/js/327e592d.77873d5f.js create mode 100644 pr-preview/pr-976/assets/js/3364.d54f19c0.js create mode 100644 pr-preview/pr-976/assets/js/35dd9928.876c8b6d.js create mode 100644 pr-preview/pr-976/assets/js/3624.631ec2ee.js create mode 100644 pr-preview/pr-976/assets/js/3683601e.e3d4185e.js create mode 100644 pr-preview/pr-976/assets/js/3840.510aef0e.js create mode 100644 pr-preview/pr-976/assets/js/39db4684.7504d8d4.js create mode 100644 pr-preview/pr-976/assets/js/3a77bb3e.ae0e3a69.js create mode 100644 pr-preview/pr-976/assets/js/3d96af17.ef1ae4be.js create mode 100644 pr-preview/pr-976/assets/js/3d9be0cc.1005a9e5.js create mode 100644 pr-preview/pr-976/assets/js/3e02a241.10a2e2ba.js create mode 100644 pr-preview/pr-976/assets/js/41b31679.7dba08fd.js create mode 100644 pr-preview/pr-976/assets/js/4445.3811e3c0.js create mode 100644 pr-preview/pr-976/assets/js/4449.bb76b6fa.js create mode 100644 pr-preview/pr-976/assets/js/44b49990.29d0eb8e.js create mode 100644 pr-preview/pr-976/assets/js/45c98560.977c2d08.js create mode 100644 pr-preview/pr-976/assets/js/484.808d13de.js create mode 100644 pr-preview/pr-976/assets/js/48f2f8ef.3afa4ead.js create mode 100644 pr-preview/pr-976/assets/js/4ce6baab.ddbc3709.js create mode 100644 pr-preview/pr-976/assets/js/4cf3063f.ffa75230.js create mode 100644 pr-preview/pr-976/assets/js/4eec459c.883ecb5e.js create mode 100644 pr-preview/pr-976/assets/js/4f453872.072c6bcc.js create mode 100644 pr-preview/pr-976/assets/js/4fb24623.4962c99a.js create mode 100644 pr-preview/pr-976/assets/js/50474e10.3e18d095.js create mode 100644 pr-preview/pr-976/assets/js/51513a8d.cdeb6e9c.js create mode 100644 pr-preview/pr-976/assets/js/54c6367b.8cc47335.js create mode 100644 pr-preview/pr-976/assets/js/5606.5910c299.js create mode 100644 pr-preview/pr-976/assets/js/567e04ee.8a836253.js create mode 100644 pr-preview/pr-976/assets/js/5aa90309.c36a9a65.js create mode 100644 pr-preview/pr-976/assets/js/5c6fa5d3.98b892e1.js create mode 100644 pr-preview/pr-976/assets/js/5e95c892.c959e509.js create mode 100644 pr-preview/pr-976/assets/js/5eab7755.b121b0e1.js create mode 100644 pr-preview/pr-976/assets/js/5ecc20d3.560917b7.js create mode 100644 pr-preview/pr-976/assets/js/5f998a2f.761e3939.js create mode 100644 pr-preview/pr-976/assets/js/6009a9aa.e37420d5.js create mode 100644 pr-preview/pr-976/assets/js/6100b425.8c972462.js create mode 100644 pr-preview/pr-976/assets/js/640cb024.2e039806.js create mode 100644 pr-preview/pr-976/assets/js/642ed902.37cf76bd.js create mode 100644 pr-preview/pr-976/assets/js/6452.9f5d0a8d.js create mode 100644 pr-preview/pr-976/assets/js/6478b99f.23cfdac2.js create mode 100644 pr-preview/pr-976/assets/js/64d58a39.1a4a9610.js create mode 100644 pr-preview/pr-976/assets/js/6507182a.417f4320.js create mode 100644 pr-preview/pr-976/assets/js/6790.b101800c.js create mode 100644 pr-preview/pr-976/assets/js/68be920e.9f8df8ee.js create mode 100644 pr-preview/pr-976/assets/js/6903d0da.aed38602.js create mode 100644 pr-preview/pr-976/assets/js/6912.4cd2abc1.js create mode 100644 pr-preview/pr-976/assets/js/6912.4cd2abc1.js.LICENSE.txt create mode 100644 pr-preview/pr-976/assets/js/69ec948c.89847346.js create mode 100644 pr-preview/pr-976/assets/js/6a46f748.9218759d.js create mode 100644 pr-preview/pr-976/assets/js/6fc50b39.46b4da2f.js create mode 100644 pr-preview/pr-976/assets/js/7032.dded9666.js create mode 100644 pr-preview/pr-976/assets/js/7060.28ce0df1.js create mode 100644 pr-preview/pr-976/assets/js/7357.6aa95f42.js create mode 100644 pr-preview/pr-976/assets/js/75100f0d.9f8f9b89.js create mode 100644 pr-preview/pr-976/assets/js/75d659e1.2d71da15.js create mode 100644 pr-preview/pr-976/assets/js/7680d80e.2894bfc5.js create mode 100644 pr-preview/pr-976/assets/js/7723.83dacf97.js create mode 100644 pr-preview/pr-976/assets/js/790f17e8.a5baddba.js create mode 100644 pr-preview/pr-976/assets/js/7bd8db71.3f1b000d.js create mode 100644 pr-preview/pr-976/assets/js/7d1602ac.42782481.js create mode 100644 pr-preview/pr-976/assets/js/7edb0f0d.85693ccb.js create mode 100644 pr-preview/pr-976/assets/js/7f3f1ff7.009aeec6.js create mode 100644 pr-preview/pr-976/assets/js/8132774f.2680af68.js create mode 100644 pr-preview/pr-976/assets/js/8159.4e759f62.js create mode 100644 pr-preview/pr-976/assets/js/8174.61ff22d1.js create mode 100644 pr-preview/pr-976/assets/js/8379.c80faf06.js create mode 100644 pr-preview/pr-976/assets/js/8496.19c721e5.js create mode 100644 pr-preview/pr-976/assets/js/8731.c272170f.js create mode 100644 pr-preview/pr-976/assets/js/890.8531ec8c.js create mode 100644 pr-preview/pr-976/assets/js/89486910.2245dcd7.js create mode 100644 pr-preview/pr-976/assets/js/8965cb1f.7fa15643.js create mode 100644 pr-preview/pr-976/assets/js/896da145.a1a53ce3.js create mode 100644 pr-preview/pr-976/assets/js/8998.5c85576b.js create mode 100644 pr-preview/pr-976/assets/js/89a4f0ca.91bcaa30.js create mode 100644 pr-preview/pr-976/assets/js/8c9a8791.46416e05.js create mode 100644 pr-preview/pr-976/assets/js/8dca39c2.b4b59560.js create mode 100644 pr-preview/pr-976/assets/js/8f09b871.5bb7d3d7.js create mode 100644 pr-preview/pr-976/assets/js/9040bbc8.06d43bf0.js create mode 100644 pr-preview/pr-976/assets/js/90af0d0d.00afd3dd.js create mode 100644 pr-preview/pr-976/assets/js/9152dfbd.3bdd0a61.js create mode 100644 pr-preview/pr-976/assets/js/921.5ff0c680.js create mode 100644 pr-preview/pr-976/assets/js/927cf76e.6f4c28bf.js create mode 100644 pr-preview/pr-976/assets/js/9368.5da20e84.js create mode 100644 pr-preview/pr-976/assets/js/9397123b.2f0b3891.js create mode 100644 pr-preview/pr-976/assets/js/9620adf5.133d730b.js create mode 100644 pr-preview/pr-976/assets/js/9664.5583cedf.js create mode 100644 pr-preview/pr-976/assets/js/966b9f47.b375a919.js create mode 100644 pr-preview/pr-976/assets/js/969019ea.32517b56.js create mode 100644 pr-preview/pr-976/assets/js/9720.8e4604d2.js create mode 100644 pr-preview/pr-976/assets/js/9802.bb09c288.js create mode 100644 pr-preview/pr-976/assets/js/98367cce.28290f99.js create mode 100644 pr-preview/pr-976/assets/js/9875.78d2cec3.js create mode 100644 pr-preview/pr-976/assets/js/989c6d03.4ac694c4.js create mode 100644 pr-preview/pr-976/assets/js/9a06ae3d.046ea467.js create mode 100644 pr-preview/pr-976/assets/js/9a28f5c4.01963c55.js create mode 100644 pr-preview/pr-976/assets/js/9a99019d.7c69ee4c.js create mode 100644 pr-preview/pr-976/assets/js/9c8ec574.c337425b.js create mode 100644 pr-preview/pr-976/assets/js/9ccb1fc6.873740e8.js create mode 100644 pr-preview/pr-976/assets/js/9ce1fd56.9821471c.js create mode 100644 pr-preview/pr-976/assets/js/9d9e06f4.34f01e43.js create mode 100644 pr-preview/pr-976/assets/js/9d9f8394.950345c7.js create mode 100644 pr-preview/pr-976/assets/js/a0a1fd3b.d49c396c.js create mode 100644 pr-preview/pr-976/assets/js/a0a4ec6e.e66a8111.js create mode 100644 pr-preview/pr-976/assets/js/a161c24f.491f18fc.js create mode 100644 pr-preview/pr-976/assets/js/a2899f6e.7ec951c7.js create mode 100644 pr-preview/pr-976/assets/js/a3713279.cb16cfe2.js create mode 100644 pr-preview/pr-976/assets/js/a66d714b.bad912b3.js create mode 100644 pr-preview/pr-976/assets/js/a71cbd8f.fee2c6c8.js create mode 100644 pr-preview/pr-976/assets/js/a7bd4aaa.3effeeae.js create mode 100644 pr-preview/pr-976/assets/js/a86a94ce.db57590c.js create mode 100644 pr-preview/pr-976/assets/js/a94703ab.e63edbb7.js create mode 100644 pr-preview/pr-976/assets/js/aa0f7abf.62cf75e4.js create mode 100644 pr-preview/pr-976/assets/js/aaec90ae.14899e6c.js create mode 100644 pr-preview/pr-976/assets/js/aafa6b90.3f7af2d6.js create mode 100644 pr-preview/pr-976/assets/js/ab09c42c.54be6c5a.js create mode 100644 pr-preview/pr-976/assets/js/aba21aa0.0f4e95f1.js create mode 100644 pr-preview/pr-976/assets/js/abfbdc79.2729a342.js create mode 100644 pr-preview/pr-976/assets/js/ac3e6feb.c8d4aa8b.js create mode 100644 pr-preview/pr-976/assets/js/ae6c0c68.92c1ee41.js create mode 100644 pr-preview/pr-976/assets/js/b0cb3eb4.99a5cbf3.js create mode 100644 pr-preview/pr-976/assets/js/b20d32fc.e428ea64.js create mode 100644 pr-preview/pr-976/assets/js/b27c3275.a5dbc455.js create mode 100644 pr-preview/pr-976/assets/js/b3916dd3.30abb5e2.js create mode 100644 pr-preview/pr-976/assets/js/b3a88889.ef306daa.js create mode 100644 pr-preview/pr-976/assets/js/b451d7c3.99a4d0de.js create mode 100644 pr-preview/pr-976/assets/js/ba2406d8.4e6c54c4.js create mode 100644 pr-preview/pr-976/assets/js/baef5027.95910e40.js create mode 100644 pr-preview/pr-976/assets/js/bced0f3c.110450d8.js create mode 100644 pr-preview/pr-976/assets/js/bd029836.96853ab4.js create mode 100644 pr-preview/pr-976/assets/js/bd625abb.43f2f678.js create mode 100644 pr-preview/pr-976/assets/js/bde25e2b.2917f0f7.js create mode 100644 pr-preview/pr-976/assets/js/bf823012.0ed024b4.js create mode 100644 pr-preview/pr-976/assets/js/c09e49b9.9ff206ce.js create mode 100644 pr-preview/pr-976/assets/js/c1fac065.af80720c.js create mode 100644 pr-preview/pr-976/assets/js/c2ce05d5.83575dcd.js create mode 100644 pr-preview/pr-976/assets/js/c3a9f66a.6efdd9fb.js create mode 100644 pr-preview/pr-976/assets/js/c4b4ced0.cc4aaa5d.js create mode 100644 pr-preview/pr-976/assets/js/c7462af2.8edc4250.js create mode 100644 pr-preview/pr-976/assets/js/ca5b6702.a3b16546.js create mode 100644 pr-preview/pr-976/assets/js/cdb2b1a5.cee59a12.js create mode 100644 pr-preview/pr-976/assets/js/cf49aa2b.89d9d490.js create mode 100644 pr-preview/pr-976/assets/js/d1a11e04.8df8afb2.js create mode 100644 pr-preview/pr-976/assets/js/d2630e76.be1d4782.js create mode 100644 pr-preview/pr-976/assets/js/d580a1fd.d3605f1d.js create mode 100644 pr-preview/pr-976/assets/js/d77304ba.f1bec1ec.js create mode 100644 pr-preview/pr-976/assets/js/dacf14a0.c33c9e89.js create mode 100644 pr-preview/pr-976/assets/js/de615ffd.ef11da9f.js create mode 100644 pr-preview/pr-976/assets/js/dfd9c366.af676094.js create mode 100644 pr-preview/pr-976/assets/js/e1e441c9.d7ad6ed8.js create mode 100644 pr-preview/pr-976/assets/js/e277c26a.364edfbf.js create mode 100644 pr-preview/pr-976/assets/js/e2b3b970.151dea1f.js create mode 100644 pr-preview/pr-976/assets/js/e446d98f.5906d2b8.js create mode 100644 pr-preview/pr-976/assets/js/e55aefba.57f034d8.js create mode 100644 pr-preview/pr-976/assets/js/e8480491.72a2b553.js create mode 100644 pr-preview/pr-976/assets/js/e9dbdd13.305d71e2.js create mode 100644 pr-preview/pr-976/assets/js/edcfcef8.efca5aef.js create mode 100644 pr-preview/pr-976/assets/js/ee8b52db.b69e4030.js create mode 100644 pr-preview/pr-976/assets/js/f2348f57.3db099bc.js create mode 100644 pr-preview/pr-976/assets/js/f31967d8.71b71235.js create mode 100644 pr-preview/pr-976/assets/js/f36abd57.48e08f44.js create mode 100644 pr-preview/pr-976/assets/js/f47dd6e5.ecf0ed95.js create mode 100644 pr-preview/pr-976/assets/js/f5272de0.78413199.js create mode 100644 pr-preview/pr-976/assets/js/f593d43a.93a070a0.js create mode 100644 pr-preview/pr-976/assets/js/f65fea7a.7a92e4f1.js create mode 100644 pr-preview/pr-976/assets/js/fbad2ec0.afc757e3.js create mode 100644 pr-preview/pr-976/assets/js/fbad79f4.6e49be6a.js create mode 100644 pr-preview/pr-976/assets/js/fbcf0d59.08f1ee86.js create mode 100644 pr-preview/pr-976/assets/js/fda633d9.f148ee0b.js create mode 100644 pr-preview/pr-976/assets/js/main.bd30bfc7.js create mode 100644 pr-preview/pr-976/assets/js/main.bd30bfc7.js.LICENSE.txt create mode 100644 pr-preview/pr-976/assets/js/runtime~main.7d4c04c9.js create mode 100644 pr-preview/pr-976/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/basics/features.html create mode 100644 pr-preview/pr-976/basics/security-benefits.html create mode 100644 pr-preview/pr-976/components/overview.html create mode 100644 pr-preview/pr-976/components/policies.html create mode 100644 pr-preview/pr-976/components/runtime.html create mode 100644 pr-preview/pr-976/components/service-mesh.html create mode 100644 pr-preview/pr-976/deployment.html create mode 100644 pr-preview/pr-976/examples/emojivoto.html create mode 100644 pr-preview/pr-976/features-limitations.html create mode 100644 pr-preview/pr-976/getting-started/bare-metal.html create mode 100644 pr-preview/pr-976/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/getting-started/install.html create mode 100644 pr-preview/pr-976/img/GitHub-Banner_Contrast_2024.gif create mode 100644 pr-preview/pr-976/img/concept.svg create mode 100644 pr-preview/pr-976/img/favicon.ico create mode 100644 pr-preview/pr-976/img/logos/contrast_icon.svg create mode 100644 pr-preview/pr-976/index.html create mode 100644 pr-preview/pr-976/next.html create mode 100644 pr-preview/pr-976/next/about/telemetry.html create mode 100644 pr-preview/pr-976/next/architecture/attestation.html create mode 100644 pr-preview/pr-976/next/architecture/certificates.html create mode 100644 pr-preview/pr-976/next/architecture/observability.html create mode 100644 pr-preview/pr-976/next/architecture/secrets.html create mode 100644 pr-preview/pr-976/next/architecture/security-considerations.html create mode 100644 pr-preview/pr-976/next/basics/confidential-containers.html create mode 100644 pr-preview/pr-976/next/basics/features.html create mode 100644 pr-preview/pr-976/next/basics/security-benefits.html create mode 100644 pr-preview/pr-976/next/components/overview.html create mode 100644 pr-preview/pr-976/next/components/policies.html create mode 100644 pr-preview/pr-976/next/components/runtime.html create mode 100644 pr-preview/pr-976/next/components/service-mesh.html create mode 100644 pr-preview/pr-976/next/deployment.html create mode 100644 pr-preview/pr-976/next/examples/emojivoto.html create mode 100644 pr-preview/pr-976/next/features-limitations.html create mode 100644 pr-preview/pr-976/next/getting-started/bare-metal.html create mode 100644 pr-preview/pr-976/next/getting-started/cluster-setup.html create mode 100644 pr-preview/pr-976/next/getting-started/install.html create mode 100644 pr-preview/pr-976/next/troubleshooting.html create mode 100644 pr-preview/pr-976/search-index-docs-default-0.5.json create mode 100644 pr-preview/pr-976/search-index-docs-default-0.6.json create mode 100644 pr-preview/pr-976/search-index-docs-default-0.7.json create mode 100644 pr-preview/pr-976/search-index-docs-default-0.8.json create mode 100644 pr-preview/pr-976/search-index-docs-default-0.9.json create mode 100644 pr-preview/pr-976/search-index-docs-default-1.0.json create mode 100644 pr-preview/pr-976/search-index-docs-default-1.1.json create mode 100644 pr-preview/pr-976/search-index-docs-default-current.json create mode 100644 pr-preview/pr-976/sitemap.xml create mode 100644 pr-preview/pr-976/troubleshooting.html diff --git a/pr-preview/pr-976/0.5.html b/pr-preview/pr-976/0.5.html new file mode 100644 index 0000000000..453b9ccc74 --- /dev/null +++ b/pr-preview/pr-976/0.5.html @@ -0,0 +1,44 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture.html b/pr-preview/pr-976/0.5/architecture.html new file mode 100644 index 0000000000..be7714c501 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture.html @@ -0,0 +1,24 @@ + + + + + +Architecture | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/attestation/coordinator.html b/pr-preview/pr-976/0.5/architecture/attestation/coordinator.html new file mode 100644 index 0000000000..e280c68d5e --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/attestation/coordinator.html @@ -0,0 +1,22 @@ + + + + + +coordinator | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/attestation/hardware.html b/pr-preview/pr-976/0.5/architecture/attestation/hardware.html new file mode 100644 index 0000000000..d38fe522f5 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/attestation/hardware.html @@ -0,0 +1,22 @@ + + + + + +hardware | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/attestation/manifest.html b/pr-preview/pr-976/0.5/architecture/attestation/manifest.html new file mode 100644 index 0000000000..4bae323c21 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/attestation/manifest.html @@ -0,0 +1,22 @@ + + + + + +manifest | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/attestation/pod-vm.html b/pr-preview/pr-976/0.5/architecture/attestation/pod-vm.html new file mode 100644 index 0000000000..40a6202303 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/attestation/pod-vm.html @@ -0,0 +1,22 @@ + + + + + +pod-vm | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies.html b/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies.html new file mode 100644 index 0000000000..b992fea458 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies.html @@ -0,0 +1,22 @@ + + + + + +runtime-policies | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki.html b/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki.html new file mode 100644 index 0000000000..8e64fa0d15 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki.html @@ -0,0 +1,22 @@ + + + + + +pki | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/components/cli.html b/pr-preview/pr-976/0.5/architecture/components/cli.html new file mode 100644 index 0000000000..575c82494f --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/components/cli.html @@ -0,0 +1,22 @@ + + + + + +cli | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/components/coordinator.html b/pr-preview/pr-976/0.5/architecture/components/coordinator.html new file mode 100644 index 0000000000..c695382a44 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/components/coordinator.html @@ -0,0 +1,22 @@ + + + + + +coordinator | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/components/init-container.html b/pr-preview/pr-976/0.5/architecture/components/init-container.html new file mode 100644 index 0000000000..5d021bdd3d --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/components/init-container.html @@ -0,0 +1,22 @@ + + + + + +init-container | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/confidential-containers.html b/pr-preview/pr-976/0.5/architecture/confidential-containers.html new file mode 100644 index 0000000000..d95208c9d2 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/confidential-containers.html @@ -0,0 +1,22 @@ + + + + + +confidential-containers | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys.html b/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys.html new file mode 100644 index 0000000000..8d90db0023 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys.html @@ -0,0 +1,22 @@ + + + + + +protocols-and-keys | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar.html b/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar.html new file mode 100644 index 0000000000..aac0c6af50 --- /dev/null +++ b/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar.html @@ -0,0 +1,22 @@ + + + + + +sidecar | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/basics/confidential-containers.html b/pr-preview/pr-976/0.5/basics/confidential-containers.html new file mode 100644 index 0000000000..cfe6e034cd --- /dev/null +++ b/pr-preview/pr-976/0.5/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable, core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The guest VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo Preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/basics/features.html b/pr-preview/pr-976/0.5/basics/features.html new file mode 100644 index 0000000000..82486aacaf --- /dev/null +++ b/pr-preview/pr-976/0.5/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product Features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Product Features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes Compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight Installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote Attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service Mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/basics/security-benefits.html b/pr-preview/pr-976/0.5/basics/security-benefits.html new file mode 100644 index 0000000000..347b1a4818 --- /dev/null +++ b/pr-preview/pr-976/0.5/basics/security-benefits.html @@ -0,0 +1,22 @@ + + + + + +security-benefits | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/category/attestation.html b/pr-preview/pr-976/0.5/category/attestation.html new file mode 100644 index 0000000000..c8f49765f4 --- /dev/null +++ b/pr-preview/pr-976/0.5/category/attestation.html @@ -0,0 +1,22 @@ + + + + + +Attestation | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/category/certificates-and-identities.html b/pr-preview/pr-976/0.5/category/certificates-and-identities.html new file mode 100644 index 0000000000..7418456839 --- /dev/null +++ b/pr-preview/pr-976/0.5/category/certificates-and-identities.html @@ -0,0 +1,22 @@ + + + + + +Certificates and Identities | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/category/components.html b/pr-preview/pr-976/0.5/category/components.html new file mode 100644 index 0000000000..b6839872a4 --- /dev/null +++ b/pr-preview/pr-976/0.5/category/components.html @@ -0,0 +1,22 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/category/network-encryption.html b/pr-preview/pr-976/0.5/category/network-encryption.html new file mode 100644 index 0000000000..e8bb62bf78 --- /dev/null +++ b/pr-preview/pr-976/0.5/category/network-encryption.html @@ -0,0 +1,22 @@ + + + + + +Network Encryption | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/deployment.html b/pr-preview/pr-976/0.5/deployment.html new file mode 100644 index 0000000000..2970e4cbd1 --- /dev/null +++ b/pr-preview/pr-976/0.5/deployment.html @@ -0,0 +1,75 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml
+

Prepare your Kubernetes resources

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: kata-cc-isolation to the pod spec (pod definition or template). +In addition, add the Contrast Initializer as initContainers to these workloads and configure the +workload to use the certificates written to a volumeMount named tls-certs.

+
spec: # v1.PodSpec
runtimeClassName: kata-cc-isolation
initContainers:
- name: initializer
image: "ghcr.io/edgelesssys/contrast/initializer:latest"
env:
- name: COORDINATOR_HOST
value: coordinator
volumeMounts:
- name: tls-certs
mountPath: /tls-config
volumes:
- name: tls-certs
emptyDir: {}
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as annotations to your +deployment files. A manifest.json with the reference values of your deployment will be created.

+
contrast generate resources/
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

After this step, the Coordinator will start issuing TLS certs to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh +root certificate and the history of manifests into the verify/ directory. In addition, the policies referenced +in the manifest are also written to the directory.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-root.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
timeout 30s bash -c 'until kubectl get service/${MY_SERVICE} --output=jsonpath='{.status.loadBalancer}' | grep "ingress"; do sleep 2 ; done'
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh root certificate with throw the following error:

$ curl --cacert ./verify/mesh-root.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-root.pem:

+
openssl s_client -CAfile verify/mesh-root.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/examples.html b/pr-preview/pr-976/0.5/examples.html new file mode 100644 index 0000000000..2ef6bc0161 --- /dev/null +++ b/pr-preview/pr-976/0.5/examples.html @@ -0,0 +1,24 @@ + + + + + +Examples | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/examples/emojivoto.html b/pr-preview/pr-976/0.5/examples/emojivoto.html new file mode 100644 index 0000000000..820b7c2afe --- /dev/null +++ b/pr-preview/pr-976/0.5/examples/emojivoto.html @@ -0,0 +1,134 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+
    +
  • Installed Contrast CLI. +See the installation instructions on how to get it.
  • +
  • Running cluster with Confidential Containers support. +Please follow the cluster setup instructions +to create a cluster.
  • +
  • Get the deployment. This is currently available as part of the preview bundle.
  • +
+

Steps to deploy emojivoto with Contrast

+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class kata-cc-isolation was added to the pods to signal they should be run +as Confidential Containers. In addition, the Contrast Initializer was added +as an init container to these workloads to facilitate the attestation and certificate pulling +before the actual workload is started.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the embedded reference values to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, we're ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The emojivoto version we're using is patched to only communicate +via mTLS (the original app talks plain HTTP). The different parts of the workload are configured +to use the credentials from the volumeMount when communicating with each other.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-root.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-root.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-root.pem:

+
openssl s_client -CAfile verify/mesh-root.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh root certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-root.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh root certificate on the manifest update. Workload certificates issued +after the manifest are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-root.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-root.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/getting-started.html b/pr-preview/pr-976/0.5/getting-started.html new file mode 100644 index 0000000000..5eea1932a6 --- /dev/null +++ b/pr-preview/pr-976/0.5/getting-started.html @@ -0,0 +1,24 @@ + + + + + +Getting started | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/getting-started/cluster-setup.html b/pr-preview/pr-976/0.5/getting-started/cluster-setup.html new file mode 100644 index 0000000000..39ee326cb6 --- /dev/null +++ b/pr-preview/pr-976/0.5/getting-started/cluster-setup.html @@ -0,0 +1,63 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which has +the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "$azResourceGroup" \
--location "$azLocation"
+

Create AKS cluster

+

First create an AKS cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "$azResourceGroup" \
--name "$azClusterName" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "$azResourceGroup" \
--name nodepool2 \
--cluster-name "$azClusterName" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "$azResourceGroup" \
--name "$azClusterName"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "$azResourceGroup"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "$azResourceGroup" \
--name "$azClusterName"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/getting-started/first-steps.html b/pr-preview/pr-976/0.5/getting-started/first-steps.html new file mode 100644 index 0000000000..fbf49bc424 --- /dev/null +++ b/pr-preview/pr-976/0.5/getting-started/first-steps.html @@ -0,0 +1,22 @@ + + + + + +first-steps | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.5/getting-started/install.html b/pr-preview/pr-976/0.5/getting-started/install.html new file mode 100644 index 0000000000..648cabb325 --- /dev/null +++ b/pr-preview/pr-976/0.5/getting-started/install.html @@ -0,0 +1,25 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.5

Installation

+

Download the bundle from the URL you received:

curl -fLO <URL>

Then unpack the unpack the downloaded archive:

unzip contrast.zip
+

Install the Contrast CLI in your PATH, e.g.:

+
mv contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6.html b/pr-preview/pr-976/0.6.html new file mode 100644 index 0000000000..2a4c417b51 --- /dev/null +++ b/pr-preview/pr-976/0.6.html @@ -0,0 +1,44 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/about.html b/pr-preview/pr-976/0.6/about.html new file mode 100644 index 0000000000..cc1b137598 --- /dev/null +++ b/pr-preview/pr-976/0.6/about.html @@ -0,0 +1,24 @@ + + + + + +About | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/about/telemetry.html b/pr-preview/pr-976/0.6/about/telemetry.html new file mode 100644 index 0000000000..1dec1a3a3d --- /dev/null +++ b/pr-preview/pr-976/0.6/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/architecture.html b/pr-preview/pr-976/0.6/architecture.html new file mode 100644 index 0000000000..6589fc77ef --- /dev/null +++ b/pr-preview/pr-976/0.6/architecture.html @@ -0,0 +1,24 @@ + + + + + +Architecture | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/architecture/attestation.html b/pr-preview/pr-976/0.6/architecture/attestation.html new file mode 100644 index 0000000000..63b3f2b48b --- /dev/null +++ b/pr-preview/pr-976/0.6/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +On AMD SEV-SNP the hash of the policy is then added to the attestation report via the HOSTDATA field by the hypervisor. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/architecture/certificates.html b/pr-preview/pr-976/0.6/architecture/certificates.html new file mode 100644 index 0000000000..80b3a1fae2 --- /dev/null +++ b/pr-preview/pr-976/0.6/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/basics/confidential-containers.html b/pr-preview/pr-976/0.6/basics/confidential-containers.html new file mode 100644 index 0000000000..36dd022a8a --- /dev/null +++ b/pr-preview/pr-976/0.6/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/basics/features.html b/pr-preview/pr-976/0.6/basics/features.html new file mode 100644 index 0000000000..67e03d458e --- /dev/null +++ b/pr-preview/pr-976/0.6/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/basics/security-benefits.html b/pr-preview/pr-976/0.6/basics/security-benefits.html new file mode 100644 index 0000000000..1478327ac1 --- /dev/null +++ b/pr-preview/pr-976/0.6/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/components.html b/pr-preview/pr-976/0.6/components.html new file mode 100644 index 0000000000..95da7e351e --- /dev/null +++ b/pr-preview/pr-976/0.6/components.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/components/policies.html b/pr-preview/pr-976/0.6/components/policies.html new file mode 100644 index 0000000000..5b478e0b66 --- /dev/null +++ b/pr-preview/pr-976/0.6/components/policies.html @@ -0,0 +1,77 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/components/runtime.html b/pr-preview/pr-976/0.6/components/runtime.html new file mode 100644 index 0000000000..19f19446b6 --- /dev/null +++ b/pr-preview/pr-976/0.6/components/runtime.html @@ -0,0 +1,72 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

cloud-hypervisor virtual machine manager (VMM)

+

The containerd shim uses cloud-hypervisor to create a confidential virtual machine for every pod. +This requires the cloud-hypervisor binary to be installed on every node (responsibility of the node-installer).

+

Tardev snapshotter

+

Contrast uses a special containerd snapshotter (tardev) to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor as the virtual machine manager (VMM)
  • +
  • Install an IGVM file for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/components/service-mesh.html b/pr-preview/pr-976/0.6/components/service-mesh.html new file mode 100644 index 0000000000..75995ba8fd --- /dev/null +++ b/pr-preview/pr-976/0.6/components/service-mesh.html @@ -0,0 +1,79 @@ + + + + + +Service Mesh | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Service Mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-pod basis by adding the service-mesh +container as a sidecar container. +The service mesh container first sets up iptables +rules based on its configuration and then starts Envoy +for TLS origination and termination.

+

Configuring the Proxy

+

The service mesh container can be configured using the EDG_INGRESS_PROXY_CONFIG +and EDG_EGRESS_PROXY_CONFIG environment variables.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the environment variable EDG_INGRESS_PROXY_CONFIG as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the +informational-only field <name>.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
initContainers:
- name: initializer
image: "ghcr.io/edgelesssys/contrast/initializer@sha256:..."
env:
- name: COORDINATOR_HOST
value: coordinator
volumeMounts:
- name: tls-certs
mountPath: /tls-config
- name: sidecar
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy@sha256:..."
restartPolicy: Always
volumeMounts:
- name: tls-certs
mountPath: /tls-config
env:
- name: EDG_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
volumeMounts:
- name: tls-certs
mountPath: /tls-config
volumes:
- name: tls-certs
emptyDir: {}
+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as EDG_EGRESS_PROXY_CONFIG. Separate multiple entries with ##. Choose any +string identifying the service on the given port as <name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are themselves part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
initContainers:
- name: initializer
image: "ghcr.io/edgelesssys/contrast/initializer@sha256:..."
env:
- name: COORDINATOR_HOST
value: coordinator
volumeMounts:
- name: tls-certs
mountPath: /tls-config
- name: sidecar
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy@sha256:..."
restartPolicy: Always
volumeMounts:
- name: tls-certs
mountPath: /tls-config
env:
- name: EDG_EGRESS_PROXY_CONFIG
value: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
securityContext:
privileged: true
capabilities:
add:
- NET_ADMIN
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
volumeMounts:
- name: tls-certs
mountPath: /tls-config
volumes:
- name: tls-certs
emptyDir: {}
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/deployment.html b/pr-preview/pr-976/0.6/deployment.html new file mode 100644 index 0000000000..5a4cc8fce9 --- /dev/null +++ b/pr-preview/pr-976/0.6/deployment.html @@ -0,0 +1,102 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

RuntimeClass and Initializer

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies. +In addition, add the Contrast Initializer as initContainers to these workloads and configure the +workload to use the certificates written to a volumeMount named tls-certs.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
initContainers:
- name: initializer
image: "ghcr.io/edgelesssys/contrast/initializer:latest"
env:
- name: COORDINATOR_HOST
value: coordinator
volumeMounts:
- name: tls-certs
mountPath: /tls-config
volumes:
- name: tls-certs
emptyDir: {}
+

Handling TLS

+

The initializer populates the shared volume with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The app has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The app has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following sidecar definition to your workload:

spec: # v1.PodSpec
initContainers:
- name: tls-sidecar
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:latest"
restartPolicy: Always
env:
- name: EDG_INGRESS_PROXY_CONFIG
value: "main#8001#false##metrics#8080#true"
- name: EDG_EGRESS_PROXY_CONFIG
value: "backend#127.0.0.2:4001#backend.default:4001"
volumeMounts:
- name: tls-certs
mountPath: /tls-config

The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as annotations to your +deployment files. A manifest.json with the reference values of your deployment will be created.

+
contrast generate resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

After this step, the Coordinator will start issuing TLS certs to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh +root certificate and the history of manifests into the verify/ directory. In addition, the policies referenced +in the manifest are also written to the directory.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/examples.html b/pr-preview/pr-976/0.6/examples.html new file mode 100644 index 0000000000..d7335d1b4b --- /dev/null +++ b/pr-preview/pr-976/0.6/examples.html @@ -0,0 +1,24 @@ + + + + + +Examples | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/examples/emojivoto.html b/pr-preview/pr-976/0.6/examples/emojivoto.html new file mode 100644 index 0000000000..345e5abb1c --- /dev/null +++ b/pr-preview/pr-976/0.6/examples/emojivoto.html @@ -0,0 +1,148 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+ +

Steps to deploy emojivoto with Contrast

+

Downloading the deployment

+

The emojivoto deployment files are part of a zip file in the Contrast release. You can download the +latest deployment by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/latest/download/emojivoto-demo.zip
+

After that, unzip the emojivoto-demo.zip file to extract the deployment/ directory.

+
unzip emojivoto-demo.zip
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<VERSIONHASH> +was added to the pods to signal they should be run as Confidential Containers. In addition, the Contrast +Initializer was added as an init container to these workloads to +facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the embedded reference values to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, we're ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/getting-started.html b/pr-preview/pr-976/0.6/getting-started.html new file mode 100644 index 0000000000..9516103aa0 --- /dev/null +++ b/pr-preview/pr-976/0.6/getting-started.html @@ -0,0 +1,24 @@ + + + + + +Getting started | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/getting-started/cluster-setup.html b/pr-preview/pr-976/0.6/getting-started/cluster-setup.html new file mode 100644 index 0000000000..2eaa9fe0c9 --- /dev/null +++ b/pr-preview/pr-976/0.6/getting-started/cluster-setup.html @@ -0,0 +1,63 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which needs +to have the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First create an AKS cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "${azResourceGroup:?}" \
--name nodepool2 \
--cluster-name "${azClusterName:?}" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/getting-started/install.html b/pr-preview/pr-976/0.6/getting-started/install.html new file mode 100644 index 0000000000..4564a84caa --- /dev/null +++ b/pr-preview/pr-976/0.6/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.6/known-limitations.html b/pr-preview/pr-976/0.6/known-limitations.html new file mode 100644 index 0000000000..5a1c1e9ab8 --- /dev/null +++ b/pr-preview/pr-976/0.6/known-limitations.html @@ -0,0 +1,46 @@ + + + + + +Known Limitations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.6

Known Limitations

+

As Contrast is currently in an early development stage, it's built on several projects that are also under active development. +This section outlines the most significant known limitations, providing stakeholders with clear expectations and understanding of the current state.

+

Availability

+
    +
  • Platform Support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
+

Kubernetes Features

+
    +
  • Persistent Volumes: Not currently supported within Confidential Containers.
  • +
  • Port-Forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource Limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime Policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling Integration

+
    +
  • CLI Availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7.html b/pr-preview/pr-976/0.7.html new file mode 100644 index 0000000000..5b7c5c4c78 --- /dev/null +++ b/pr-preview/pr-976/0.7.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/about.html b/pr-preview/pr-976/0.7/about.html new file mode 100644 index 0000000000..3e394e3ed4 --- /dev/null +++ b/pr-preview/pr-976/0.7/about.html @@ -0,0 +1,24 @@ + + + + + +About | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/about/telemetry.html b/pr-preview/pr-976/0.7/about/telemetry.html new file mode 100644 index 0000000000..832aeb7bc3 --- /dev/null +++ b/pr-preview/pr-976/0.7/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/architecture.html b/pr-preview/pr-976/0.7/architecture.html new file mode 100644 index 0000000000..26cafb8d3b --- /dev/null +++ b/pr-preview/pr-976/0.7/architecture.html @@ -0,0 +1,24 @@ + + + + + +Architecture | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/architecture/attestation.html b/pr-preview/pr-976/0.7/architecture/attestation.html new file mode 100644 index 0000000000..c9c9ae3ead --- /dev/null +++ b/pr-preview/pr-976/0.7/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +On AMD SEV-SNP the hash of the policy is then added to the attestation report via the HOSTDATA field by the hypervisor. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/architecture/certificates.html b/pr-preview/pr-976/0.7/architecture/certificates.html new file mode 100644 index 0000000000..99ca394e3e --- /dev/null +++ b/pr-preview/pr-976/0.7/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/architecture/observability.html b/pr-preview/pr-976/0.7/architecture/observability.html new file mode 100644 index 0000000000..b22a1d752d --- /dev/null +++ b/pr-preview/pr-976/0.7/architecture/observability.html @@ -0,0 +1,66 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator starts two gRPC servers, one for the user API on port 1313 and +one for the mesh API on port 7777. Metrics for both servers can be accessed +using different prefixes.

+

All metric names for the user API are prefixed with contrast_userapi_grpc_server_. +Exposed metrics include the number of handled requests of the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively. For each method +you can see the gRPC status code indicating whether the request succeeded or +not and the request latency.

+

For the mesh API, the metric names are prefixed with contrast_meshapi_grpc_server_. The +metrics include similar data to the user API for the method NewMeshCert which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/basics/confidential-containers.html b/pr-preview/pr-976/0.7/basics/confidential-containers.html new file mode 100644 index 0000000000..1b79a83684 --- /dev/null +++ b/pr-preview/pr-976/0.7/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/basics/features.html b/pr-preview/pr-976/0.7/basics/features.html new file mode 100644 index 0000000000..0bd997efdc --- /dev/null +++ b/pr-preview/pr-976/0.7/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/basics/security-benefits.html b/pr-preview/pr-976/0.7/basics/security-benefits.html new file mode 100644 index 0000000000..9ba2e2be15 --- /dev/null +++ b/pr-preview/pr-976/0.7/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/components.html b/pr-preview/pr-976/0.7/components.html new file mode 100644 index 0000000000..941cea41c9 --- /dev/null +++ b/pr-preview/pr-976/0.7/components.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/components/policies.html b/pr-preview/pr-976/0.7/components/policies.html new file mode 100644 index 0000000000..431d208f65 --- /dev/null +++ b/pr-preview/pr-976/0.7/components/policies.html @@ -0,0 +1,77 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/components/runtime.html b/pr-preview/pr-976/0.7/components/runtime.html new file mode 100644 index 0000000000..784671d22f --- /dev/null +++ b/pr-preview/pr-976/0.7/components/runtime.html @@ -0,0 +1,72 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

cloud-hypervisor virtual machine manager (VMM)

+

The containerd shim uses cloud-hypervisor to create a confidential virtual machine for every pod. +This requires the cloud-hypervisor binary to be installed on every node (responsibility of the node-installer).

+

Tardev snapshotter

+

Contrast uses a special containerd snapshotter (tardev) to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor as the virtual machine manager (VMM)
  • +
  • Install an IGVM file for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/components/service-mesh.html b/pr-preview/pr-976/0.7/components/service-mesh.html new file mode 100644 index 0000000000..315262549e --- /dev/null +++ b/pr-preview/pr-976/0.7/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables EDG_INGRESS_PROXY_CONFIG, +EDG_EGRESS_PROXY_CONFIG and EDG_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: EDG_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.7.3@sha256:e297e9db93744445608f229d44479359313bc187a7f31e1a9c3c9b1d5407b5f6"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-tls-certs
mountPath: /tls-config
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/deployment.html b/pr-preview/pr-976/0.7/deployment.html new file mode 100644 index 0000000000..7a06e36640 --- /dev/null +++ b/pr-preview/pr-976/0.7/deployment.html @@ -0,0 +1,115 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/runtime.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/coordinator.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-tls-certs shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-tls-certs volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:v0.7.3@sha256:55475365c8177420ff3b27ad48bb0f38f8a92bfe754f50f1ed97f50f17ee23b8"
name: contrast-initializer
volumeMounts:
- mountPath: /tls-config
name: contrast-tls-certs
volumes:
- emptyDir: {}
name: contrast-tls-certs
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh +root certificate and the history of manifests into the verify/ directory. In addition, the policies referenced +in the manifest are also written to the directory.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/examples.html b/pr-preview/pr-976/0.7/examples.html new file mode 100644 index 0000000000..4aba2c8eca --- /dev/null +++ b/pr-preview/pr-976/0.7/examples.html @@ -0,0 +1,24 @@ + + + + + +Examples | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/examples/emojivoto.html b/pr-preview/pr-976/0.7/examples/emojivoto.html new file mode 100644 index 0000000000..248a39305d --- /dev/null +++ b/pr-preview/pr-976/0.7/examples/emojivoto.html @@ -0,0 +1,148 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+ +

Steps to deploy emojivoto with Contrast

+

Downloading the deployment

+

The emojivoto deployment files are part of a zip file in the Contrast release. You can download the +latest deployment by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.7.3/emojivoto-demo.zip
+

After that, unzip the emojivoto-demo.zip file to extract the deployment/ directory.

+
unzip emojivoto-demo.zip
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/runtime.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<VERSIONHASH> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the embedded reference values to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using embedded reference values. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/features-limitations.html b/pr-preview/pr-976/0.7/features-limitations.html new file mode 100644 index 0000000000..7a0664157e --- /dev/null +++ b/pr-preview/pr-976/0.7/features-limitations.html @@ -0,0 +1,46 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Not currently supported within Confidential Containers.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/getting-started.html b/pr-preview/pr-976/0.7/getting-started.html new file mode 100644 index 0000000000..7e3b2b3c99 --- /dev/null +++ b/pr-preview/pr-976/0.7/getting-started.html @@ -0,0 +1,24 @@ + + + + + +Getting started | Contrast + + + + + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/getting-started/cluster-setup.html b/pr-preview/pr-976/0.7/getting-started/cluster-setup.html new file mode 100644 index 0000000000..6868f3a09b --- /dev/null +++ b/pr-preview/pr-976/0.7/getting-started/cluster-setup.html @@ -0,0 +1,67 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which needs +to have the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a +non-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool.

+

We'll first start by creating the non-CoCo cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "${azResourceGroup:?}" \
--name nodepool2 \
--cluster-name "${azClusterName:?}" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Optionally, we can now remove the non-CoCo node pool:

+
az aks nodepool delete \
--resource-group "${azResourceGroup:?}" \
--cluster-name "${azClusterName:?}" \
--name nodepool1
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.7/getting-started/install.html b/pr-preview/pr-976/0.7/getting-started/install.html new file mode 100644 index 0000000000..d4821852ce --- /dev/null +++ b/pr-preview/pr-976/0.7/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.7

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.7.3/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8.html b/pr-preview/pr-976/0.8.html new file mode 100644 index 0000000000..69dccb7e01 --- /dev/null +++ b/pr-preview/pr-976/0.8.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/about/telemetry.html b/pr-preview/pr-976/0.8/about/telemetry.html new file mode 100644 index 0000000000..ad6005bb58 --- /dev/null +++ b/pr-preview/pr-976/0.8/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/architecture/attestation.html b/pr-preview/pr-976/0.8/architecture/attestation.html new file mode 100644 index 0000000000..3052d39beb --- /dev/null +++ b/pr-preview/pr-976/0.8/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +On AMD SEV-SNP the hash of the policy is then added to the attestation report via the HOSTDATA field by the hypervisor. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/architecture/certificates.html b/pr-preview/pr-976/0.8/architecture/certificates.html new file mode 100644 index 0000000000..832f1ca572 --- /dev/null +++ b/pr-preview/pr-976/0.8/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/architecture/observability.html b/pr-preview/pr-976/0.8/architecture/observability.html new file mode 100644 index 0000000000..2ac45a059c --- /dev/null +++ b/pr-preview/pr-976/0.8/architecture/observability.html @@ -0,0 +1,65 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator exports gRPC metrics under the prefix contrast_grpc_server_. +These metrics are labeled with the gRPC service name and method name. +Metrics of interest include contrast_grpc_server_handled_total, which counts +the number of requests by return code, and +contrast_grpc_server_handling_seconds_bucket, which produces a histogram of
+request latency.

+

The gRPC service userapi.UserAPI records metrics for the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively.

+

The meshapi.MeshAPI service records metrics for the method NewMeshCert, which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/architecture/secrets.html b/pr-preview/pr-976/0.8/architecture/secrets.html new file mode 100644 index 0000000000..b7667cae2f --- /dev/null +++ b/pr-preview/pr-976/0.8/architecture/secrets.html @@ -0,0 +1,39 @@ + + + + + +Secrets & recovery | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Secrets & recovery

+

When the Coordinator is configured with the initial manifest, it generates a random secret seed. +From this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history. +This derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state.

+

The secret seed is returned to the user on the first call to contrast set, encrypted with the user's public seed share owner key. +If no seed share owner key is provided, a key is generated and stored in the working directory.

+

Persistence

+

The Coordinator runs as a StatefulSet with a dynamically provisioned persistent volume. +This volume stores the manifest history and the associated runtime policies. +The manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads. +However, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users. +Thus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed.

+

Recovery

+

When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests. +It needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures. +This procedure is called recovery and is initiated by the workload owner. +The CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the Recover method. +The Coordinator recovers its key material and verifies the manifest history signature.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/basics/confidential-containers.html b/pr-preview/pr-976/0.8/basics/confidential-containers.html new file mode 100644 index 0000000000..aeedd05d59 --- /dev/null +++ b/pr-preview/pr-976/0.8/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/basics/features.html b/pr-preview/pr-976/0.8/basics/features.html new file mode 100644 index 0000000000..905711671d --- /dev/null +++ b/pr-preview/pr-976/0.8/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/basics/security-benefits.html b/pr-preview/pr-976/0.8/basics/security-benefits.html new file mode 100644 index 0000000000..1055a1f43d --- /dev/null +++ b/pr-preview/pr-976/0.8/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/components/overview.html b/pr-preview/pr-976/0.8/components/overview.html new file mode 100644 index 0000000000..59e3434822 --- /dev/null +++ b/pr-preview/pr-976/0.8/components/overview.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/components/policies.html b/pr-preview/pr-976/0.8/components/policies.html new file mode 100644 index 0000000000..479b6d570d --- /dev/null +++ b/pr-preview/pr-976/0.8/components/policies.html @@ -0,0 +1,77 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/components/runtime.html b/pr-preview/pr-976/0.8/components/runtime.html new file mode 100644 index 0000000000..40373cc0a2 --- /dev/null +++ b/pr-preview/pr-976/0.8/components/runtime.html @@ -0,0 +1,72 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

cloud-hypervisor virtual machine manager (VMM)

+

The containerd shim uses cloud-hypervisor to create a confidential virtual machine for every pod. +This requires the cloud-hypervisor binary to be installed on every node (responsibility of the node-installer).

+

Tardev snapshotter

+

Contrast uses a special containerd snapshotter (tardev) to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor as the virtual machine manager (VMM)
  • +
  • Install an IGVM file for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/components/service-mesh.html b/pr-preview/pr-976/0.8/components/service-mesh.html new file mode 100644 index 0000000000..c6dac0f28a --- /dev/null +++ b/pr-preview/pr-976/0.8/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables CONTRAST_INGRESS_PROXY_CONFIG, +CONTRAST_EGRESS_PROXY_CONFIG and CONTRAST_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: CONTRAST_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.8.1@sha256:de65f2921d617fd2cee3734c4d325b9464e655d3c29e95844163a0738937748a"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-tls-certs
mountPath: /tls-config
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/deployment.html b/pr-preview/pr-976/0.8/deployment.html new file mode 100644 index 0000000000..4946d08823 --- /dev/null +++ b/pr-preview/pr-976/0.8/deployment.html @@ -0,0 +1,130 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/runtime.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/coordinator.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-tls-certs shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate --reference-values aks-clh-snp resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --reference-values aks-clh-snp --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-tls-certs volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:v0.8.1@sha256:6260af0b4ee2b5e583970aaa74ba6f5cbaa4d2029bc2aef947987d2398f1164f"
name: contrast-initializer
volumeMounts:
- mountPath: /tls-config
name: contrast-tls-certs
volumes:
- emptyDir: {}
name: contrast-tls-certs
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

This will use the reference values from the manifest file to attest the Coordinator. +After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the +service mesh root certificate and the history of manifests into the verify/ directory. In addition, the policies +referenced in the active manifest are also written to the directory. The verification will fail if the active +manifest at the Coordinator doesn't match the manifest passed to the CLI.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Recover the Coordinator

+

If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material. +For demonstration purposes, you can simulate this scenario by deleting the Coordinator pod.

+
kubectl delete pod -l app.kubernetes.io/name=coordinator
+

Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet. +You can confirm this by running verify again, or you can restart a workload pod, which should stay in the initialization phase. +However, the secret seed in your working directory is sufficient to recover the coordinator.

+
contrast recover -c "${coordinator}:1313"
+

Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state. +You can now verify the Coordinator again, which should return the same manifest you set before.

+
warning

The recovery process invalidates the mesh CA certificate: +existing workloads won't be able to communicate with workloads newly spawned. +All workloads should be restarted after the recovery succeeded.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/examples/emojivoto.html b/pr-preview/pr-976/0.8/examples/emojivoto.html new file mode 100644 index 0000000000..3873c2e51e --- /dev/null +++ b/pr-preview/pr-976/0.8/examples/emojivoto.html @@ -0,0 +1,148 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+ +

Steps to deploy emojivoto with Contrast

+

Downloading the deployment

+

The emojivoto deployment files are part of Contrast release. You can download the +latest deployment by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.8.1/emojivoto-demo.yml --create-dirs --output-dir deployment
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/runtime.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate --reference-values aks-clh-snp deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<VERSIONHASH> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the reference values from the manifest to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313" -m manifest.json
+

The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs +to be communicated out of band to everyone wanting to verify the deployment, as the verify command checks +if the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/features-limitations.html b/pr-preview/pr-976/0.8/features-limitations.html new file mode 100644 index 0000000000..41cac12a2f --- /dev/null +++ b/pr-preview/pr-976/0.8/features-limitations.html @@ -0,0 +1,50 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Contrast only supports volumes with volumeMode: Block. These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+

Automatic recovery and high availability

+

The Contrast Coordinator is a singleton and can't be scaled to more than one instance. +When this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually. +In a future release, we plan to support distributed Coordinator instances that can recover automatically.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/getting-started/cluster-setup.html b/pr-preview/pr-976/0.8/getting-started/cluster-setup.html new file mode 100644 index 0000000000..6659bf520c --- /dev/null +++ b/pr-preview/pr-976/0.8/getting-started/cluster-setup.html @@ -0,0 +1,67 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which needs +to have the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a +non-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool.

+

We'll first start by creating the non-CoCo cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "${azResourceGroup:?}" \
--name nodepool2 \
--cluster-name "${azClusterName:?}" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Optionally, we can now remove the non-CoCo node pool:

+
az aks nodepool delete \
--resource-group "${azResourceGroup:?}" \
--cluster-name "${azClusterName:?}" \
--name nodepool1
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/getting-started/install.html b/pr-preview/pr-976/0.8/getting-started/install.html new file mode 100644 index 0000000000..a63026b6e6 --- /dev/null +++ b/pr-preview/pr-976/0.8/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.8.1/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.8/troubleshooting.html b/pr-preview/pr-976/0.8/troubleshooting.html new file mode 100644 index 0000000000..5f022de10d --- /dev/null +++ b/pr-preview/pr-976/0.8/troubleshooting.html @@ -0,0 +1,100 @@ + + + + + +Troubleshooting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.8

Troubleshooting

+

This section contains information on how to debug your Contrast deployment.

+

Logging

+

Collecting logs can be a good first step to identify problems in your +deployment. Both the CLI and the Contrast Coordinator as well as the Initializer +can be configured to emit additional logs.

+

CLI

+

The CLI logs can be configured with the --log-level command-line flag, which +can be set to either debug, info, warn or error. The default is info. +Setting this to debug can get more fine-grained information as to where the +problem lies.

+

Coordinator and Initializer

+

The logs from the Coordinator and the Initializer can be configured via the +environment variables CONTRAST_LOG_LEVEL, CONTRAST_LOG_FORMAT and +CONTRAST_LOG_SUBSYSTEMS.

+
    +
  • CONTRAST_LOG_LEVEL can be set to one of either debug, info, warn, or +error, similar to the CLI (defaults to info).
  • +
  • CONTRAST_LOG_FORMAT can be set to text or json, determining the output +format (defaults to text).
  • +
  • CONTRAST_LOG_SUBSYSTEMS is a comma-seperated list of subsystems that should +be enabled for logging, which are disabled by default. Subsystems include: +snp-issuer, kds-getter, and snp-validator. To enable all subsystems, use +* as the value for this environment variable. +Warnings and error messages from subsystems get printed regardless of whether +the subsystem is listed in the CONTRAST_LOG_SUBSYSTEMS environment variable.
  • +
+

To configure debug logging with all subsystems for your Coordinator, add the +following variables to your container definition.

+
spec: # v1.PodSpec
containers:
image: "ghcr.io/edgelesssys/contrast/coordinator:v0.8.1@sha256:bcd08a03096d38b350853c1dc8a595e0e8dd18e6af651bad4afd6838d842e257"
name: coordinator
env:
- name: CONTRAST_LOG_LEVEL
value: debug
- name: CONTRAST_LOG_SUBSYSTEMS
value: "*"
# ...
+
info

While the Contrast Coordinator has a policy that allows certain configurations, +the Initializer and service mesh don't. When changing environment variables of other +parts than the Coordinator, ensure to rerun contrast generate to update the policy.

+

To access the logs generated by the Coordinator, you can use kubectl with the +following command:

+
kubectl logs <coordinator-pod-name>
+

Pod fails to start

+

If the Coordinator or a workload pod fails to even start, it can be helpful to +look at the events of the pod during the startup process using the describe +command.

+
kubectl -n <namespace> events --for pod/<coordinator-pod-name>
+

Example output:

+
LAST SEEN  TYPE     REASON  OBJECT             MESSAGE
32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...
+

A common error, as in this example, is that the container creation was blocked by the +policy. Potential reasons are a modification of the deployment YAML without updating +the policies afterward, or a version mismatch between Contrast components.

+

Regenerating the policies

+

To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated +policies, rerun

+
contrast generate
+

on your deployment. If any of the policy annotations change, re-deploy with the updated policies.

+

Pin container images

+

When generating the policies, Contrast will download the images specified in your deployment +YAML and include their cryptographic identity. If the image tag is moved to another +container image after the policy has been generated, the image downloaded at deploy time +will differ from the one at generation time, and the policy enforcement won't allow the +container to be started in the pod VM.

+

To ensure the correct image is always used, pin the container image to a fixed sha256:

+
image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac
+

This way, the same image will still be pulled when the container tag (22.04) is moved +to another image.

+

Validate Contrast components match

+

A version mismatch between Contrast components can cause policy validation or attestation +to fail. Each Contrast runtime is identifiable based on its (shortened) measurement value +used to name the runtime class version.

+

First, analyze which runtime class is currently installed in your cluster by running

+
kubectl get runtimeclasses
+

This should give you output similar to the following one.

+
NAME                                           HANDLER                                        AGE
contrast-cc-30bfa8706b542271ec9b7762bbb400af contrast-cc-30bfa8706b542271ec9b7762bbb400af 23d
contrast-cc-4d70a6e266cca46dfa8e41d92874e638 contrast-cc-4d70a6e266cca46dfa8e41d92874e638 7d
contrast-cc-b817659e094106f61bf6c178c27153ba contrast-cc-b817659e094106f61bf6c178c27153ba 2d19h
contrast-cc-beee79ca916b9e5dc59602788cbfb097 contrast-cc-beee79ca916b9e5dc59602788cbfb097 121m
kata-cc-isolation kata-cc 45d
+

The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided +by the AKS CoCo preview, which isn't used by Contrast).

+

Next, check if the pod that won't start has the correct runtime class configured, and the +Coordinator uses the exact same runtime:

+
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>
+

The output should list the runtime class the pod is using:

+
contrast-cc-beee79ca916b9e5dc59602788cbfb097
contrast-cc-beee79ca916b9e5dc59602788cbfb097
+

Version information about the currently used CLI can be obtained via the version flag:

+
contrast --version
+
contrast version v0.X.0

runtime handler: contrast-cc-beee79ca916b9e5dc59602788cbfb097
launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35
genpolicy version: 3.2.0.azl1.genpolicy0
image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...
ghcr.io/edgelesssys/contrast/initializer@sha256:...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9.html b/pr-preview/pr-976/0.9.html new file mode 100644 index 0000000000..6199d901be --- /dev/null +++ b/pr-preview/pr-976/0.9.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/about/telemetry.html b/pr-preview/pr-976/0.9/about/telemetry.html new file mode 100644 index 0000000000..db74c53960 --- /dev/null +++ b/pr-preview/pr-976/0.9/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/architecture/attestation.html b/pr-preview/pr-976/0.9/architecture/attestation.html new file mode 100644 index 0000000000..bb073b7fa9 --- /dev/null +++ b/pr-preview/pr-976/0.9/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +On AMD SEV-SNP the hash of the policy is then added to the attestation report via the HOSTDATA field by the hypervisor. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/architecture/certificates.html b/pr-preview/pr-976/0.9/architecture/certificates.html new file mode 100644 index 0000000000..247958a935 --- /dev/null +++ b/pr-preview/pr-976/0.9/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/architecture/observability.html b/pr-preview/pr-976/0.9/architecture/observability.html new file mode 100644 index 0000000000..c55de80c88 --- /dev/null +++ b/pr-preview/pr-976/0.9/architecture/observability.html @@ -0,0 +1,65 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator exports gRPC metrics under the prefix contrast_grpc_server_. +These metrics are labeled with the gRPC service name and method name. +Metrics of interest include contrast_grpc_server_handled_total, which counts +the number of requests by return code, and +contrast_grpc_server_handling_seconds_bucket, which produces a histogram of
+request latency.

+

The gRPC service userapi.UserAPI records metrics for the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively.

+

The meshapi.MeshAPI service records metrics for the method NewMeshCert, which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures_total.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/architecture/secrets.html b/pr-preview/pr-976/0.9/architecture/secrets.html new file mode 100644 index 0000000000..54bc125be3 --- /dev/null +++ b/pr-preview/pr-976/0.9/architecture/secrets.html @@ -0,0 +1,39 @@ + + + + + +Secrets & recovery | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Secrets & recovery

+

When the Coordinator is configured with the initial manifest, it generates a random secret seed. +From this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history. +This derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state.

+

The secret seed is returned to the user on the first call to contrast set, encrypted with the user's public seed share owner key. +If no seed share owner key is provided, a key is generated and stored in the working directory.

+

Persistence

+

The Coordinator runs as a StatefulSet with a dynamically provisioned persistent volume. +This volume stores the manifest history and the associated runtime policies. +The manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads. +However, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users. +Thus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed.

+

Recovery

+

When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests. +It needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures. +This procedure is called recovery and is initiated by the workload owner. +The CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the Recover method. +The Coordinator recovers its key material and verifies the manifest history signature.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/basics/confidential-containers.html b/pr-preview/pr-976/0.9/basics/confidential-containers.html new file mode 100644 index 0000000000..329a5ddfde --- /dev/null +++ b/pr-preview/pr-976/0.9/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/basics/features.html b/pr-preview/pr-976/0.9/basics/features.html new file mode 100644 index 0000000000..1e93cf33a6 --- /dev/null +++ b/pr-preview/pr-976/0.9/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/basics/security-benefits.html b/pr-preview/pr-976/0.9/basics/security-benefits.html new file mode 100644 index 0000000000..7b2a9dc136 --- /dev/null +++ b/pr-preview/pr-976/0.9/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/components/overview.html b/pr-preview/pr-976/0.9/components/overview.html new file mode 100644 index 0000000000..4f0f6a8976 --- /dev/null +++ b/pr-preview/pr-976/0.9/components/overview.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/components/policies.html b/pr-preview/pr-976/0.9/components/policies.html new file mode 100644 index 0000000000..a78fab0ea4 --- /dev/null +++ b/pr-preview/pr-976/0.9/components/policies.html @@ -0,0 +1,77 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/components/runtime.html b/pr-preview/pr-976/0.9/components/runtime.html new file mode 100644 index 0000000000..75a98d42c4 --- /dev/null +++ b/pr-preview/pr-976/0.9/components/runtime.html @@ -0,0 +1,72 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

cloud-hypervisor virtual machine manager (VMM)

+

The containerd shim uses cloud-hypervisor to create a confidential virtual machine for every pod. +This requires the cloud-hypervisor binary to be installed on every node (responsibility of the node-installer).

+

Tardev snapshotter

+

Contrast uses a special containerd snapshotter (tardev) to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor as the virtual machine manager (VMM)
  • +
  • Install an IGVM file for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/components/service-mesh.html b/pr-preview/pr-976/0.9/components/service-mesh.html new file mode 100644 index 0000000000..bd02ca79ed --- /dev/null +++ b/pr-preview/pr-976/0.9/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables CONTRAST_INGRESS_PROXY_CONFIG, +CONTRAST_EGRESS_PROXY_CONFIG and CONTRAST_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: CONTRAST_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.9.0@sha256:d97397770b8ea13082eab96099629f971688508e5b0cc1596df07aa5510d5972"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-tls-certs
mountPath: /tls-config
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/deployment.html b/pr-preview/pr-976/0.9/deployment.html new file mode 100644 index 0000000000..b65f098145 --- /dev/null +++ b/pr-preview/pr-976/0.9/deployment.html @@ -0,0 +1,130 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/runtime.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/coordinator.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-tls-certs shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate --reference-values aks-clh-snp resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --reference-values aks-clh-snp --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-tls-certs volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:v0.9.0@sha256:ca1ee62f9abb47224a70cb4b1a4593b3fa83481e083047ec707ded911baf134b"
name: contrast-initializer
volumeMounts:
- mountPath: /tls-config
name: contrast-tls-certs
volumes:
- emptyDir: {}
name: contrast-tls-certs
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

This will use the reference values from the manifest file to attest the Coordinator. +After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the +service mesh root certificate and the history of manifests into the verify/ directory. In addition, the policies +referenced in the active manifest are also written to the directory. The verification will fail if the active +manifest at the Coordinator doesn't match the manifest passed to the CLI.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Recover the Coordinator

+

If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material. +For demonstration purposes, you can simulate this scenario by deleting the Coordinator pod.

+
kubectl delete pod -l app.kubernetes.io/name=coordinator
+

Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet. +You can confirm this by running verify again, or you can restart a workload pod, which should stay in the initialization phase. +However, the secret seed in your working directory is sufficient to recover the coordinator.

+
contrast recover -c "${coordinator}:1313"
+

Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state. +You can now verify the Coordinator again, which should return the same manifest you set before.

+
warning

The recovery process invalidates the mesh CA certificate: +existing workloads won't be able to communicate with workloads newly spawned. +All workloads should be restarted after the recovery succeeded.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/examples/emojivoto.html b/pr-preview/pr-976/0.9/examples/emojivoto.html new file mode 100644 index 0000000000..1c1459ff11 --- /dev/null +++ b/pr-preview/pr-976/0.9/examples/emojivoto.html @@ -0,0 +1,148 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+ +

Steps to deploy emojivoto with Contrast

+

Downloading the deployment

+

The emojivoto deployment files are part of Contrast release. You can download the +latest deployment by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.9.0/emojivoto-demo.yml --create-dirs --output-dir deployment
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/runtime.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate --reference-values aks-clh-snp deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<platform>-<runtime-hash> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the reference values from the manifest to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313" -m manifest.json
+

The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs +to be communicated out of band to everyone wanting to verify the deployment, as the verify command checks +if the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/features-limitations.html b/pr-preview/pr-976/0.9/features-limitations.html new file mode 100644 index 0000000000..bafe2be549 --- /dev/null +++ b/pr-preview/pr-976/0.9/features-limitations.html @@ -0,0 +1,50 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Contrast only supports volumes with volumeMode: Block. These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+

Automatic recovery and high availability

+

The Contrast Coordinator is a singleton and can't be scaled to more than one instance. +When this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually. +In a future release, we plan to support distributed Coordinator instances that can recover automatically.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/getting-started/cluster-setup.html b/pr-preview/pr-976/0.9/getting-started/cluster-setup.html new file mode 100644 index 0000000000..da7f225c37 --- /dev/null +++ b/pr-preview/pr-976/0.9/getting-started/cluster-setup.html @@ -0,0 +1,67 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which needs +to have the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a +non-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool.

+

We'll first start by creating the non-CoCo cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "${azResourceGroup:?}" \
--name nodepool2 \
--cluster-name "${azClusterName:?}" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Optionally, we can now remove the non-CoCo node pool:

+
az aks nodepool delete \
--resource-group "${azResourceGroup:?}" \
--cluster-name "${azClusterName:?}" \
--name nodepool1
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/getting-started/install.html b/pr-preview/pr-976/0.9/getting-started/install.html new file mode 100644 index 0000000000..127d15b079 --- /dev/null +++ b/pr-preview/pr-976/0.9/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.9.0/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/0.9/troubleshooting.html b/pr-preview/pr-976/0.9/troubleshooting.html new file mode 100644 index 0000000000..11eb82addf --- /dev/null +++ b/pr-preview/pr-976/0.9/troubleshooting.html @@ -0,0 +1,100 @@ + + + + + +Troubleshooting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 0.9

Troubleshooting

+

This section contains information on how to debug your Contrast deployment.

+

Logging

+

Collecting logs can be a good first step to identify problems in your +deployment. Both the CLI and the Contrast Coordinator as well as the Initializer +can be configured to emit additional logs.

+

CLI

+

The CLI logs can be configured with the --log-level command-line flag, which +can be set to either debug, info, warn or error. The default is info. +Setting this to debug can get more fine-grained information as to where the +problem lies.

+

Coordinator and Initializer

+

The logs from the Coordinator and the Initializer can be configured via the +environment variables CONTRAST_LOG_LEVEL, CONTRAST_LOG_FORMAT and +CONTRAST_LOG_SUBSYSTEMS.

+
    +
  • CONTRAST_LOG_LEVEL can be set to one of either debug, info, warn, or +error, similar to the CLI (defaults to info).
  • +
  • CONTRAST_LOG_FORMAT can be set to text or json, determining the output +format (defaults to text).
  • +
  • CONTRAST_LOG_SUBSYSTEMS is a comma-seperated list of subsystems that should +be enabled for logging, which are disabled by default. Subsystems include: +kds-getter, issuer and validator. +To enable all subsystems, use * as the value for this environment variable. +Warnings and error messages from subsystems get printed regardless of whether +the subsystem is listed in the CONTRAST_LOG_SUBSYSTEMS environment variable.
  • +
+

To configure debug logging with all subsystems for your Coordinator, add the +following variables to your container definition.

+
spec: # v1.PodSpec
containers:
image: "ghcr.io/edgelesssys/contrast/coordinator:v0.9.0@sha256:7530dcd0bd16b5dbeda915c8ebfeb5d860c2f9e4661acbc70fdaae60bf174e20"
name: coordinator
env:
- name: CONTRAST_LOG_LEVEL
value: debug
- name: CONTRAST_LOG_SUBSYSTEMS
value: "*"
# ...
+
info

While the Contrast Coordinator has a policy that allows certain configurations, +the Initializer and service mesh don't. When changing environment variables of other +parts than the Coordinator, ensure to rerun contrast generate to update the policy.

+

To access the logs generated by the Coordinator, you can use kubectl with the +following command:

+
kubectl logs <coordinator-pod-name>
+

Pod fails to start

+

If the Coordinator or a workload pod fails to even start, it can be helpful to +look at the events of the pod during the startup process using the describe +command.

+
kubectl -n <namespace> events --for pod/<coordinator-pod-name>
+

Example output:

+
LAST SEEN  TYPE     REASON  OBJECT             MESSAGE
32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...
+

A common error, as in this example, is that the container creation was blocked by the +policy. Potential reasons are a modification of the deployment YAML without updating +the policies afterward, or a version mismatch between Contrast components.

+

Regenerating the policies

+

To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated +policies, rerun

+
contrast generate
+

on your deployment. If any of the policy annotations change, re-deploy with the updated policies.

+

Pin container images

+

When generating the policies, Contrast will download the images specified in your deployment +YAML and include their cryptographic identity. If the image tag is moved to another +container image after the policy has been generated, the image downloaded at deploy time +will differ from the one at generation time, and the policy enforcement won't allow the +container to be started in the pod VM.

+

To ensure the correct image is always used, pin the container image to a fixed sha256:

+
image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac
+

This way, the same image will still be pulled when the container tag (22.04) is moved +to another image.

+

Validate Contrast components match

+

A version mismatch between Contrast components can cause policy validation or attestation +to fail. Each Contrast runtime is identifiable based on its (shortened) measurement value +used to name the runtime class version.

+

First, analyze which runtime class is currently installed in your cluster by running

+
kubectl get runtimeclasses
+

This should give you output similar to the following one.

+
NAME                                           HANDLER                                        AGE
contrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h
kata-cc-isolation kata-cc 45d
+

The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided +by the AKS CoCo preview, which isn't used by Contrast).

+

Next, check if the pod that won't start has the correct runtime class configured, and the +Coordinator uses the exact same runtime:

+
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>
+

The output should list the runtime class the pod is using:

+
contrast-cc-aks-clh-snp-7173acb5
+

Version information about the currently used CLI can be obtained via the version flag:

+
contrast --version
+
contrast version v0.X.0

runtime handler: contrast-cc-aks-clh-snp-7173acb5
launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35
genpolicy version: 3.2.0.azl1.genpolicy0
image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...
ghcr.io/edgelesssys/contrast/initializer@sha256:...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0.html b/pr-preview/pr-976/1.0.html new file mode 100644 index 0000000000..7195e865e1 --- /dev/null +++ b/pr-preview/pr-976/1.0.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/about/telemetry.html b/pr-preview/pr-976/1.0/about/telemetry.html new file mode 100644 index 0000000000..b419e8cb19 --- /dev/null +++ b/pr-preview/pr-976/1.0/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/architecture/attestation.html b/pr-preview/pr-976/1.0/architecture/attestation.html new file mode 100644 index 0000000000..7ebf28afb1 --- /dev/null +++ b/pr-preview/pr-976/1.0/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +On AMD SEV-SNP the hash of the policy is then added to the attestation report via the HOSTDATA field by the hypervisor. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/architecture/certificates.html b/pr-preview/pr-976/1.0/architecture/certificates.html new file mode 100644 index 0000000000..2afbe9f8b3 --- /dev/null +++ b/pr-preview/pr-976/1.0/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/architecture/observability.html b/pr-preview/pr-976/1.0/architecture/observability.html new file mode 100644 index 0000000000..2f81113530 --- /dev/null +++ b/pr-preview/pr-976/1.0/architecture/observability.html @@ -0,0 +1,65 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator exports gRPC metrics under the prefix contrast_grpc_server_. +These metrics are labeled with the gRPC service name and method name. +Metrics of interest include contrast_grpc_server_handled_total, which counts +the number of requests by return code, and +contrast_grpc_server_handling_seconds_bucket, which produces a histogram of
+request latency.

+

The gRPC service userapi.UserAPI records metrics for the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively.

+

The meshapi.MeshAPI service records metrics for the method NewMeshCert, which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures_total.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/architecture/secrets.html b/pr-preview/pr-976/1.0/architecture/secrets.html new file mode 100644 index 0000000000..ccf4fb594d --- /dev/null +++ b/pr-preview/pr-976/1.0/architecture/secrets.html @@ -0,0 +1,45 @@ + + + + + +Secrets & recovery | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Secrets & recovery

+

When the Coordinator is configured with the initial manifest, it generates a random secret seed. +From this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history. +This derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state.

+

The secret seed is returned to the user on the first call to contrast set, encrypted with the user's public seed share owner key. +If no seed share owner key is provided, a key is generated and stored in the working directory.

+

Persistence

+

The Coordinator runs as a StatefulSet with a dynamically provisioned persistent volume. +This volume stores the manifest history and the associated runtime policies. +The manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads. +However, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users. +Thus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed.

+

Recovery

+

When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests. +It needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures. +This procedure is called recovery and is initiated by the workload owner. +The CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the Recover method. +The Coordinator recovers its key material and verifies the manifest history signature.

+

Workload Secrets

+

The Coordinator provides each workload a secret seed during attestation. This secret can be used by the workload to derive additional secrets for example to +encrypt persistent data. Like the workload certificates it's mounted in the shared Kubernetes volume contrast-secrets in the path <mountpoint>/secrets/workload-secret-seed.

+
warning

The workload owner can decrypt data encrypted with secrets derived from the workload secret. +The workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner. +If the data owner and the workload owner is the same entity, then they can safely use the workload secrets.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/basics/confidential-containers.html b/pr-preview/pr-976/1.0/basics/confidential-containers.html new file mode 100644 index 0000000000..37fb3b00e7 --- /dev/null +++ b/pr-preview/pr-976/1.0/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/basics/features.html b/pr-preview/pr-976/1.0/basics/features.html new file mode 100644 index 0000000000..cfbd684539 --- /dev/null +++ b/pr-preview/pr-976/1.0/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/basics/security-benefits.html b/pr-preview/pr-976/1.0/basics/security-benefits.html new file mode 100644 index 0000000000..28cbbe595f --- /dev/null +++ b/pr-preview/pr-976/1.0/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/components/overview.html b/pr-preview/pr-976/1.0/components/overview.html new file mode 100644 index 0000000000..4361ba3a0d --- /dev/null +++ b/pr-preview/pr-976/1.0/components/overview.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/components/policies.html b/pr-preview/pr-976/1.0/components/policies.html new file mode 100644 index 0000000000..6450ea6453 --- /dev/null +++ b/pr-preview/pr-976/1.0/components/policies.html @@ -0,0 +1,77 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/components/runtime.html b/pr-preview/pr-976/1.0/components/runtime.html new file mode 100644 index 0000000000..5013e81440 --- /dev/null +++ b/pr-preview/pr-976/1.0/components/runtime.html @@ -0,0 +1,72 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

cloud-hypervisor virtual machine manager (VMM)

+

The containerd shim uses cloud-hypervisor to create a confidential virtual machine for every pod. +This requires the cloud-hypervisor binary to be installed on every node (responsibility of the node-installer).

+

Tardev snapshotter

+

Contrast uses a special containerd snapshotter (tardev) to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor as the virtual machine manager (VMM)
  • +
  • Install an IGVM file for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/components/service-mesh.html b/pr-preview/pr-976/1.0/components/service-mesh.html new file mode 100644 index 0000000000..b4e032c568 --- /dev/null +++ b/pr-preview/pr-976/1.0/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables CONTRAST_INGRESS_PROXY_CONFIG, +CONTRAST_EGRESS_PROXY_CONFIG and CONTRAST_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: CONTRAST_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v1.0.0@sha256:2aa3a6711ed8dee36a8dcdae63dd10b9fd5bb9aac6dba688ed1be8ab1fbb310e"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-secrets
mountPath: /contrast
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/deployment.html b/pr-preview/pr-976/1.0/deployment.html new file mode 100644 index 0000000000..97bd59e860 --- /dev/null +++ b/pr-preview/pr-976/1.0/deployment.html @@ -0,0 +1,130 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set it up.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/runtime.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/coordinator.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-secrets shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate --reference-values aks-clh-snp resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --reference-values aks-clh-snp --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-secrets volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:v1.0.0@sha256:a86b8637016aff07fe157f6334f58033707f2d657263e956f195a5254e1ee9b5"
name: contrast-initializer
volumeMounts:
- mountPath: /contrast
name: contrast-secrets
volumes:
- emptyDir: {}
name: contrast-secrets
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

This will use the reference values from the manifest file to attest the Coordinator. +After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the +service mesh root certificate and the history of manifests into the verify/ directory. In addition, the policies +referenced in the active manifest are also written to the directory. The verification will fail if the active +manifest at the Coordinator doesn't match the manifest passed to the CLI.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Recover the Coordinator

+

If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material. +For demonstration purposes, you can simulate this scenario by deleting the Coordinator pod.

+
kubectl delete pod -l app.kubernetes.io/name=coordinator
+

Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet. +You can confirm this by running verify again, or you can restart a workload pod, which should stay in the initialization phase. +However, the secret seed in your working directory is sufficient to recover the coordinator.

+
contrast recover -c "${coordinator}:1313"
+

Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state. +You can now verify the Coordinator again, which should return the same manifest you set before.

+
warning

The recovery process invalidates the mesh CA certificate: +existing workloads won't be able to communicate with workloads newly spawned. +All workloads should be restarted after the recovery succeeded.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/examples/emojivoto.html b/pr-preview/pr-976/1.0/examples/emojivoto.html new file mode 100644 index 0000000000..44e21ed27e --- /dev/null +++ b/pr-preview/pr-976/1.0/examples/emojivoto.html @@ -0,0 +1,148 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voters perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

emojivoto components topology

+

Motivation

+

Using a voting service, users' votes are considered highly sensitive data, as we require +a secret ballot. Also, users are likely interested in the fairness of the ballot. For +both requirements, we can use Confidential Computing and, specifically, workload attestation +to prove to those interested in voting that the app is running in a protected environment +where their votes are processed without leaking to the platform provider or workload owner.

+

Prerequisites

+ +

Steps to deploy emojivoto with Contrast

+

Downloading the deployment

+

The emojivoto deployment files are part of Contrast release. You can download the +latest deployment by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/download/v1.0.0/emojivoto-demo.yml --create-dirs --output-dir deployment
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/runtime.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/coordinator.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate --reference-values aks-clh-snp deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<platform>-<runtime-hash> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the reference values from the manifest to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Voter's perspective: Verifying the ballot

+

As voters, we want to verify the fairness and confidentiality of the deployment before +deciding to vote. Regardless of the scale of our distributed deployment, Contrast only +needs a single remote attestation step to verify the deployment. By doing remote attestation +of the Coordinator, we transitively verify those systems the Coordinator has already attested +or will attest in the future. Successful verification of the Coordinator means that +we can be sure it will enforce the configured manifest.

+

Attest the Coordinator

+

A potential voter can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313" -m manifest.json
+

The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs +to be communicated out of band to everyone wanting to verify the deployment, as the verify command checks +if the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+

Manifest history and artifact audit

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Confidential connection to the attested workload

+

After ensuring the configuration of the Coordinator fits the expectation, you can securely connect +to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Certificate SAN and manifest update (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configure the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
"SANs": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
"WorkloadSecretID": "web"
},
+

Update the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/features-limitations.html b/pr-preview/pr-976/1.0/features-limitations.html new file mode 100644 index 0000000000..c6a32d9b3e --- /dev/null +++ b/pr-preview/pr-976/1.0/features-limitations.html @@ -0,0 +1,50 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Contrast only supports volumes with volumeMode: Block. These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+

Automatic recovery and high availability

+

The Contrast Coordinator is a singleton and can't be scaled to more than one instance. +When this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually. +In a future release, we plan to support distributed Coordinator instances that can recover automatically.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/getting-started/cluster-setup.html b/pr-preview/pr-976/1.0/getting-started/cluster-setup.html new file mode 100644 index 0000000000..1ff195ae09 --- /dev/null +++ b/pr-preview/pr-976/1.0/getting-started/cluster-setup.html @@ -0,0 +1,67 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Create a cluster

+

Prerequisites

+

Install the latest version of the Azure CLI.

+

Login to your account, which needs +to have the permissions to create an AKS cluster, by executing:

+
az login
+

Prepare using the AKS preview

+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a +non-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool.

+

We'll first start by creating the non-CoCo cluster:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.29 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--node-count 1 \
--generate-ssh-keys
+

We then add a second node pool with CoCo support:

+
az aks nodepool add \
--resource-group "${azResourceGroup:?}" \
--name nodepool2 \
--cluster-name "${azClusterName:?}" \
--node-count 1 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation
+

Optionally, we can now remove the non-CoCo node pool:

+
az aks nodepool delete \
--resource-group "${azResourceGroup:?}" \
--cluster-name "${azClusterName:?}" \
--name nodepool1
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show two nodes:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
aks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0
+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/getting-started/install.html b/pr-preview/pr-976/1.0/getting-started/install.html new file mode 100644 index 0000000000..b8c53b5b4a --- /dev/null +++ b/pr-preview/pr-976/1.0/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v1.0.0/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/1.0/troubleshooting.html b/pr-preview/pr-976/1.0/troubleshooting.html new file mode 100644 index 0000000000..c0e92b5489 --- /dev/null +++ b/pr-preview/pr-976/1.0/troubleshooting.html @@ -0,0 +1,100 @@ + + + + + +Troubleshooting | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.0

Troubleshooting

+

This section contains information on how to debug your Contrast deployment.

+

Logging

+

Collecting logs can be a good first step to identify problems in your +deployment. Both the CLI and the Contrast Coordinator as well as the Initializer +can be configured to emit additional logs.

+

CLI

+

The CLI logs can be configured with the --log-level command-line flag, which +can be set to either debug, info, warn or error. The default is info. +Setting this to debug can get more fine-grained information as to where the +problem lies.

+

Coordinator and Initializer

+

The logs from the Coordinator and the Initializer can be configured via the +environment variables CONTRAST_LOG_LEVEL, CONTRAST_LOG_FORMAT and +CONTRAST_LOG_SUBSYSTEMS.

+
    +
  • CONTRAST_LOG_LEVEL can be set to one of either debug, info, warn, or +error, similar to the CLI (defaults to info).
  • +
  • CONTRAST_LOG_FORMAT can be set to text or json, determining the output +format (defaults to text).
  • +
  • CONTRAST_LOG_SUBSYSTEMS is a comma-seperated list of subsystems that should +be enabled for logging, which are disabled by default. Subsystems include: +kds-getter, issuer and validator. +To enable all subsystems, use * as the value for this environment variable. +Warnings and error messages from subsystems get printed regardless of whether +the subsystem is listed in the CONTRAST_LOG_SUBSYSTEMS environment variable.
  • +
+

To configure debug logging with all subsystems for your Coordinator, add the +following variables to your container definition.

+
spec: # v1.PodSpec
containers:
image: "ghcr.io/edgelesssys/contrast/coordinator:v1.0.0@sha256:36766ae51dbafa4ef5e90c3e24698bdfbb3b4d765e13c14bdee190a1a7638c35"
name: coordinator
env:
- name: CONTRAST_LOG_LEVEL
value: debug
- name: CONTRAST_LOG_SUBSYSTEMS
value: "*"
# ...
+
info

While the Contrast Coordinator has a policy that allows certain configurations, +the Initializer and service mesh don't. When changing environment variables of other +parts than the Coordinator, ensure to rerun contrast generate to update the policy.

+

To access the logs generated by the Coordinator, you can use kubectl with the +following command:

+
kubectl logs <coordinator-pod-name>
+

Pod fails to start

+

If the Coordinator or a workload pod fails to even start, it can be helpful to +look at the events of the pod during the startup process using the describe +command.

+
kubectl -n <namespace> events --for pod/<coordinator-pod-name>
+

Example output:

+
LAST SEEN  TYPE     REASON  OBJECT             MESSAGE
32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...
+

A common error, as in this example, is that the container creation was blocked by the +policy. Potential reasons are a modification of the deployment YAML without updating +the policies afterward, or a version mismatch between Contrast components.

+

Regenerating the policies

+

To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated +policies, rerun

+
contrast generate
+

on your deployment. If any of the policy annotations change, re-deploy with the updated policies.

+

Pin container images

+

When generating the policies, Contrast will download the images specified in your deployment +YAML and include their cryptographic identity. If the image tag is moved to another +container image after the policy has been generated, the image downloaded at deploy time +will differ from the one at generation time, and the policy enforcement won't allow the +container to be started in the pod VM.

+

To ensure the correct image is always used, pin the container image to a fixed sha256:

+
image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac
+

This way, the same image will still be pulled when the container tag (22.04) is moved +to another image.

+

Validate Contrast components match

+

A version mismatch between Contrast components can cause policy validation or attestation +to fail. Each Contrast runtime is identifiable based on its (shortened) measurement value +used to name the runtime class version.

+

First, analyze which runtime class is currently installed in your cluster by running

+
kubectl get runtimeclasses
+

This should give you output similar to the following one.

+
NAME                                           HANDLER                                        AGE
contrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h
kata-cc-isolation kata-cc 45d
+

The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided +by the AKS CoCo preview, which isn't used by Contrast).

+

Next, check if the pod that won't start has the correct runtime class configured, and the +Coordinator uses the exact same runtime:

+
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>
+

The output should list the runtime class the pod is using:

+
contrast-cc-aks-clh-snp-7173acb5
+

Version information about the currently used CLI can be obtained via the version flag:

+
contrast --version
+
contrast version v0.X.0

runtime handler: contrast-cc-aks-clh-snp-7173acb5
launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35
genpolicy version: 3.2.0.azl1.genpolicy0
image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...
ghcr.io/edgelesssys/contrast/initializer@sha256:...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/404.html b/pr-preview/pr-976/404.html new file mode 100644 index 0000000000..36b86ffd69 --- /dev/null +++ b/pr-preview/pr-976/404.html @@ -0,0 +1,22 @@ + + + + + +Contrast + + + + + + + + + + + + + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/about/telemetry.html b/pr-preview/pr-976/about/telemetry.html new file mode 100644 index 0000000000..f77ae98a8e --- /dev/null +++ b/pr-preview/pr-976/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/architecture/attestation.html b/pr-preview/pr-976/architecture/attestation.html new file mode 100644 index 0000000000..e77aa52f2f --- /dev/null +++ b/pr-preview/pr-976/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +The hypervisor adds the hash of the policy to the attestation report via the HOSTDATA (on AMD SEV-SNP) or MRCONFIGID (Intel TDX) fields. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA/MRCONFIGID field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP or Intel TDX to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/architecture/certificates.html b/pr-preview/pr-976/architecture/certificates.html new file mode 100644 index 0000000000..be36920f9c --- /dev/null +++ b/pr-preview/pr-976/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/architecture/observability.html b/pr-preview/pr-976/architecture/observability.html new file mode 100644 index 0000000000..c2bb82ffa9 --- /dev/null +++ b/pr-preview/pr-976/architecture/observability.html @@ -0,0 +1,65 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator exports gRPC metrics under the prefix contrast_grpc_server_. +These metrics are labeled with the gRPC service name and method name. +Metrics of interest include contrast_grpc_server_handled_total, which counts +the number of requests by return code, and +contrast_grpc_server_handling_seconds_bucket, which produces a histogram of
+request latency.

+

The gRPC service userapi.UserAPI records metrics for the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively.

+

The meshapi.MeshAPI service records metrics for the method NewMeshCert, which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures_total.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/architecture/secrets.html b/pr-preview/pr-976/architecture/secrets.html new file mode 100644 index 0000000000..c17bb5f93a --- /dev/null +++ b/pr-preview/pr-976/architecture/secrets.html @@ -0,0 +1,45 @@ + + + + + +Secrets & recovery | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

Secrets & recovery

+

When the Coordinator is configured with the initial manifest, it generates a random secret seed. +From this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history. +This derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state.

+

The secret seed is returned to the user on the first call to contrast set, encrypted with the user's public seed share owner key. +If no seed share owner key is provided, a key is generated and stored in the working directory.

+

Persistence

+

The Coordinator runs as a StatefulSet with a dynamically provisioned persistent volume. +This volume stores the manifest history and the associated runtime policies. +The manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads. +However, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users. +Thus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed.

+

Recovery

+

When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests. +It needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures. +This procedure is called recovery and is initiated by the workload owner. +The CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the Recover method. +The Coordinator recovers its key material and verifies the manifest history signature.

+

Workload Secrets

+

The Coordinator provides each workload a secret seed during attestation. This secret can be used by the workload to derive additional secrets for example to +encrypt persistent data. Like the workload certificates it's mounted in the shared Kubernetes volume contrast-secrets in the path <mountpoint>/secrets/workload-secret-seed.

+
warning

The workload owner can decrypt data encrypted with secrets derived from the workload secret. +The workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner. +If the data owner and the workload owner is the same entity, then they can safely use the workload secrets.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/architecture/security-considerations.html b/pr-preview/pr-976/architecture/security-considerations.html new file mode 100644 index 0000000000..e93d339e29 --- /dev/null +++ b/pr-preview/pr-976/architecture/security-considerations.html @@ -0,0 +1,68 @@ + + + + + +Security Considerations | Contrast + + + + + + + + + + + + + +
Skip to main content
Version: 1.1

Security Considerations

+

Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits). +However, care must be taken when interacting with the outside of Contrast's confidential environment. +This page presents some tips for writing secure applications and outlines the trust boundaries app developers need to know.

+

General recommendations

+

Authentication

+

The application receives credentials from the Contrast Coordinator during initialization. +This allows to authenticate towards peers and to verify credentials received from peers. +The application should use the certificate bundle to authenticate incoming requests and be wary of unauthenticated requests or requests with a different root of trust (for example the internet PKI).

+

The recommendation to authenticate not only applies to network traffic, but also to volumes, GPUs and other devices. +Generally speaking, all information provided by the world outside the confidential VM should be treated with due scepticism, especially if it's not authenticated. +Common cases where Kubernetes apps interact with external services include DNS, Kubernetes API clients and cloud storage endpoints.

+

Encryption

+

Any external persistence should be encrypted with an authenticated cipher. +This recommendation applies to block devices or filesystems mounted into the container, but also to cloud blob storage or external databases.

+

Contrast security guarantees

+

If an application authenticates with a certificate signed by the Contrast Mesh CA of a given manifest, Contrast provides the following guarantees:

+
    +
  1. The container images used by the app are the images specified in the resource definitions.
  2. +
  3. The command line arguments of containers are exactly the arguments specified in the resource definitions.
  4. +
  5. All environment variables are either specified in resource definitions, in the container image manifest or in a settings file for the Contrast CLI.
  6. +
  7. The containers run in a confidential VM that matches the reference values in the manifest.
  8. +
  9. The containers' root filesystems are mounted in encrypted memory.
  10. +
+

Limitations inherent to policy checking

+

Workload policies serve as workload identities. +From the perspective of the Contrast Coordinator, all workloads that authenticate with the same policy are equal. +Thus, it's not possible to disambiguate, for example, pods spawned from a deployment or to limit the amount of certificates issued per policy.

+

Container image references from Kubernetes resource definitions are taken into account when generating the policy. +A mutable reference may lead to policy failures or unverified image content, depending on the Contrast runtime. +Reliability and security can only be ensured with a full image reference, including digest. +The docker pull documentation explains pinned image references in detail.

+

Policies can only verify what can be inferred at generation time. +Some attributes of Kubernetes pods can't be predicted and thus can't be verified. +Particularly the downward API contains many fields that are dynamic or depend on the host environment, rendering it unsafe for process environment or arguments. +The same goes for ConfigMap and Secret resources, which can also be used to populate container fields. +If the application requires such external information, it should be injected as a mount point and carefully inspected before use.

+

Another type of dynamic content are persistent volumes. +Any volumes mounted to the pod need to be scrutinized, and sensitive data must not be written to unprotected volumes. +Ideally, a volume is mounted as a raw block device and authenticated encryption is added within the confidential container.

+

Logs

+

By default, container logs are visible to the host. +Sensitive information shouldn't be logged.

+

As of right now, hiding logs isn't natively supported. +If ReadStreamRequest is denied in the policy, the Kata Agent stops reading the logs. +This causes the pipes used for standard out and standard error to fill up and potentially deadlock the container. +If absolutely required, standard out and standard error should be manually redirected to /dev/null inside the container.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/assets/css/styles.b5828750.css b/pr-preview/pr-976/assets/css/styles.b5828750.css new file mode 100644 index 0000000000..c1e722a831 --- /dev/null +++ b/pr-preview/pr-976/assets/css/styles.b5828750.css @@ -0,0 +1 @@ +@import url(https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap);.col,.container{padding:0 var(--ifm-spacing-horizontal);width:100%}.markdown>h2,.markdown>h3,.markdown>h4,.markdown>h5,.markdown>h6{margin-bottom:calc(var(--ifm-heading-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown li,body{word-wrap:break-word}body,ol ol,ol ul,ul ol,ul ul{margin:0}pre,table{overflow:auto}blockquote,pre{margin:0 0 var(--ifm-spacing-vertical)}.breadcrumbs__link,.button{transition-timing-function:var(--ifm-transition-timing-default)}.button,code{vertical-align:middle}.button--outline.button--active,.button--outline:active,.button--outline:hover,:root{--ifm-button-color:var(--ifm-font-color-base-inverse)}.menu__link:hover,a{transition:color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.navbar--dark,:root{--ifm-navbar-link-hover-color:var(--ifm-color-primary)}.menu,.navbar-sidebar{overflow-x:hidden}:root,html[data-theme=dark]{--ifm-color-emphasis-500:var(--ifm-color-gray-500)}.toggleButton_gllP,html{-webkit-tap-highlight-color:transparent}:root,body.dark,body[data-theme=dark]{--aa-icon-color-rgb:119,119,163;--aa-scrollbar-thumb-background-color-rgb:var(--aa-background-color-rgb)}.aa-List,.clean-list,.containsTaskList_mC6p,.details_lb9f>summary,.dropdown__menu,.menu__list{list-style:none}:root{--ifm-color-scheme:light;--ifm-dark-value:10%;--ifm-darker-value:15%;--ifm-darkest-value:30%;--ifm-light-value:15%;--ifm-lighter-value:30%;--ifm-lightest-value:50%;--ifm-contrast-background-value:90%;--ifm-contrast-foreground-value:70%;--ifm-contrast-background-dark-value:70%;--ifm-contrast-foreground-dark-value:90%;--ifm-color-primary:#3578e5;--ifm-color-secondary:#ebedf0;--ifm-color-success:#00a400;--ifm-color-info:#54c7ec;--ifm-color-warning:#ffba00;--ifm-color-danger:#fa383e;--ifm-color-primary-dark:#306cce;--ifm-color-primary-darker:#2d66c3;--ifm-color-primary-darkest:#2554a0;--ifm-color-primary-light:#538ce9;--ifm-color-primary-lighter:#72a1ed;--ifm-color-primary-lightest:#9abcf2;--ifm-color-primary-contrast-background:#ebf2fc;--ifm-color-primary-contrast-foreground:#102445;--ifm-color-secondary-dark:#d4d5d8;--ifm-color-secondary-darker:#c8c9cc;--ifm-color-secondary-darkest:#a4a6a8;--ifm-color-secondary-light:#eef0f2;--ifm-color-secondary-lighter:#f1f2f5;--ifm-color-secondary-lightest:#f5f6f8;--ifm-color-secondary-contrast-background:#fdfdfe;--ifm-color-secondary-contrast-foreground:#474748;--ifm-color-success-dark:#009400;--ifm-color-success-darker:#008b00;--ifm-color-success-darkest:#007300;--ifm-color-success-light:#26b226;--ifm-color-success-lighter:#4dbf4d;--ifm-color-success-lightest:#80d280;--ifm-color-success-contrast-background:#e6f6e6;--ifm-color-success-contrast-foreground:#003100;--ifm-color-info-dark:#4cb3d4;--ifm-color-info-darker:#47a9c9;--ifm-color-info-darkest:#3b8ba5;--ifm-color-info-light:#6ecfef;--ifm-color-info-lighter:#87d8f2;--ifm-color-info-lightest:#aae3f6;--ifm-color-info-contrast-background:#eef9fd;--ifm-color-info-contrast-foreground:#193c47;--ifm-color-warning-dark:#e6a700;--ifm-color-warning-darker:#d99e00;--ifm-color-warning-darkest:#b38200;--ifm-color-warning-light:#ffc426;--ifm-color-warning-lighter:#ffcf4d;--ifm-color-warning-lightest:#ffdd80;--ifm-color-warning-contrast-background:#fff8e6;--ifm-color-warning-contrast-foreground:#4d3800;--ifm-color-danger-dark:#e13238;--ifm-color-danger-darker:#d53035;--ifm-color-danger-darkest:#af272b;--ifm-color-danger-light:#fb565b;--ifm-color-danger-lighter:#fb7478;--ifm-color-danger-lightest:#fd9c9f;--ifm-color-danger-contrast-background:#ffebec;--ifm-color-danger-contrast-foreground:#4b1113;--ifm-color-white:#fff;--ifm-color-black:#000;--ifm-color-gray-0:var(--ifm-color-white);--ifm-color-gray-100:#f5f6f7;--ifm-color-gray-200:#ebedf0;--ifm-color-gray-300:#dadde1;--ifm-color-gray-400:#ccd0d5;--ifm-color-gray-500:#bec3c9;--ifm-color-gray-600:#8d949e;--ifm-color-gray-700:#606770;--ifm-color-gray-800:#444950;--ifm-color-gray-900:#1c1e21;--ifm-color-gray-1000:var(--ifm-color-black);--ifm-color-emphasis-0:var(--ifm-color-gray-0);--ifm-color-emphasis-100:var(--ifm-color-gray-100);--ifm-color-emphasis-200:var(--ifm-color-gray-200);--ifm-color-emphasis-300:var(--ifm-color-gray-300);--ifm-color-emphasis-400:var(--ifm-color-gray-400);--ifm-color-emphasis-600:var(--ifm-color-gray-600);--ifm-color-emphasis-700:var(--ifm-color-gray-700);--ifm-color-emphasis-800:var(--ifm-color-gray-800);--ifm-color-emphasis-900:var(--ifm-color-gray-900);--ifm-color-emphasis-1000:var(--ifm-color-gray-1000);--ifm-color-content:var(--ifm-color-emphasis-900);--ifm-color-content-inverse:var(--ifm-color-emphasis-0);--ifm-color-content-secondary:#525860;--ifm-background-color:#0000;--ifm-background-surface-color:var(--ifm-color-content-inverse);--ifm-global-border-width:1px;--ifm-global-radius:0.4rem;--ifm-hover-overlay:#0000000d;--ifm-font-color-base:var(--ifm-color-content);--ifm-font-color-base-inverse:var(--ifm-color-content-inverse);--ifm-font-color-secondary:var(--ifm-color-content-secondary);--ifm-font-family-base:system-ui,-apple-system,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--ifm-font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--ifm-font-size-base:100%;--ifm-font-weight-light:300;--ifm-font-weight-normal:400;--ifm-font-weight-semibold:500;--ifm-font-weight-bold:700;--ifm-font-weight-base:var(--ifm-font-weight-normal);--ifm-line-height-base:1.65;--ifm-global-spacing:1rem;--ifm-spacing-vertical:var(--ifm-global-spacing);--ifm-spacing-horizontal:var(--ifm-global-spacing);--ifm-transition-fast:200ms;--ifm-transition-slow:400ms;--ifm-transition-timing-default:cubic-bezier(0.08,0.52,0.52,1);--ifm-global-shadow-lw:0 1px 2px 0 #0000001a;--ifm-global-shadow-md:0 5px 40px #0003;--ifm-global-shadow-tl:0 12px 28px 0 #0003,0 2px 4px 0 #0000001a;--ifm-z-index-dropdown:100;--ifm-z-index-fixed:200;--ifm-z-index-overlay:400;--ifm-container-width:1140px;--ifm-container-width-xl:1320px;--ifm-code-background:#f6f7f8;--ifm-code-border-radius:var(--ifm-global-radius);--ifm-code-font-size:90%;--ifm-code-padding-horizontal:0.1rem;--ifm-code-padding-vertical:0.1rem;--ifm-pre-background:var(--ifm-code-background);--ifm-pre-border-radius:var(--ifm-code-border-radius);--ifm-pre-color:inherit;--ifm-pre-line-height:1.45;--ifm-pre-padding:1rem;--ifm-heading-color:inherit;--ifm-heading-margin-top:0;--ifm-heading-margin-bottom:var(--ifm-spacing-vertical);--ifm-heading-font-family:var(--ifm-font-family-base);--ifm-heading-font-weight:var(--ifm-font-weight-bold);--ifm-heading-line-height:1.25;--ifm-h1-font-size:2rem;--ifm-h2-font-size:1.5rem;--ifm-h3-font-size:1.25rem;--ifm-h4-font-size:1rem;--ifm-h5-font-size:0.875rem;--ifm-h6-font-size:0.85rem;--ifm-image-alignment-padding:1.25rem;--ifm-leading-desktop:1.25;--ifm-leading:calc(var(--ifm-leading-desktop)*1rem);--ifm-list-left-padding:2rem;--ifm-list-margin:1rem;--ifm-list-item-margin:0.25rem;--ifm-list-paragraph-margin:1rem;--ifm-table-cell-padding:0.75rem;--ifm-table-background:#0000;--ifm-table-stripe-background:#00000008;--ifm-table-border-width:1px;--ifm-table-border-color:var(--ifm-color-emphasis-300);--ifm-table-head-background:inherit;--ifm-table-head-color:inherit;--ifm-table-head-font-weight:var(--ifm-font-weight-bold);--ifm-table-cell-color:inherit;--ifm-link-color:var(--ifm-color-primary);--ifm-link-decoration:none;--ifm-link-hover-color:var(--ifm-link-color);--ifm-link-hover-decoration:underline;--ifm-paragraph-margin-bottom:var(--ifm-leading);--ifm-blockquote-font-size:var(--ifm-font-size-base);--ifm-blockquote-border-left-width:2px;--ifm-blockquote-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-blockquote-padding-vertical:0;--ifm-blockquote-shadow:none;--ifm-blockquote-color:var(--ifm-color-emphasis-800);--ifm-blockquote-border-color:var(--ifm-color-emphasis-300);--ifm-hr-background-color:var(--ifm-color-emphasis-500);--ifm-hr-height:1px;--ifm-hr-margin-vertical:1.5rem;--ifm-scrollbar-size:7px;--ifm-scrollbar-track-background-color:#f1f1f1;--ifm-scrollbar-thumb-background-color:silver;--ifm-scrollbar-thumb-hover-background-color:#a7a7a7;--ifm-alert-background-color:inherit;--ifm-alert-border-color:inherit;--ifm-alert-border-radius:var(--ifm-global-radius);--ifm-alert-border-width:0px;--ifm-alert-border-left-width:5px;--ifm-alert-color:var(--ifm-font-color-base);--ifm-alert-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-alert-padding-vertical:var(--ifm-spacing-vertical);--ifm-alert-shadow:var(--ifm-global-shadow-lw);--ifm-avatar-intro-margin:1rem;--ifm-avatar-intro-alignment:inherit;--ifm-avatar-photo-size:3rem;--ifm-badge-background-color:inherit;--ifm-badge-border-color:inherit;--ifm-badge-border-radius:var(--ifm-global-radius);--ifm-badge-border-width:var(--ifm-global-border-width);--ifm-badge-color:var(--ifm-color-white);--ifm-badge-padding-horizontal:calc(var(--ifm-spacing-horizontal)*0.5);--ifm-badge-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-breadcrumb-border-radius:1.5rem;--ifm-breadcrumb-spacing:0.5rem;--ifm-breadcrumb-color-active:var(--ifm-color-primary);--ifm-breadcrumb-item-background-active:var(--ifm-hover-overlay);--ifm-breadcrumb-padding-horizontal:0.8rem;--ifm-breadcrumb-padding-vertical:0.4rem;--ifm-breadcrumb-size-multiplier:1;--ifm-breadcrumb-separator:url('data:image/svg+xml;utf8,');--ifm-breadcrumb-separator-filter:none;--ifm-breadcrumb-separator-size:0.5rem;--ifm-breadcrumb-separator-size-multiplier:1.25;--ifm-button-background-color:inherit;--ifm-button-border-color:var(--ifm-button-background-color);--ifm-button-border-width:var(--ifm-global-border-width);--ifm-button-font-weight:var(--ifm-font-weight-bold);--ifm-button-padding-horizontal:1.5rem;--ifm-button-padding-vertical:0.375rem;--ifm-button-size-multiplier:1;--ifm-button-transition-duration:var(--ifm-transition-fast);--ifm-button-border-radius:calc(var(--ifm-global-radius)*var(--ifm-button-size-multiplier));--ifm-button-group-spacing:2px;--ifm-card-background-color:var(--ifm-background-surface-color);--ifm-card-border-radius:calc(var(--ifm-global-radius)*2);--ifm-card-horizontal-spacing:var(--ifm-global-spacing);--ifm-card-vertical-spacing:var(--ifm-global-spacing);--ifm-toc-border-color:var(--ifm-color-emphasis-300);--ifm-toc-link-color:var(--ifm-color-content-secondary);--ifm-toc-padding-vertical:0.5rem;--ifm-toc-padding-horizontal:0.5rem;--ifm-dropdown-background-color:var(--ifm-background-surface-color);--ifm-dropdown-font-weight:var(--ifm-font-weight-semibold);--ifm-dropdown-link-color:var(--ifm-font-color-base);--ifm-dropdown-hover-background-color:var(--ifm-hover-overlay);--ifm-footer-background-color:var(--ifm-color-emphasis-100);--ifm-footer-color:inherit;--ifm-footer-link-color:var(--ifm-color-emphasis-700);--ifm-footer-link-hover-color:var(--ifm-color-primary);--ifm-footer-link-horizontal-spacing:0.5rem;--ifm-footer-padding-horizontal:calc(var(--ifm-spacing-horizontal)*2);--ifm-footer-padding-vertical:calc(var(--ifm-spacing-vertical)*2);--ifm-footer-title-color:inherit;--ifm-footer-logo-max-width:min(30rem,90vw);--ifm-hero-background-color:var(--ifm-background-surface-color);--ifm-hero-text-color:var(--ifm-color-emphasis-800);--ifm-menu-color:var(--ifm-color-emphasis-700);--ifm-menu-color-active:var(--ifm-color-primary);--ifm-menu-color-background-active:var(--ifm-hover-overlay);--ifm-menu-color-background-hover:var(--ifm-hover-overlay);--ifm-menu-link-padding-horizontal:0.75rem;--ifm-menu-link-padding-vertical:0.375rem;--ifm-menu-link-sublist-icon:url('data:image/svg+xml;utf8,');--ifm-menu-link-sublist-icon-filter:none;--ifm-navbar-background-color:var(--ifm-background-surface-color);--ifm-navbar-height:3.75rem;--ifm-navbar-item-padding-horizontal:0.75rem;--ifm-navbar-item-padding-vertical:0.25rem;--ifm-navbar-link-color:var(--ifm-font-color-base);--ifm-navbar-link-active-color:var(--ifm-link-color);--ifm-navbar-padding-horizontal:var(--ifm-spacing-horizontal);--ifm-navbar-padding-vertical:calc(var(--ifm-spacing-vertical)*0.5);--ifm-navbar-shadow:var(--ifm-global-shadow-lw);--ifm-navbar-search-input-background-color:var(--ifm-color-emphasis-200);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-800);--ifm-navbar-search-input-placeholder-color:var(--ifm-color-emphasis-500);--ifm-navbar-search-input-icon:url('data:image/svg+xml;utf8,');--ifm-navbar-sidebar-width:83vw;--ifm-pagination-border-radius:var(--ifm-global-radius);--ifm-pagination-color-active:var(--ifm-color-primary);--ifm-pagination-font-size:1rem;--ifm-pagination-item-active-background:var(--ifm-hover-overlay);--ifm-pagination-page-spacing:0.2em;--ifm-pagination-padding-horizontal:calc(var(--ifm-spacing-horizontal)*1);--ifm-pagination-padding-vertical:calc(var(--ifm-spacing-vertical)*0.25);--ifm-pagination-nav-border-radius:var(--ifm-global-radius);--ifm-pagination-nav-color-hover:var(--ifm-color-primary);--ifm-pills-color-active:var(--ifm-color-primary);--ifm-pills-color-background-active:var(--ifm-hover-overlay);--ifm-pills-spacing:0.125rem;--ifm-tabs-color:var(--ifm-font-color-secondary);--ifm-tabs-color-active:var(--ifm-color-primary);--ifm-tabs-color-active-border:var(--ifm-tabs-color-active);--ifm-tabs-padding-horizontal:1rem;--ifm-tabs-padding-vertical:1rem;--docusaurus-progress-bar-color:var(--ifm-color-primary);--ifm-color-primary:#8b04dd;--ifm-color-primary-dark:#58089e;--ifm-color-primary-darker:#330663;--ifm-color-primary-darkest:#1c033c;--ifm-color-primary-light:#8b04dd;--ifm-color-primary-lighter:#b873f4;--ifm-color-primary-lightest:#e3d2ff;--ifm-font-family-base:"Inter",sans-serif;--ifm-code-font-size:95%;--docusaurus-highlighted-code-line-bg:#0000001a;--docusaurus-tag-list-border:var(--ifm-color-emphasis-300);--docusaurus-collapse-button-bg:#0000;--docusaurus-collapse-button-bg-hover:#0000001a;--doc-sidebar-width:300px;--doc-sidebar-hidden-width:30px;--docusaurus-announcement-bar-height:auto;--aa-search-input-height:44px;--aa-input-icon-size:20px;--aa-base-unit:16;--aa-spacing-factor:1;--aa-spacing:calc(var(--aa-base-unit)*var(--aa-spacing-factor)*1px);--aa-spacing-half:calc(var(--aa-spacing)/2);--aa-panel-max-height:650px;--aa-base-z-index:9999;--aa-font-size:calc(var(--aa-base-unit)*1px);--aa-font-family:inherit;--aa-font-weight-medium:500;--aa-font-weight-semibold:600;--aa-font-weight-bold:700;--aa-icon-size:20px;--aa-icon-stroke-width:1.6;--aa-icon-color-alpha:1;--aa-action-icon-size:20px;--aa-text-color-rgb:38,38,39;--aa-text-color-alpha:1;--aa-primary-color-rgb:62,52,211;--aa-primary-color-alpha:0.2;--aa-muted-color-rgb:128,126,163;--aa-muted-color-alpha:0.6;--aa-panel-border-color-rgb:128,126,163;--aa-panel-border-color-alpha:0.3;--aa-input-border-color-rgb:128,126,163;--aa-input-border-color-alpha:0.8;--aa-background-color-rgb:255,255,255;--aa-background-color-alpha:1;--aa-input-background-color-rgb:255,255,255;--aa-input-background-color-alpha:1;--aa-selected-color-rgb:179,173,214;--aa-selected-color-alpha:0.205;--aa-description-highlight-background-color-rgb:245,223,77;--aa-description-highlight-background-color-alpha:0.5;--aa-detached-media-query:(max-width:680px);--aa-detached-modal-media-query:(min-width:680px);--aa-detached-modal-max-width:680px;--aa-detached-modal-max-height:500px;--aa-overlay-color-rgb:115,114,129;--aa-overlay-color-alpha:0.4;--aa-panel-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;--aa-scrollbar-width:13px;--aa-scrollbar-track-background-color-rgb:234,234,234;--aa-scrollbar-track-background-color-alpha:1;--aa-scrollbar-thumb-background-color-alpha:1;--aa-search-input-height:36px}.badge--danger,.badge--info,.badge--primary,.badge--secondary,.badge--success,.badge--warning{--ifm-badge-border-color:var(--ifm-badge-background-color)}.button--link,.button--outline{--ifm-button-background-color:#0000}*,.aa-Autocomplete *,.aa-DetachedFormContainer *,.aa-Panel *{box-sizing:border-box}html{background-color:var(--ifm-background-color);color:var(--ifm-font-color-base);color-scheme:var(--ifm-color-scheme);font:var(--ifm-font-size-base)/var(--ifm-line-height-base) var(--ifm-font-family-base);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;-webkit-text-size-adjust:100%;text-size-adjust:100%}iframe{border:0;color-scheme:auto}.container{margin:0 auto;max-width:var(--ifm-container-width)}.container--fluid{max-width:inherit}.row{display:flex;flex-wrap:wrap;margin:0 calc(var(--ifm-spacing-horizontal)*-1)}.list_eTzJ article:last-child,.margin-bottom--none,.margin-vert--none,.markdown>:last-child{margin-bottom:0!important}.margin-top--none,.margin-vert--none,.tabItem_LNqP{margin-top:0!important}.row--no-gutters{margin-left:0;margin-right:0}.margin-horiz--none,.margin-right--none{margin-right:0!important}.row--no-gutters>.col{padding-left:0;padding-right:0}.row--align-top{align-items:flex-start}.row--align-bottom{align-items:flex-end}.menuExternalLink_NmtK,.row--align-center{align-items:center}.row--align-stretch{align-items:stretch}.row--align-baseline{align-items:baseline}.col{--ifm-col-width:100%;flex:1 0;margin-left:0;max-width:var(--ifm-col-width)}.padding-bottom--none,.padding-vert--none{padding-bottom:0!important}.padding-top--none,.padding-vert--none{padding-top:0!important}.padding-horiz--none,.padding-left--none{padding-left:0!important}.padding-horiz--none,.padding-right--none{padding-right:0!important}.col[class*=col--]{flex:0 0 var(--ifm-col-width)}.col--1{--ifm-col-width:8.33333%}.col--offset-1{margin-left:8.33333%}.col--2{--ifm-col-width:16.66667%}.col--offset-2{margin-left:16.66667%}.col--3{--ifm-col-width:25%}.col--offset-3{margin-left:25%}.col--4{--ifm-col-width:33.33333%}.col--offset-4{margin-left:33.33333%}.col--5{--ifm-col-width:41.66667%}.col--offset-5{margin-left:41.66667%}.col--6{--ifm-col-width:50%}.col--offset-6{margin-left:50%}.col--7{--ifm-col-width:58.33333%}.col--offset-7{margin-left:58.33333%}.col--8{--ifm-col-width:66.66667%}.col--offset-8{margin-left:66.66667%}.col--9{--ifm-col-width:75%}.col--offset-9{margin-left:75%}.col--10{--ifm-col-width:83.33333%}.col--offset-10{margin-left:83.33333%}.col--11{--ifm-col-width:91.66667%}.col--offset-11{margin-left:91.66667%}.col--12{--ifm-col-width:100%}.col--offset-12{margin-left:100%}.margin-horiz--none,.margin-left--none{margin-left:0!important}.margin--none{margin:0!important}.margin-bottom--xs,.margin-vert--xs{margin-bottom:.25rem!important}.margin-top--xs,.margin-vert--xs{margin-top:.25rem!important}.margin-horiz--xs,.margin-left--xs{margin-left:.25rem!important}.margin-horiz--xs,.margin-right--xs{margin-right:.25rem!important}.margin--xs{margin:.25rem!important}.margin-bottom--sm,.margin-vert--sm{margin-bottom:.5rem!important}.margin-top--sm,.margin-vert--sm{margin-top:.5rem!important}.margin-horiz--sm,.margin-left--sm{margin-left:.5rem!important}.margin-horiz--sm,.margin-right--sm{margin-right:.5rem!important}.margin--sm{margin:.5rem!important}.margin-bottom--md,.margin-vert--md{margin-bottom:1rem!important}.margin-top--md,.margin-vert--md{margin-top:1rem!important}.margin-horiz--md,.margin-left--md{margin-left:1rem!important}.margin-horiz--md,.margin-right--md{margin-right:1rem!important}.margin--md{margin:1rem!important}.margin-bottom--lg,.margin-vert--lg{margin-bottom:2rem!important}.margin-top--lg,.margin-vert--lg{margin-top:2rem!important}.margin-horiz--lg,.margin-left--lg{margin-left:2rem!important}.margin-horiz--lg,.margin-right--lg{margin-right:2rem!important}.margin--lg{margin:2rem!important}.margin-bottom--xl,.margin-vert--xl{margin-bottom:5rem!important}.margin-top--xl,.margin-vert--xl{margin-top:5rem!important}.margin-horiz--xl,.margin-left--xl{margin-left:5rem!important}.margin-horiz--xl,.margin-right--xl{margin-right:5rem!important}.margin--xl{margin:5rem!important}.padding--none{padding:0!important}.padding-bottom--xs,.padding-vert--xs{padding-bottom:.25rem!important}.padding-top--xs,.padding-vert--xs{padding-top:.25rem!important}.padding-horiz--xs,.padding-left--xs{padding-left:.25rem!important}.padding-horiz--xs,.padding-right--xs{padding-right:.25rem!important}.padding--xs{padding:.25rem!important}.padding-bottom--sm,.padding-vert--sm{padding-bottom:.5rem!important}.padding-top--sm,.padding-vert--sm{padding-top:.5rem!important}.padding-horiz--sm,.padding-left--sm{padding-left:.5rem!important}.padding-horiz--sm,.padding-right--sm{padding-right:.5rem!important}.padding--sm{padding:.5rem!important}.padding-bottom--md,.padding-vert--md{padding-bottom:1rem!important}.padding-top--md,.padding-vert--md{padding-top:1rem!important}.padding-horiz--md,.padding-left--md{padding-left:1rem!important}.padding-horiz--md,.padding-right--md{padding-right:1rem!important}.padding--md{padding:1rem!important}.padding-bottom--lg,.padding-vert--lg{padding-bottom:2rem!important}.padding-top--lg,.padding-vert--lg{padding-top:2rem!important}.padding-horiz--lg,.padding-left--lg{padding-left:2rem!important}.padding-horiz--lg,.padding-right--lg{padding-right:2rem!important}.padding--lg{padding:2rem!important}.padding-bottom--xl,.padding-vert--xl{padding-bottom:5rem!important}.padding-top--xl,.padding-vert--xl{padding-top:5rem!important}.padding-horiz--xl,.padding-left--xl{padding-left:5rem!important}.padding-horiz--xl,.padding-right--xl{padding-right:5rem!important}.padding--xl{padding:5rem!important}code{background-color:var(--ifm-code-background);border:.1rem solid #0000001a;border-radius:var(--ifm-code-border-radius);font-family:var(--ifm-font-family-monospace);font-size:var(--ifm-code-font-size);padding:var(--ifm-code-padding-vertical) var(--ifm-code-padding-horizontal)}a code{color:inherit}pre{background-color:var(--ifm-pre-background);border-radius:var(--ifm-pre-border-radius);color:var(--ifm-pre-color);font:var(--ifm-code-font-size)/var(--ifm-pre-line-height) var(--ifm-font-family-monospace);padding:var(--ifm-pre-padding)}pre code{background-color:initial;border:none;font-size:100%;line-height:inherit;padding:0}kbd{background-color:var(--ifm-color-emphasis-0);border:1px solid var(--ifm-color-emphasis-400);border-radius:.2rem;box-shadow:inset 0 -1px 0 var(--ifm-color-emphasis-400);color:var(--ifm-color-emphasis-800);font:80% var(--ifm-font-family-monospace);padding:.15rem .3rem}h1,h2,h3,h4,h5,h6{color:var(--ifm-heading-color);font-family:var(--ifm-heading-font-family);font-weight:var(--ifm-heading-font-weight);line-height:var(--ifm-heading-line-height);margin:var(--ifm-heading-margin-top) 0 var(--ifm-heading-margin-bottom) 0}h1{font-size:var(--ifm-h1-font-size)}h2{font-size:var(--ifm-h2-font-size)}h3{font-size:var(--ifm-h3-font-size)}h4{font-size:var(--ifm-h4-font-size)}h5{font-size:var(--ifm-h5-font-size)}h6{font-size:var(--ifm-h6-font-size)}.container_lyt7,.container_lyt7>svg,img{max-width:100%}img[align=right]{padding-left:var(--image-alignment-padding)}img[align=left]{padding-right:var(--image-alignment-padding)}.markdown{--ifm-h1-vertical-rhythm-top:3;--ifm-h2-vertical-rhythm-top:2;--ifm-h3-vertical-rhythm-top:1.5;--ifm-heading-vertical-rhythm-top:1.25;--ifm-h1-vertical-rhythm-bottom:1.25;--ifm-heading-vertical-rhythm-bottom:1}.markdown:after,.markdown:before{content:"";display:table}.markdown:after{clear:both}.markdown h1:first-child{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-h1-vertical-rhythm-bottom)*var(--ifm-leading))}.markdown>h2{--ifm-h2-font-size:2rem;margin-top:calc(var(--ifm-h2-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h3{--ifm-h3-font-size:1.5rem;margin-top:calc(var(--ifm-h3-vertical-rhythm-top)*var(--ifm-leading))}.markdown>h4,.markdown>h5,.markdown>h6{margin-top:calc(var(--ifm-heading-vertical-rhythm-top)*var(--ifm-leading))}.markdown>p,.markdown>pre,.markdown>ul,.tabList__CuJ{margin-bottom:var(--ifm-leading)}.markdown li>p{margin-top:var(--ifm-list-paragraph-margin)}.markdown li+li{margin-top:var(--ifm-list-item-margin)}ol,ul{margin:0 0 var(--ifm-list-margin);padding-left:var(--ifm-list-left-padding)}ol ol,ul ol{list-style-type:lower-roman}ol ol ol,ol ul ol,ul ol ol,ul ul ol{list-style-type:lower-alpha}table{border-collapse:collapse;display:block;margin-bottom:var(--ifm-spacing-vertical)}table thead tr{border-bottom:2px solid var(--ifm-table-border-color)}table thead,table tr:nth-child(2n){background-color:var(--ifm-table-stripe-background)}table tr{background-color:var(--ifm-table-background);border-top:var(--ifm-table-border-width) solid var(--ifm-table-border-color)}table td,table th{border:var(--ifm-table-border-width) solid var(--ifm-table-border-color);padding:var(--ifm-table-cell-padding)}table th{background-color:var(--ifm-table-head-background);color:var(--ifm-table-head-color);font-weight:var(--ifm-table-head-font-weight)}table td{color:var(--ifm-table-cell-color)}strong{font-weight:var(--ifm-font-weight-bold)}a{color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}a:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button:hover,.text--no-decoration,.text--no-decoration:hover,a:not([href]){text-decoration:none}p{margin:0 0 var(--ifm-paragraph-margin-bottom)}blockquote{border-left:var(--ifm-blockquote-border-left-width) solid var(--ifm-blockquote-border-color);box-shadow:var(--ifm-blockquote-shadow);color:var(--ifm-blockquote-color);font-size:var(--ifm-blockquote-font-size);padding:var(--ifm-blockquote-padding-vertical) var(--ifm-blockquote-padding-horizontal)}.docItemContainer_Djhp article>:first-child,.docItemContainer_Djhp header+*,.footer__item,blockquote>:first-child{margin-top:0}blockquote>:last-child{margin-bottom:0}hr{background-color:var(--ifm-hr-background-color);border:0;height:var(--ifm-hr-height);margin:var(--ifm-hr-margin-vertical) 0}.shadow--lw{box-shadow:var(--ifm-global-shadow-lw)!important}.shadow--md{box-shadow:var(--ifm-global-shadow-md)!important}.shadow--tl{box-shadow:var(--ifm-global-shadow-tl)!important}.text--primary,.wordWrapButtonEnabled_EoeP .wordWrapButtonIcon_Bwma{color:var(--ifm-color-primary)}.text--secondary{color:var(--ifm-color-secondary)}.text--success{color:var(--ifm-color-success)}.text--info{color:var(--ifm-color-info)}.text--warning{color:var(--ifm-color-warning)}.text--danger{color:var(--ifm-color-danger)}.text--center{text-align:center}.text--left{text-align:left}.text--justify{text-align:justify}.text--right{text-align:right}.text--capitalize{text-transform:capitalize}.text--lowercase{text-transform:lowercase}.admonitionHeading_Gvgb,.alert__heading,.text--uppercase{text-transform:uppercase}.text--light{font-weight:var(--ifm-font-weight-light)}.text--normal{font-weight:var(--ifm-font-weight-normal)}.text--semibold{font-weight:var(--ifm-font-weight-semibold)}.text--bold{font-weight:var(--ifm-font-weight-bold)}.text--italic{font-style:italic}.text--truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text--break{word-wrap:break-word!important;word-break:break-word!important}.clean-btn{background:none;border:none;color:inherit;cursor:pointer;font-family:inherit;padding:0}.alert,.alert .close{color:var(--ifm-alert-foreground-color)}.clean-list{padding-left:0}.alert--primary{--ifm-alert-background-color:var(--ifm-color-primary-contrast-background);--ifm-alert-background-color-highlight:#3578e526;--ifm-alert-foreground-color:var(--ifm-color-primary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-primary-dark)}.alert--secondary{--ifm-alert-background-color:var(--ifm-color-secondary-contrast-background);--ifm-alert-background-color-highlight:#ebedf026;--ifm-alert-foreground-color:var(--ifm-color-secondary-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-secondary-dark)}.alert--success{--ifm-alert-background-color:var(--ifm-color-success-contrast-background);--ifm-alert-background-color-highlight:#00a40026;--ifm-alert-foreground-color:var(--ifm-color-success-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-success-dark)}.alert--info{--ifm-alert-background-color:var(--ifm-color-info-contrast-background);--ifm-alert-background-color-highlight:#54c7ec26;--ifm-alert-foreground-color:var(--ifm-color-info-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-info-dark)}.alert--warning{--ifm-alert-background-color:var(--ifm-color-warning-contrast-background);--ifm-alert-background-color-highlight:#ffba0026;--ifm-alert-foreground-color:var(--ifm-color-warning-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-warning-dark)}.alert--danger{--ifm-alert-background-color:var(--ifm-color-danger-contrast-background);--ifm-alert-background-color-highlight:#fa383e26;--ifm-alert-foreground-color:var(--ifm-color-danger-contrast-foreground);--ifm-alert-border-color:var(--ifm-color-danger-dark)}.alert{--ifm-code-background:var(--ifm-alert-background-color-highlight);--ifm-link-color:var(--ifm-alert-foreground-color);--ifm-link-hover-color:var(--ifm-alert-foreground-color);--ifm-link-decoration:underline;--ifm-tabs-color:var(--ifm-alert-foreground-color);--ifm-tabs-color-active:var(--ifm-alert-foreground-color);--ifm-tabs-color-active-border:var(--ifm-alert-border-color);background-color:var(--ifm-alert-background-color);border:var(--ifm-alert-border-width) solid var(--ifm-alert-border-color);border-left-width:var(--ifm-alert-border-left-width);border-radius:var(--ifm-alert-border-radius);box-shadow:var(--ifm-alert-shadow);padding:var(--ifm-alert-padding-vertical) var(--ifm-alert-padding-horizontal)}.alert__heading{align-items:center;display:flex;font:700 var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family);margin-bottom:.5rem}.alert__icon{display:inline-flex;margin-right:.4em}.alert__icon svg{fill:var(--ifm-alert-foreground-color);stroke:var(--ifm-alert-foreground-color);stroke-width:0}.alert .close{margin:calc(var(--ifm-alert-padding-vertical)*-1) calc(var(--ifm-alert-padding-horizontal)*-1) 0 0;opacity:.75}.alert .close:focus,.alert .close:hover{opacity:1}.alert a{text-decoration-color:var(--ifm-alert-border-color)}.alert a:hover{text-decoration-thickness:2px}.avatar{column-gap:var(--ifm-avatar-intro-margin);display:flex}.avatar__photo{border-radius:50%;display:block;height:var(--ifm-avatar-photo-size);overflow:hidden;width:var(--ifm-avatar-photo-size)}.card--full-height,.navbar__logo img,body,html{height:100%}.avatar__photo--sm{--ifm-avatar-photo-size:2rem}.avatar__photo--lg{--ifm-avatar-photo-size:4rem}.avatar__photo--xl{--ifm-avatar-photo-size:6rem}.avatar__intro{display:flex;flex:1 1;flex-direction:column;justify-content:center;text-align:var(--ifm-avatar-intro-alignment)}.badge,.breadcrumbs__item,.breadcrumbs__link,.button,.dropdown>.navbar__link:after{display:inline-block}.avatar__name{font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base)}.avatar__subtitle{margin-top:.25rem}.avatar--vertical{--ifm-avatar-intro-alignment:center;--ifm-avatar-intro-margin:0.5rem;align-items:center;flex-direction:column}.badge{background-color:var(--ifm-badge-background-color);border:var(--ifm-badge-border-width) solid var(--ifm-badge-border-color);border-radius:var(--ifm-badge-border-radius);color:var(--ifm-badge-color);font-size:75%;font-weight:var(--ifm-font-weight-bold);line-height:1;padding:var(--ifm-badge-padding-vertical) var(--ifm-badge-padding-horizontal)}.badge--primary{--ifm-badge-background-color:var(--ifm-color-primary)}.badge--secondary{--ifm-badge-background-color:var(--ifm-color-secondary);color:var(--ifm-color-black)}.breadcrumbs__link,.button.button--secondary.button--outline:not(.button--active):not(:hover){color:var(--ifm-font-color-base)}.badge--success{--ifm-badge-background-color:var(--ifm-color-success)}.badge--info{--ifm-badge-background-color:var(--ifm-color-info)}.badge--warning{--ifm-badge-background-color:var(--ifm-color-warning)}.badge--danger{--ifm-badge-background-color:var(--ifm-color-danger)}.breadcrumbs{margin-bottom:0;padding-left:0}.breadcrumbs__item:not(:last-child):after{background:var(--ifm-breadcrumb-separator) center;content:" ";display:inline-block;filter:var(--ifm-breadcrumb-separator-filter);height:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier));margin:0 var(--ifm-breadcrumb-spacing);opacity:.5;width:calc(var(--ifm-breadcrumb-separator-size)*var(--ifm-breadcrumb-size-multiplier)*var(--ifm-breadcrumb-separator-size-multiplier))}.breadcrumbs__item--active .breadcrumbs__link{background:var(--ifm-breadcrumb-item-background-active);color:var(--ifm-breadcrumb-color-active)}.breadcrumbs__link{border-radius:var(--ifm-breadcrumb-border-radius);font-size:calc(1rem*var(--ifm-breadcrumb-size-multiplier));padding:calc(var(--ifm-breadcrumb-padding-vertical)*var(--ifm-breadcrumb-size-multiplier)) calc(var(--ifm-breadcrumb-padding-horizontal)*var(--ifm-breadcrumb-size-multiplier));transition-duration:var(--ifm-transition-fast);transition-property:background,color}.breadcrumbs__link:any-link:hover,.breadcrumbs__link:link:hover,.breadcrumbs__link:visited:hover,area[href].breadcrumbs__link:hover{background:var(--ifm-breadcrumb-item-background-active);text-decoration:none}.breadcrumbs--sm{--ifm-breadcrumb-size-multiplier:0.8}.breadcrumbs--lg{--ifm-breadcrumb-size-multiplier:1.2}.button{background-color:var(--ifm-button-background-color);border:var(--ifm-button-border-width) solid var(--ifm-button-border-color);border-radius:var(--ifm-button-border-radius);cursor:pointer;font-size:calc(.875rem*var(--ifm-button-size-multiplier));font-weight:var(--ifm-button-font-weight);line-height:1.5;padding:calc(var(--ifm-button-padding-vertical)*var(--ifm-button-size-multiplier)) calc(var(--ifm-button-padding-horizontal)*var(--ifm-button-size-multiplier));text-align:center;transition-duration:var(--ifm-button-transition-duration);transition-property:color,background,border-color;-webkit-user-select:none;user-select:none;white-space:nowrap}.button,.button:hover{color:var(--ifm-button-color)}.button--outline{--ifm-button-color:var(--ifm-button-border-color)}.button--outline:hover{--ifm-button-background-color:var(--ifm-button-border-color)}.button--link{--ifm-button-border-color:#0000;color:var(--ifm-link-color);text-decoration:var(--ifm-link-decoration)}.button--link.button--active,.button--link:active,.button--link:hover{color:var(--ifm-link-hover-color);text-decoration:var(--ifm-link-hover-decoration)}.button.disabled,.button:disabled,.button[disabled]{opacity:.65;pointer-events:none}.button--sm{--ifm-button-size-multiplier:0.8}.button--lg{--ifm-button-size-multiplier:1.35}.button--block{display:block;width:100%}.button.button--secondary{color:var(--ifm-color-gray-900)}:where(.button--primary){--ifm-button-background-color:var(--ifm-color-primary);--ifm-button-border-color:var(--ifm-color-primary)}:where(.button--primary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-primary-dark);--ifm-button-border-color:var(--ifm-color-primary-dark)}.button--primary.button--active,.button--primary:active{--ifm-button-background-color:var(--ifm-color-primary-darker);--ifm-button-border-color:var(--ifm-color-primary-darker)}:where(.button--secondary){--ifm-button-background-color:var(--ifm-color-secondary);--ifm-button-border-color:var(--ifm-color-secondary)}:where(.button--secondary):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-secondary-dark);--ifm-button-border-color:var(--ifm-color-secondary-dark)}.button--secondary.button--active,.button--secondary:active{--ifm-button-background-color:var(--ifm-color-secondary-darker);--ifm-button-border-color:var(--ifm-color-secondary-darker)}:where(.button--success){--ifm-button-background-color:var(--ifm-color-success);--ifm-button-border-color:var(--ifm-color-success)}:where(.button--success):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-success-dark);--ifm-button-border-color:var(--ifm-color-success-dark)}.button--success.button--active,.button--success:active{--ifm-button-background-color:var(--ifm-color-success-darker);--ifm-button-border-color:var(--ifm-color-success-darker)}:where(.button--info){--ifm-button-background-color:var(--ifm-color-info);--ifm-button-border-color:var(--ifm-color-info)}:where(.button--info):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-info-dark);--ifm-button-border-color:var(--ifm-color-info-dark)}.button--info.button--active,.button--info:active{--ifm-button-background-color:var(--ifm-color-info-darker);--ifm-button-border-color:var(--ifm-color-info-darker)}:where(.button--warning){--ifm-button-background-color:var(--ifm-color-warning);--ifm-button-border-color:var(--ifm-color-warning)}:where(.button--warning):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-warning-dark);--ifm-button-border-color:var(--ifm-color-warning-dark)}.button--warning.button--active,.button--warning:active{--ifm-button-background-color:var(--ifm-color-warning-darker);--ifm-button-border-color:var(--ifm-color-warning-darker)}:where(.button--danger){--ifm-button-background-color:var(--ifm-color-danger);--ifm-button-border-color:var(--ifm-color-danger)}:where(.button--danger):not(.button--outline):hover{--ifm-button-background-color:var(--ifm-color-danger-dark);--ifm-button-border-color:var(--ifm-color-danger-dark)}.button--danger.button--active,.button--danger:active{--ifm-button-background-color:var(--ifm-color-danger-darker);--ifm-button-border-color:var(--ifm-color-danger-darker)}.button-group{display:inline-flex;gap:var(--ifm-button-group-spacing)}.button-group>.button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.button-group>.button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.button-group--block{display:flex;justify-content:stretch}.button-group--block>.button{flex-grow:1}.card{background-color:var(--ifm-card-background-color);border-radius:var(--ifm-card-border-radius);box-shadow:var(--ifm-global-shadow-lw);display:flex;flex-direction:column;overflow:hidden}.card__image{padding-top:var(--ifm-card-vertical-spacing)}.card__image:first-child{padding-top:0}.card__body,.card__footer,.card__header{padding:var(--ifm-card-vertical-spacing) var(--ifm-card-horizontal-spacing)}.card__body:not(:last-child),.card__footer:not(:last-child),.card__header:not(:last-child){padding-bottom:0}.card__body>:last-child,.card__footer>:last-child,.card__header>:last-child{margin-bottom:0}.card__footer{margin-top:auto}.table-of-contents{font-size:.8rem;margin-bottom:0;padding:var(--ifm-toc-padding-vertical) 0}.table-of-contents,.table-of-contents ul{list-style:none;padding-left:var(--ifm-toc-padding-horizontal)}.table-of-contents li{margin:var(--ifm-toc-padding-vertical) var(--ifm-toc-padding-horizontal)}.table-of-contents__left-border{border-left:1px solid var(--ifm-toc-border-color)}.table-of-contents__link{color:var(--ifm-toc-link-color);display:block}.table-of-contents__link--active,.table-of-contents__link--active code,.table-of-contents__link:hover,.table-of-contents__link:hover code{color:var(--ifm-color-primary);text-decoration:none}.close{color:var(--ifm-color-black);float:right;font-size:1.5rem;font-weight:var(--ifm-font-weight-bold);line-height:1;opacity:.5;padding:1rem;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.close:hover{opacity:.7}.close:focus,.theme-code-block-highlighted-line .codeLineNumber_Tfdd:before{opacity:.8}.dropdown{display:inline-flex;font-weight:var(--ifm-dropdown-font-weight);position:relative;vertical-align:top}.dropdown--hoverable:hover .dropdown__menu,.dropdown--show .dropdown__menu{opacity:1;pointer-events:all;transform:translateY(-1px);visibility:visible}#nprogress,.dropdown__menu,.navbar__item.dropdown .navbar__link:not([href]){pointer-events:none}.dropdown--right .dropdown__menu{left:inherit;right:0}.dropdown--nocaret .navbar__link:after{content:none!important}.dropdown__menu{background-color:var(--ifm-dropdown-background-color);border-radius:var(--ifm-global-radius);box-shadow:var(--ifm-global-shadow-md);left:0;max-height:80vh;min-width:10rem;opacity:0;overflow-y:auto;padding:.5rem;position:absolute;top:calc(100% - var(--ifm-navbar-item-padding-vertical) + .3rem);transform:translateY(-.625rem);transition-duration:var(--ifm-transition-fast);transition-property:opacity,transform,visibility;transition-timing-function:var(--ifm-transition-timing-default);visibility:hidden;z-index:var(--ifm-z-index-dropdown)}.menu__caret,.menu__link,.menu__list-item-collapsible{border-radius:.25rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.dropdown__link{border-radius:.25rem;color:var(--ifm-dropdown-link-color);display:block;font-size:.875rem;margin-top:.2rem;padding:.25rem .5rem;white-space:nowrap}.dropdown__link--active,.dropdown__link:hover{background-color:var(--ifm-dropdown-hover-background-color);color:var(--ifm-dropdown-link-color);text-decoration:none}.dropdown__link--active,.dropdown__link--active:hover{--ifm-dropdown-link-color:var(--ifm-link-color)}.dropdown>.navbar__link:after{border-color:currentcolor #0000;border-style:solid;border-width:.4em .4em 0;content:"";margin-left:.3em;position:relative;top:2px;transform:translateY(-50%)}.footer{background-color:var(--ifm-footer-background-color);color:var(--ifm-footer-color);padding:var(--ifm-footer-padding-vertical) var(--ifm-footer-padding-horizontal)}.footer__links{margin-bottom:1rem}.footer__link-item{color:var(--ifm-footer-link-color);line-height:2}.footer__link-item:hover{color:var(--ifm-footer-link-hover-color)}.footer__link-separator{margin:0 var(--ifm-footer-link-horizontal-spacing)}.footer__logo{margin-top:1rem;max-width:var(--ifm-footer-logo-max-width)}.footer__title{color:var(--ifm-footer-title-color);font:700 var(--ifm-h4-font-size)/var(--ifm-heading-line-height) var(--ifm-font-family-base);margin-bottom:var(--ifm-heading-margin-bottom)}.menu,.navbar__link{font-weight:var(--ifm-font-weight-semibold)}.admonitionContent_BuS1>:last-child,.cardContainer_fWXF :last-child,.collapsibleContent_i85q p:last-child,.details_lb9f>summary>p:last-child,.footer__items,.tabItem_Ymn6>:last-child{margin-bottom:0}.codeBlockStandalone_MEMb,[type=checkbox]{padding:0}.hero{align-items:center;background-color:var(--ifm-hero-background-color);color:var(--ifm-hero-text-color);display:flex;padding:4rem 2rem}.hero--primary{--ifm-hero-background-color:var(--ifm-color-primary);--ifm-hero-text-color:var(--ifm-font-color-base-inverse)}.hero--dark{--ifm-hero-background-color:#303846;--ifm-hero-text-color:var(--ifm-color-white)}.hero__title{font-size:3rem}.hero__subtitle{font-size:1.5rem}.menu__list{margin:0;padding-left:0}.menu__caret,.menu__link{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu__list .menu__list{flex:0 0 100%;margin-top:.25rem;padding-left:var(--ifm-menu-link-padding-horizontal)}.menu__list-item:not(:first-child){margin-top:.25rem}.menu__list-item--collapsed .menu__list{height:0;overflow:hidden}.details_lb9f[data-collapsed=false].isBrowser_bmU9>summary:before,.details_lb9f[open]:not(.isBrowser_bmU9)>summary:before,.menu__list-item--collapsed .menu__caret:before,.menu__list-item--collapsed .menu__link--sublist:after{transform:rotate(90deg)}.menu__list-item-collapsible{display:flex;flex-wrap:wrap;position:relative}.menu__caret:hover,.menu__link:hover,.menu__list-item-collapsible--active,.menu__list-item-collapsible:hover{background:var(--ifm-menu-color-background-hover)}.menu__list-item-collapsible .menu__link--active,.menu__list-item-collapsible .menu__link:hover{background:none!important}.menu__caret,.menu__link{align-items:center;display:flex}.navbar-sidebar,.navbar-sidebar__backdrop{bottom:0;opacity:0;transition-duration:var(--ifm-transition-fast);transition-timing-function:ease-in-out;top:0;visibility:hidden;left:0}.menu__link{color:var(--ifm-menu-color);flex:1;line-height:1.25}.menu__link:hover{color:var(--ifm-menu-color);text-decoration:none}.menu__caret:before,.menu__link--sublist-caret:after{height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast) linear;width:1.25rem;filter:var(--ifm-menu-link-sublist-icon-filter);content:""}.menu__link--sublist-caret:after{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem;margin-left:auto;min-width:1.25rem}.menu__link--active,.menu__link--active:hover{color:var(--ifm-menu-color-active)}.navbar__brand,.navbar__link{color:var(--ifm-navbar-link-color)}.menu__link--active:not(.menu__link--sublist){background-color:var(--ifm-menu-color-background-active)}.menu__caret:before{background:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem}.navbar--dark,html[data-theme=dark]{--ifm-menu-link-sublist-icon-filter:invert(100%) sepia(94%) saturate(17%) hue-rotate(223deg) brightness(104%) contrast(98%)}.navbar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-navbar-shadow);height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar,.navbar>.container,.navbar>.container-fluid{display:flex}.navbar--fixed-top{position:sticky;top:0;z-index:var(--ifm-z-index-fixed)}.navbar__inner{display:flex;flex-wrap:wrap;justify-content:space-between;width:100%}.navbar__brand{align-items:center;display:flex;margin-right:1rem;min-width:0}.navbar__brand:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.announcementBarContent_xLdY,.navbar__title{flex:1 1 auto}.navbar__toggle{display:none;margin-right:.5rem}.navbar__logo{flex:0 0 auto;height:2rem;margin-right:.5rem}.navbar__items{align-items:center;display:flex;flex:1;min-width:0}.navbar__items--center{flex:0 0 auto}.navbar__items--center .navbar__brand{margin:0}.navbar__items--center+.navbar__items--right{flex:1}.navbar__items--right{flex:0 0 auto;justify-content:flex-end}.navbar__items--right>:last-child{padding-right:0}.navbar__item{display:inline-block;padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.navbar__link--active,.navbar__link:hover{color:var(--ifm-navbar-link-hover-color);text-decoration:none}.navbar--dark,.navbar--primary{--ifm-menu-color:var(--ifm-color-gray-300);--ifm-navbar-link-color:var(--ifm-color-gray-100);--ifm-navbar-search-input-background-color:#ffffff1a;--ifm-navbar-search-input-placeholder-color:#ffffff80;color:var(--ifm-color-white)}.navbar--dark{--ifm-navbar-background-color:#242526;--ifm-menu-color-background-active:#ffffff0d;--ifm-navbar-search-input-color:var(--ifm-color-white)}.navbar--primary{--ifm-navbar-background-color:var(--ifm-color-primary);--ifm-navbar-link-hover-color:var(--ifm-color-white);--ifm-menu-color-active:var(--ifm-color-white);--ifm-navbar-search-input-color:var(--ifm-color-emphasis-500)}.navbar__search-input{appearance:none;background:var(--ifm-navbar-search-input-background-color) var(--ifm-navbar-search-input-icon) no-repeat .75rem center/1rem 1rem;border:none;border-radius:2rem;color:var(--ifm-navbar-search-input-color);cursor:text;display:inline-block;font-size:1rem;height:2rem;padding:0 .5rem 0 2.25rem;width:12.5rem}.navbar__search-input::placeholder{color:var(--ifm-navbar-search-input-placeholder-color)}.navbar-sidebar{background-color:var(--ifm-navbar-background-color);box-shadow:var(--ifm-global-shadow-md);position:fixed;transform:translate3d(-100%,0,0);transition-property:opacity,visibility,transform;width:var(--ifm-navbar-sidebar-width)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar__items{transform:translateZ(0)}.navbar-sidebar--show .navbar-sidebar,.navbar-sidebar--show .navbar-sidebar__backdrop{opacity:1;visibility:visible}.navbar-sidebar__backdrop{background-color:#0009;position:fixed;right:0;transition-property:opacity,visibility}.navbar-sidebar__brand{align-items:center;box-shadow:var(--ifm-navbar-shadow);display:flex;flex:1;height:var(--ifm-navbar-height);padding:var(--ifm-navbar-padding-vertical) var(--ifm-navbar-padding-horizontal)}.navbar-sidebar__items{display:flex;height:calc(100% - var(--ifm-navbar-height));transition:transform var(--ifm-transition-fast) ease-in-out}.navbar-sidebar__items--show-secondary{transform:translate3d(calc((var(--ifm-navbar-sidebar-width))*-1),0,0)}.navbar-sidebar__item{flex-shrink:0;padding:.5rem;width:calc(var(--ifm-navbar-sidebar-width))}.navbar-sidebar__back{background:var(--ifm-menu-color-background-active);font-size:15px;font-weight:var(--ifm-button-font-weight);margin:0 0 .2rem -.5rem;padding:.6rem 1.5rem;position:relative;text-align:left;top:-.5rem;width:calc(100% + 1rem)}.navbar-sidebar__close{display:flex;margin-left:auto}.pagination{column-gap:var(--ifm-pagination-page-spacing);display:flex;font-size:var(--ifm-pagination-font-size);padding-left:0}.pagination--sm{--ifm-pagination-font-size:0.8rem;--ifm-pagination-padding-horizontal:0.8rem;--ifm-pagination-padding-vertical:0.2rem}.pagination--lg{--ifm-pagination-font-size:1.2rem;--ifm-pagination-padding-horizontal:1.2rem;--ifm-pagination-padding-vertical:0.3rem}.pagination__item{display:inline-flex}.pagination__item>span{padding:var(--ifm-pagination-padding-vertical)}.pagination__item--active .pagination__link{color:var(--ifm-pagination-color-active)}.pagination__item--active .pagination__link,.pagination__item:not(.pagination__item--active):hover .pagination__link{background:var(--ifm-pagination-item-active-background)}.pagination__item--disabled,.pagination__item[disabled]{opacity:.25;pointer-events:none}.pagination__link{border-radius:var(--ifm-pagination-border-radius);color:var(--ifm-font-color-base);display:inline-block;padding:var(--ifm-pagination-padding-vertical) var(--ifm-pagination-padding-horizontal);transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination__link:hover{text-decoration:none}.pagination-nav{display:grid;grid-gap:var(--ifm-spacing-horizontal);gap:var(--ifm-spacing-horizontal);grid-template-columns:repeat(2,1fr)}.pagination-nav__link{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);display:block;height:100%;line-height:var(--ifm-heading-line-height);padding:var(--ifm-global-spacing);transition:border-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.pagination-nav__link:hover{border-color:var(--ifm-pagination-nav-color-hover);text-decoration:none}.pagination-nav__link--next{grid-column:2/3;text-align:right}.pagination-nav__label{font-size:var(--ifm-h4-font-size);font-weight:var(--ifm-heading-font-weight);word-break:break-word}.pagination-nav__link--prev .pagination-nav__label:before{content:"« "}.pagination-nav__link--next .pagination-nav__label:after{content:" »"}.pagination-nav__sublabel{color:var(--ifm-color-content-secondary);font-size:var(--ifm-h5-font-size);font-weight:var(--ifm-font-weight-semibold);margin-bottom:.25rem}.pills__item,.tabs{font-weight:var(--ifm-font-weight-bold)}.pills{display:flex;gap:var(--ifm-pills-spacing);padding-left:0}.pills__item{border-radius:.5rem;cursor:pointer;display:inline-block;padding:.25rem 1rem;transition:background var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs,:not(.containsTaskList_mC6p>li)>.containsTaskList_mC6p{padding-left:0}.pills__item--active{color:var(--ifm-pills-color-active)}.pills__item--active,.pills__item:not(.pills__item--active):hover{background:var(--ifm-pills-color-background-active)}.pills--block{justify-content:stretch}.pills--block .pills__item{flex-grow:1;text-align:center}.tabs{color:var(--ifm-tabs-color);display:flex;margin-bottom:0;overflow-x:auto}.tabs__item{border-bottom:3px solid #0000;border-radius:var(--ifm-global-radius);cursor:pointer;display:inline-flex;padding:var(--ifm-tabs-padding-vertical) var(--ifm-tabs-padding-horizontal);transition:background-color var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.tabs__item--active{border-bottom-color:var(--ifm-tabs-color-active-border);border-bottom-left-radius:0;border-bottom-right-radius:0;color:var(--ifm-tabs-color-active)}.tabs__item:hover{background-color:var(--ifm-hover-overlay)}.tabs--block{justify-content:stretch}.tabs--block .tabs__item{flex-grow:1;justify-content:center}html[data-theme=dark]{--ifm-color-scheme:dark;--ifm-color-emphasis-0:var(--ifm-color-gray-1000);--ifm-color-emphasis-100:var(--ifm-color-gray-900);--ifm-color-emphasis-200:var(--ifm-color-gray-800);--ifm-color-emphasis-300:var(--ifm-color-gray-700);--ifm-color-emphasis-400:var(--ifm-color-gray-600);--ifm-color-emphasis-600:var(--ifm-color-gray-400);--ifm-color-emphasis-700:var(--ifm-color-gray-300);--ifm-color-emphasis-800:var(--ifm-color-gray-200);--ifm-color-emphasis-900:var(--ifm-color-gray-100);--ifm-color-emphasis-1000:var(--ifm-color-gray-0);--ifm-background-color:#1b1b1d;--ifm-background-surface-color:#242526;--ifm-hover-overlay:#ffffff0d;--ifm-color-content:#e3e3e3;--ifm-color-content-secondary:#fff;--ifm-breadcrumb-separator-filter:invert(64%) sepia(11%) saturate(0%) hue-rotate(149deg) brightness(99%) contrast(95%);--ifm-code-background:#ffffff1a;--ifm-scrollbar-track-background-color:#444;--ifm-scrollbar-thumb-background-color:#686868;--ifm-scrollbar-thumb-hover-background-color:#7a7a7a;--ifm-table-stripe-background:#ffffff12;--ifm-toc-border-color:var(--ifm-color-emphasis-200);--ifm-color-primary-contrast-background:#102445;--ifm-color-primary-contrast-foreground:#ebf2fc;--ifm-color-secondary-contrast-background:#474748;--ifm-color-secondary-contrast-foreground:#fdfdfe;--ifm-color-success-contrast-background:#003100;--ifm-color-success-contrast-foreground:#e6f6e6;--ifm-color-info-contrast-background:#193c47;--ifm-color-info-contrast-foreground:#eef9fd;--ifm-color-warning-contrast-background:#4d3800;--ifm-color-warning-contrast-foreground:#fff8e6;--ifm-color-danger-contrast-background:#4b1113;--ifm-color-danger-contrast-foreground:#ffebec}#nprogress .bar{background:var(--docusaurus-progress-bar-color);height:2px;left:0;position:fixed;top:0;width:100%;z-index:1031}#nprogress .peg{box-shadow:0 0 10px var(--docusaurus-progress-bar-color),0 0 5px var(--docusaurus-progress-bar-color);height:100%;opacity:1;position:absolute;right:0;transform:rotate(3deg) translateY(-4px);width:100px}[data-theme=dark]{--ifm-color-primary:#90ff99;--ifm-color-primary-dark:#5bc95b;--ifm-color-primary-darker:#238723;--ifm-color-primary-darkest:#124c12;--ifm-color-primary-light:#90ff99;--ifm-color-primary-lighter:#d2ffd3;--ifm-color-primary-lightest:#d2ffd3;--docusaurus-highlighted-code-line-bg:#0000004d}.header-github-link:hover{opacity:.6}.header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat;content:"";display:flex;height:24px;width:24px}html[data-theme=dark] .header-github-link:before{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") no-repeat}.tabs-container{border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-pagination-nav-border-radius);padding:var(--ifm-global-spacing)}.tabs{border-bottom:1px solid var(--ifm-color-emphasis-300)}.footer--dark{--ifm-footer-background-color:#303846;--ifm-footer-color:var(--ifm-footer-link-color);--ifm-footer-link-color:var(--ifm-color-secondary);--ifm-footer-title-color:var(--ifm-color-white);background-color:#000}.asciinema-theme-edgeless .asciinema-terminal{background-color:#000;border-color:#000;color:#fff}.asciinema-theme-edgeless .fg-bg{color:#000}.asciinema-theme-edgeless .bg-fg{background-color:#fff}.tag_zVej{border:1px solid var(--docusaurus-tag-list-border);transition:border var(--ifm-transition-fast)}.tag_zVej:hover{--docusaurus-tag-list-border:var(--ifm-link-color);text-decoration:none}.tagRegular_sFm0{border-radius:var(--ifm-global-radius);font-size:90%;padding:.2rem .5rem .3rem}.tagWithCount_h2kH{align-items:center;border-left:0;display:flex;padding:0 .5rem 0 1rem;position:relative}.tagWithCount_h2kH:after,.tagWithCount_h2kH:before{border:1px solid var(--docusaurus-tag-list-border);content:"";position:absolute;top:50%;transition:inherit}.tagWithCount_h2kH:before{border-bottom:0;border-right:0;height:1.18rem;right:100%;transform:translate(50%,-50%) rotate(-45deg);width:1.18rem}.tagWithCount_h2kH:after{border-radius:50%;height:.5rem;left:0;transform:translateY(-50%);width:.5rem}.tagWithCount_h2kH span{background:var(--ifm-color-secondary);border-radius:var(--ifm-global-radius);color:var(--ifm-color-black);font-size:.7rem;line-height:1.2;margin-left:.3rem;padding:.1rem .4rem}.tags_jXut{display:inline}.tag_QGVx{display:inline-block;margin:0 .4rem .5rem 0}.iconEdit_Z9Sw{margin-right:.3em;vertical-align:sub}.lastUpdated_JAkA{font-size:smaller;font-style:italic;margin-top:.2rem}.tocCollapsibleButton_TO0P{align-items:center;display:flex;font-size:inherit;justify-content:space-between;padding:.4rem .8rem;width:100%}.tocCollapsibleButton_TO0P:after{background:var(--ifm-menu-link-sublist-icon) 50% 50%/2rem 2rem no-repeat;content:"";filter:var(--ifm-menu-link-sublist-icon-filter);height:1.25rem;transform:rotate(180deg);transition:transform var(--ifm-transition-fast);width:1.25rem}.tocCollapsibleButtonExpanded_MG3E:after,.tocCollapsibleExpanded_sAul{transform:none}.tocCollapsible_ETCw{background-color:var(--ifm-menu-color-background-active);border-radius:var(--ifm-global-radius);margin:1rem 0}.tocCollapsibleContent_vkbj>ul{border-left:none;border-top:1px solid var(--ifm-color-emphasis-300);font-size:15px;padding:.2rem 0}.tocCollapsibleContent_vkbj ul li{margin:.4rem .8rem}.tocCollapsibleContent_vkbj a{display:block}.tableOfContents_bqdL{max-height:calc(100vh - var(--ifm-navbar-height) - 2rem);overflow-y:auto;position:sticky;top:calc(var(--ifm-navbar-height) + 1rem)}.backToTopButton_sjWU{background-color:var(--ifm-color-emphasis-200);border-radius:50%;bottom:1.3rem;box-shadow:var(--ifm-global-shadow-lw);height:3rem;opacity:0;position:fixed;right:1.3rem;transform:scale(0);transition:all var(--ifm-transition-fast) var(--ifm-transition-timing-default);visibility:hidden;width:3rem;z-index:calc(var(--ifm-z-index-fixed) - 1)}.buttonGroup__atx button,.codeBlockContainer_Ckt0{background:var(--prism-background-color);color:var(--prism-color)}.backToTopButton_sjWU:after{background-color:var(--ifm-color-emphasis-1000);content:" ";display:inline-block;height:100%;-webkit-mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;mask:var(--ifm-menu-link-sublist-icon) 50%/2rem 2rem no-repeat;width:100%}.backToTopButtonShow_xfvO{opacity:1;transform:scale(1);visibility:visible}.docSidebarContainer_YfHR,.sidebarLogo_isFc,.themedComponent_mlkZ{display:none}[data-theme=dark] .themedComponent--dark_xIcU,[data-theme=light] .themedComponent--light_NVdE,html:not([data-theme]) .themedComponent--light_NVdE{display:initial}[data-theme=dark]:root{--docusaurus-collapse-button-bg:#ffffff0d;--docusaurus-collapse-button-bg-hover:#ffffff1a}.collapseSidebarButton_PEFL{display:none;margin:0}.iconExternalLink_nPIU{margin-left:.3rem}.docMainContainer_TBSr,.docRoot_UBD9{display:flex;width:100%}.docsWrapper_hBAB{display:flex;flex:1 0 auto}.anchorWithStickyNavbar_LWe7{scroll-margin-top:calc(var(--ifm-navbar-height) + .5rem)}.anchorWithHideOnScrollNavbar_WYt5{scroll-margin-top:.5rem}.hash-link{opacity:0;padding-left:.5rem;transition:opacity var(--ifm-transition-fast);-webkit-user-select:none;user-select:none}.hash-link:before{content:"#"}.footerLogoLink_BH7S:hover,.hash-link:focus,:hover>.hash-link{opacity:1}.cardContainer_fWXF{--ifm-link-color:var(--ifm-color-emphasis-800);--ifm-link-hover-color:var(--ifm-color-emphasis-700);--ifm-link-hover-decoration:none;border:1px solid var(--ifm-color-emphasis-200);box-shadow:0 1.5px 3px 0 #00000026;transition:all var(--ifm-transition-fast) ease;transition-property:border,box-shadow}.cardContainer_fWXF:hover{border-color:var(--ifm-color-primary);box-shadow:0 3px 6px 0 #0003}.cardTitle_rnsV{font-size:1.2rem}.cardDescription_PWke{font-size:.8rem}.codeBlockContainer_Ckt0{border-radius:var(--ifm-code-border-radius);box-shadow:var(--ifm-global-shadow-lw);margin-bottom:var(--ifm-leading)}.codeBlockContent_biex{border-radius:inherit;direction:ltr;position:relative}.codeBlockTitle_Ktv7{border-bottom:1px solid var(--ifm-color-emphasis-300);border-top-left-radius:inherit;border-top-right-radius:inherit;font-size:var(--ifm-code-font-size);font-weight:500;padding:.75rem var(--ifm-pre-padding)}.codeBlock_bY9V{--ifm-pre-background:var(--prism-background-color);margin:0;padding:0}.codeBlockTitle_Ktv7+.codeBlockContent_biex .codeBlock_bY9V{border-top-left-radius:0;border-top-right-radius:0}.codeBlockLines_e6Vv{float:left;font:inherit;min-width:100%;padding:var(--ifm-pre-padding)}.codeBlockLinesWithNumbering_o6Pm{display:table;padding:var(--ifm-pre-padding) 0}.buttonGroup__atx{column-gap:.2rem;display:flex;position:absolute;right:calc(var(--ifm-pre-padding)/2);top:calc(var(--ifm-pre-padding)/2)}.buttonGroup__atx button{align-items:center;border:1px solid var(--ifm-color-emphasis-300);border-radius:var(--ifm-global-radius);display:flex;line-height:0;opacity:0;padding:.4rem;transition:opacity var(--ifm-transition-fast) ease-in-out}.buttonGroup__atx button:focus-visible,.buttonGroup__atx button:hover{opacity:1!important}.theme-code-block:hover .buttonGroup__atx button{opacity:.4}:where(:root){--docusaurus-highlighted-code-line-bg:#484d5b}:where([data-theme=dark]){--docusaurus-highlighted-code-line-bg:#646464}.theme-code-block-highlighted-line{background-color:var(--docusaurus-highlighted-code-line-bg);display:block;margin:0 calc(var(--ifm-pre-padding)*-1);padding:0 var(--ifm-pre-padding)}.codeLine_lJS_{counter-increment:a;display:table-row}.codeLineNumber_Tfdd{background:var(--ifm-pre-background);display:table-cell;left:0;overflow-wrap:normal;padding:0 var(--ifm-pre-padding);position:sticky;text-align:right;width:1%}.codeLineNumber_Tfdd:before{content:counter(a);opacity:.4}.codeLineContent_feaV{padding-right:var(--ifm-pre-padding)}.theme-code-block:hover .copyButtonCopied_obH4{opacity:1!important}.copyButtonIcons_eSgA{height:1.125rem;position:relative;width:1.125rem}.copyButtonIcon_y97N,.copyButtonSuccessIcon_LjdS{left:0;position:absolute;top:0;fill:currentColor;height:inherit;opacity:inherit;transition:all var(--ifm-transition-fast) ease;width:inherit}.copyButtonSuccessIcon_LjdS{color:#00d600;left:50%;opacity:0;top:50%;transform:translate(-50%,-50%) scale(.33)}.copyButtonCopied_obH4 .copyButtonIcon_y97N{opacity:0;transform:scale(.33)}.copyButtonCopied_obH4 .copyButtonSuccessIcon_LjdS{opacity:1;transform:translate(-50%,-50%) scale(1);transition-delay:75ms}.wordWrapButtonIcon_Bwma{height:1.2rem;width:1.2rem}.details_lb9f{--docusaurus-details-summary-arrow-size:0.38rem;--docusaurus-details-transition:transform 200ms ease;--docusaurus-details-decoration-color:grey}.details_lb9f>summary{cursor:pointer;padding-left:1rem;position:relative}.details_lb9f>summary::-webkit-details-marker{display:none}.details_lb9f>summary:before{border-color:#0000 #0000 #0000 var(--docusaurus-details-decoration-color);border-style:solid;border-width:var(--docusaurus-details-summary-arrow-size);content:"";left:0;position:absolute;top:.45rem;transform:rotate(0);transform-origin:calc(var(--docusaurus-details-summary-arrow-size)/2) 50%;transition:var(--docusaurus-details-transition)}.collapsibleContent_i85q{border-top:1px solid var(--docusaurus-details-decoration-color);margin-top:1rem;padding-top:1rem}.details_b_Ee{--docusaurus-details-decoration-color:var(--ifm-alert-border-color);--docusaurus-details-transition:transform var(--ifm-transition-fast) ease;border:1px solid var(--ifm-alert-border-color);margin:0 0 var(--ifm-spacing-vertical)}.img_ev3q{height:auto}.admonition_xJq3{margin-bottom:1em}.admonitionHeading_Gvgb{font:var(--ifm-heading-font-weight) var(--ifm-h5-font-size)/var(--ifm-heading-line-height) var(--ifm-heading-font-family)}.admonitionHeading_Gvgb:not(:last-child){margin-bottom:.3rem}.admonitionHeading_Gvgb code{text-transform:none}.admonitionIcon_Rf37{display:inline-block;margin-right:.4em;vertical-align:middle}.admonitionIcon_Rf37 svg{display:inline-block;height:1.6em;width:1.6em;fill:var(--ifm-alert-foreground-color)}.skipToContent_fXgn{background-color:var(--ifm-background-surface-color);color:var(--ifm-color-emphasis-900);left:100%;padding:calc(var(--ifm-global-spacing)/2) var(--ifm-global-spacing);position:fixed;top:1rem;z-index:calc(var(--ifm-z-index-fixed) + 1)}.skipToContent_fXgn:focus{box-shadow:var(--ifm-global-shadow-md);left:1rem}.closeButton_CVFx{line-height:0;padding:0}.content_knG7{font-size:85%;padding:5px 0;text-align:center}.content_knG7 a{color:inherit;text-decoration:underline}.announcementBar_mb4j{align-items:center;background-color:var(--ifm-color-white);border-bottom:1px solid var(--ifm-color-emphasis-100);color:var(--ifm-color-black);display:flex;height:var(--docusaurus-announcement-bar-height)}.aa-ClearButton[hidden],.aa-ItemContent:empty,.aa-LoadingIndicator[hidden],.aa-Source:empty,.aa-SourceHeader:empty,[data-theme=dark] .lightToggleIcon_pyhR,[data-theme=light] .darkToggleIcon_wfgR,html[data-announcement-bar-initially-dismissed=true] .announcementBar_mb4j{display:none}.announcementBarPlaceholder_vyr4{flex:0 0 10px}.announcementBarClose_gvF7{align-self:stretch;flex:0 0 30px}.toggle_vylO{height:2rem;width:2rem}.aa-Form,.toggleButton_gllP{align-items:center;width:100%;display:flex}.toggleButton_gllP{border-radius:50%;height:100%;justify-content:center;transition:background var(--ifm-transition-fast)}.toggleButton_gllP:hover{background:var(--ifm-color-emphasis-200)}.toggleButtonDisabled_aARS{cursor:not-allowed}.darkNavbarColorModeToggle_X3D1:hover{background:var(--ifm-color-gray-800)}.dropdownNavbarItemMobile_S0Fm{cursor:pointer}.iconLanguage_nlXk{margin-right:5px;vertical-align:text-bottom}body.dark,body[data-theme=dark]{--aa-text-color-rgb:183,192,199;--aa-primary-color-rgb:146,138,255;--aa-muted-color-rgb:146,138,255;--aa-input-background-color-rgb:0,3,9;--aa-background-color-rgb:21,24,42;--aa-selected-color-rgb:146,138,255;--aa-selected-color-alpha:0.25;--aa-description-highlight-background-color-rgb:0 255 255;--aa-description-highlight-background-color-alpha:0.25;--aa-panel-shadow:inset 1px 1px 0 0 #2c2e40,0 3px 8px 0 #000309;--aa-scrollbar-track-background-color-rgb:44,46,64;--aa-muted-color-alpha:1}.aa-Autocomplete,.aa-DetachedFormContainer,.aa-Panel{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-family:inherit;font-family:var(--aa-font-family);font-size:16px;font-size:var(--aa-font-size);font-weight:400;line-height:1em;margin:0;padding:0;text-align:left}.aa-Form{background-color:#fff;background-color:rgba(var(--aa-input-background-color-rgb),var(--aa-input-background-color-alpha));border:1px solid #807ea3cc;border:1px solid rgba(var(--aa-input-border-color-rgb),var(--aa-input-border-color-alpha));border-radius:3px;line-height:1em;margin:0;position:relative}.aa-ClearButton,.aa-Input,.aa-SubmitButton{border:0;background:none}.aa-Form:focus-within{border-color:#3e34d3;border-color:rgba(var(--aa-primary-color-rgb),1);box-shadow:0 0 0 2px #3e34d333,inset 0 0 0 2px #3e34d333;box-shadow:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px,inset rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px;outline:currentColor}.aa-InputWrapperPrefix{align-items:center;display:flex;flex-shrink:0;height:44px;height:var(--aa-search-input-height);order:1}.aa-Label,.aa-LoadingIndicator{cursor:auto;flex-shrink:0;height:100%;padding:0;text-align:left}.aa-Label svg,.aa-LoadingIndicator svg{color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);height:auto;max-height:20px;max-height:var(--aa-input-icon-size);stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-input-icon-size)}.aa-LoadingIndicator,.aa-SubmitButton{height:100%;padding-left:11px;padding-left:calc(var(--aa-spacing)*.75 - 1px);padding-right:8px;padding-right:var(--aa-spacing-half);width:47px;width:calc(var(--aa-spacing)*1.75 + var(--aa-icon-size) - 1px)}.aa-SubmitButton{appearance:none;margin:0}.aa-LoadingIndicator{align-items:center;display:flex;justify-content:center}.aa-InputWrapper{order:3;position:relative;width:100%}.aa-Input{appearance:none;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font:inherit;height:44px;height:var(--aa-search-input-height);padding:0;width:100%}.aa-Input::placeholder{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));opacity:1}.aa-Input:focus{border-color:none;box-shadow:none;outline:0}.aa-Input::-webkit-search-cancel-button,.aa-Input::-webkit-search-decoration,.aa-Input::-webkit-search-results-button,.aa-Input::-webkit-search-results-decoration{appearance:none}.aa-InputWrapperSuffix{align-items:center;display:flex;height:44px;height:var(--aa-search-input-height);order:4}.aa-ClearButton{align-items:center;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;height:100%;margin:0;padding:0 12.83328px;padding:0 calc(var(--aa-spacing)*.83333 - .5px)}.aa-Item,.aa-ItemIcon{align-items:center;border-radius:3px}.aa-ClearButton:focus,.aa-ClearButton:hover,.aa-ItemActionButton:focus svg,.aa-ItemActionButton:hover svg{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha))}.aa-ClearButton svg{stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-icon-size)}.aa-Panel{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));border-radius:4px;border-radius:calc(var(--aa-spacing)/4);box-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;box-shadow:var(--aa-panel-shadow);margin:8px 0 0;overflow:hidden;position:absolute;transition:opacity .2s ease-in,filter .2s ease-in}.aa-Panel button{appearance:none;background:none;border:0;margin:0;padding:0}.aa-PanelLayout{height:100%;margin:0;max-height:650px;max-height:var(--aa-panel-max-height);overflow-y:auto;padding:0;position:relative;text-align:left}.aa-PanelLayoutColumns--twoGolden{display:grid;grid-template-columns:39.2% auto;overflow:hidden;padding:0}.aa-PanelLayoutColumns--two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));overflow:hidden;padding:0}.aa-PanelLayoutColumns--three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));overflow:hidden;padding:0}.aa-Panel--stalled .aa-Source{filter:grayscale(1);opacity:.8}.aa-Panel--scrollable{margin:0;max-height:650px;max-height:var(--aa-panel-max-height);overflow-x:hidden;overflow-y:auto;padding:8px;padding:var(--aa-spacing-half);scrollbar-color:#fff #eaeaea;scrollbar-color:rgba(var(--aa-scrollbar-thumb-background-color-rgb),var(--aa-scrollbar-thumb-background-color-alpha)) rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha));scrollbar-width:thin}.aa-Panel--scrollable::-webkit-scrollbar{width:13px;width:var(--aa-scrollbar-width)}.aa-Panel--scrollable::-webkit-scrollbar-track{background-color:#eaeaea;background-color:rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha))}.aa-Panel--scrollable::-webkit-scrollbar-thumb{background-color:#fff;background-color:rgba(var(--aa-scrollbar-thumb-background-color-rgb),var(--aa-scrollbar-thumb-background-color-alpha));border:3px solid #eaeaea;border:3px solid rgba(var(--aa-scrollbar-track-background-color-rgb),var(--aa-scrollbar-track-background-color-alpha));border-radius:9999px;border-right-width:2px}.aa-Source{margin:0;padding:0;position:relative;width:100%}.aa-SourceNoResults{font-size:1em;margin:0;padding:16px;padding:var(--aa-spacing)}.aa-List{margin:0}.aa-List,.aa-SourceHeader{padding:0;position:relative}.aa-SourceHeader{margin:8px .5em 8px 0;margin:var(--aa-spacing-half) .5em var(--aa-spacing-half) 0}.aa-SourceHeaderTitle{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);display:inline-block;font-size:.8em;font-weight:600;font-weight:var(--aa-font-weight-semibold);margin:0;padding:0 8px 0 0;padding:0 var(--aa-spacing-half) 0 0;position:relative;z-index:9999;z-index:var(--aa-base-z-index)}.aa-SourceHeaderLine{border-bottom:1px solid #3e34d3;border-bottom:1px solid rgba(var(--aa-primary-color-rgb),1);display:block;height:2px;left:0;margin:0;opacity:.3;padding:0;position:absolute;right:0;top:8px;top:var(--aa-spacing-half);z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-SourceFooterSeeAll{background:linear-gradient(180deg,#fff,#807ea324);background:linear-gradient(180deg,rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha)),#807ea324);border:1px solid #807ea399;border:1px solid rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));border-radius:5px;box-shadow:inset 0 0 2px #fff,0 2px 2px -1px #4c455826;color:inherit;font-size:.95em;font-weight:500;font-weight:var(--aa-font-weight-medium);padding:.475em 1em .6em;-webkit-text-decoration:none;text-decoration:none}.aa-SourceFooterSeeAll:focus,.aa-SourceFooterSeeAll:hover{border:1px solid #3e34d3;border:1px solid rgba(var(--aa-primary-color-rgb),1);color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1)}.aa-Item{cursor:pointer;display:grid;min-height:40px;min-height:calc(var(--aa-spacing)*2.5);padding:4px;padding:calc(var(--aa-spacing-half)/2)}.aa-Item[aria-selected=true]{background-color:rgba(179,173,214,.205);background-color:rgba(var(--aa-selected-color-rgb),var(--aa-selected-color-alpha))}.aa-Item[aria-selected=true] .aa-ActiveOnly,.aa-Item[aria-selected=true] .aa-ItemActionButton{visibility:visible}.aa-ItemIcon{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));box-shadow:inset 0 0 0 1px #807ea34d;box-shadow:inset 0 0 0 1px rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));color:#7777a3;color:rgba(var(--aa-icon-color-rgb),var(--aa-icon-color-alpha));display:flex;flex-shrink:0;font-size:.7em;height:28px;height:calc(var(--aa-icon-size) + var(--aa-spacing-half));justify-content:center;overflow:hidden;stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);text-align:center;width:28px;width:calc(var(--aa-icon-size) + var(--aa-spacing-half))}.aa-ItemIcon img{height:auto;max-height:20px;max-height:calc(var(--aa-icon-size) + var(--aa-spacing-half) - 8px);max-width:20px;max-width:calc(var(--aa-icon-size) + var(--aa-spacing-half) - 8px);width:auto}.aa-ItemIcon svg{height:20px;height:var(--aa-icon-size);width:20px;width:var(--aa-icon-size)}.aa-ItemIcon--alignTop{align-self:flex-start}.aa-ItemIcon--noBorder{background:none;box-shadow:none}.aa-ItemIcon--picture{height:96px;width:96px}.aa-ItemIcon--picture img{max-height:100%;max-width:100%;padding:8px;padding:var(--aa-spacing-half)}.aa-ItemContent{align-items:center;cursor:pointer;display:grid;gap:8px;grid-gap:8px;grid-gap:var(--aa-spacing-half);gap:var(--aa-spacing-half);grid-auto-flow:column;line-height:1.25em;overflow:hidden}.aa-ItemContent mark{background:none;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-style:normal;font-weight:700;font-weight:var(--aa-font-weight-bold)}.aa-ItemContent--dual{display:flex;flex-direction:column;justify-content:space-between;text-align:left}.aa-ItemContent--dual .aa-ItemContentSubtitle,.aa-ItemContent--dual .aa-ItemContentTitle{display:block}.aa-ItemContent--indented{padding-left:36px;padding-left:calc(var(--aa-icon-size) + var(--aa-spacing))}.aa-ItemContentBody{display:grid;gap:4px;grid-gap:4px;grid-gap:calc(var(--aa-spacing-half)/2);gap:calc(var(--aa-spacing-half)/2)}.aa-ItemContentTitle{display:inline-block;margin:0 .5em 0 0;max-width:100%;overflow:hidden;padding:0;text-overflow:ellipsis;white-space:nowrap}.aa-ItemContentSubtitle{font-size:.92em}.aa-ItemContentSubtitleIcon:before{border-color:#807ea3a3;border-color:rgba(var(--aa-muted-color-rgb),.64);border-style:solid;content:"";display:inline-block;left:1px;position:relative;top:-3px}.aa-PanelFooter:after,.aa-PanelHeader:after{content:"";position:absolute;left:0;pointer-events:none;right:0}.aa-ItemContentSubtitle--inline .aa-ItemContentSubtitleIcon:before{border-width:0 0 1.5px;margin-left:8px;margin-left:var(--aa-spacing-half);margin-right:4px;margin-right:calc(var(--aa-spacing-half)/2);width:10px;width:calc(var(--aa-spacing-half) + 2px)}.aa-ItemContentSubtitle--standalone{align-items:center;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));display:grid;gap:8px;grid-gap:8px;grid-gap:var(--aa-spacing-half);gap:var(--aa-spacing-half);grid-auto-flow:column;justify-content:start}#__docusaurus-base-url-issue-banner-container,.aa-DetachedContainer--modal .aa-PanelLayout:empty,.aa-DetachedSearchButtonPlaceholder[hidden],.aa-ItemContentDescription:empty,.navbarSearchContainer_Bca1:empty{display:none}.aa-ItemContentSubtitle--standalone .aa-ItemContentSubtitleIcon:before{border-radius:0 0 0 3px;border-width:0 0 1.5px 1.5px;height:8px;height:var(--aa-spacing-half);width:8px;width:var(--aa-spacing-half)}.aa-ItemContentSubtitleCategory{color:#807ea3;color:rgba(var(--aa-muted-color-rgb),1);font-weight:500}.aa-ItemContentDescription{color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-size:.85em;max-width:100%;overflow-x:hidden;text-overflow:ellipsis}.aa-ItemContentDescription mark{background:#f5df4d80;background:rgba(var(--aa-description-highlight-background-color-rgb),var(--aa-description-highlight-background-color-alpha));color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));font-style:normal;font-weight:500;font-weight:var(--aa-font-weight-medium)}.aa-ItemContentDash{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));display:none;opacity:.4}.aa-ItemContentTag{background-color:#3e34d333;background-color:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha));border-radius:3px;margin:0 .4em 0 0;padding:.08em .3em}.aa-ItemLink,.aa-ItemWrapper{align-items:center;color:inherit;display:grid;gap:4px;grid-gap:4px;grid-gap:calc(var(--aa-spacing-half)/2);gap:calc(var(--aa-spacing-half)/2);grid-auto-flow:column;justify-content:space-between;width:100%}.aa-ItemLink{color:inherit;-webkit-text-decoration:none;text-decoration:none}.aa-ItemActions{display:grid;grid-auto-flow:column;height:100%;justify-self:end;margin:0 -5.33333px;margin:0 calc(var(--aa-spacing)/-3);padding:0 2px 0 0}.aa-ItemActionButton{align-items:center;background:none;border:0;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;flex-shrink:0;padding:0}.aa-ItemActionButton svg{color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));margin:5.33333px;margin:calc(var(--aa-spacing)/3);stroke-width:1.6;stroke-width:var(--aa-icon-stroke-width);width:20px;width:var(--aa-action-icon-size)}.aa-ActiveOnly{visibility:hidden}.aa-PanelHeader{align-items:center;background:#3e34d3;background:rgba(var(--aa-primary-color-rgb),1);color:#fff;display:grid;height:var(--aa-modal-header-height);margin:0;padding:8px 16px;padding:var(--aa-spacing-half) var(--aa-spacing);position:relative}.aa-PanelHeader:after{background-image:linear-gradient(#fff,#fff0);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),1),rgba(var(--aa-background-color-rgb),0));bottom:-8px;bottom:calc(var(--aa-spacing-half)*-1);height:8px;height:var(--aa-spacing-half)}.aa-PanelFooter,.aa-PanelHeader:after{z-index:9999;z-index:var(--aa-base-z-index)}.aa-PanelFooter{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));box-shadow:inset 0 1px 0 #807ea34d;box-shadow:inset 0 1px 0 rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));display:flex;justify-content:space-between;margin:0;padding:16px;padding:var(--aa-spacing);position:relative}.aa-PanelFooter:after{background-image:linear-gradient(#fff0,#807ea399);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),0),rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha)));height:16px;height:var(--aa-spacing);opacity:.12;top:-16px;top:calc(var(--aa-spacing)*-1);z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-DetachedContainer{background:#fff;background:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));bottom:0;box-shadow:0 0 0 1px #23263b1a,0 6px 16px -4px #23263b26;box-shadow:var(--aa-panel-shadow);display:flex;flex-direction:column;left:0;margin:0;overflow:hidden;padding:0;position:fixed;right:0;top:0;z-index:9999;z-index:var(--aa-base-z-index)}.aa-DetachedContainer:after{height:32px}.aa-DetachedContainer .aa-SourceHeader{margin:8px 0 8px 2px;margin:var(--aa-spacing-half) 0 var(--aa-spacing-half) 2px}.aa-DetachedContainer .aa-Panel{background-color:#fff;background-color:rgba(var(--aa-background-color-rgb),var(--aa-background-color-alpha));border-radius:0;box-shadow:none;flex-grow:1;margin:0;padding:0;position:relative}.aa-DetachedContainer .aa-PanelLayout{bottom:0;box-shadow:none;left:0;margin:0;max-height:none;overflow-y:auto;position:absolute;right:0;top:0;width:100%}.aa-DetachedFormContainer{border-bottom:1px solid #807ea34d;border-bottom:1px solid rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha));display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:8px;padding:var(--aa-spacing-half)}.aa-DetachedCancelButton{background:none;border:0;border-radius:3px;color:#262627;color:rgba(var(--aa-text-color-rgb),var(--aa-text-color-alpha));cursor:pointer;font:inherit;margin:0 0 0 8px;margin:0 0 0 var(--aa-spacing-half);padding:0 8px;padding:0 var(--aa-spacing-half)}.aa-DetachedCancelButton:focus,.aa-DetachedCancelButton:hover{box-shadow:inset 0 0 0 1px #807ea34d;box-shadow:inset 0 0 0 1px rgba(var(--aa-panel-border-color-rgb),var(--aa-panel-border-color-alpha))}.aa-DetachedContainer--modal{border-radius:6px;bottom:inherit;height:auto;margin:0 auto;max-width:680px;max-width:var(--aa-detached-modal-max-width);position:absolute;top:3%}.aa-DetachedContainer--modal .aa-PanelLayout{max-height:500px;max-height:var(--aa-detached-modal-max-height);padding-bottom:8px;padding-bottom:var(--aa-spacing-half);position:static}.aa-DetachedSearchButton{align-items:center;background-color:#fff;background-color:rgba(var(--aa-input-background-color-rgb),var(--aa-input-background-color-alpha));border:1px solid #807ea3cc;border:1px solid rgba(var(--aa-input-border-color-rgb),var(--aa-input-border-color-alpha));border-radius:3px;color:#807ea399;color:rgba(var(--aa-muted-color-rgb),var(--aa-muted-color-alpha));cursor:pointer;display:flex;font:inherit;font-family:inherit;font-family:var(--aa-font-family);font-size:16px;font-size:var(--aa-font-size);height:44px;height:var(--aa-search-input-height);margin:0;padding:0 5.5px;padding:0 calc(var(--aa-search-input-height)/8);position:relative;text-align:left;width:100%}.aa-DetachedSearchButton:focus{border-color:#3e34d3;border-color:rgba(var(--aa-primary-color-rgb),1);box-shadow:0 0 0 3px #3e34d333,inset 0 0 0 2px #3e34d333;box-shadow:rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 3px,inset rgba(var(--aa-primary-color-rgb),var(--aa-primary-color-alpha)) 0 0 0 2px;outline:currentColor}.aa-DetachedSearchButtonIcon{align-items:center;color:#3e34d3;color:rgba(var(--aa-primary-color-rgb),1);cursor:auto;display:flex;flex-shrink:0;height:100%;justify-content:center;width:36px;width:calc(var(--aa-icon-size) + var(--aa-spacing))}.aa-DetachedSearchButtonQuery{color:#262627;color:rgba(var(--aa-text-color-rgb),1);line-height:1.25em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.aa-Detached{height:100vh;overflow:hidden}.aa-DetachedOverlay{background-color:#73728166;background-color:rgba(var(--aa-overlay-color-rgb),var(--aa-overlay-color-alpha));height:100vh;left:0;margin:0;padding:0;position:fixed;right:0;top:0;z-index:9998;z-index:calc(var(--aa-base-z-index) - 1)}.aa-GradientBottom,.aa-GradientTop{height:8px;height:var(--aa-spacing-half);left:0;pointer-events:none;position:absolute;right:0;z-index:9999;z-index:var(--aa-base-z-index)}.aa-GradientTop{background-image:linear-gradient(#fff,#fff0);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),1),rgba(var(--aa-background-color-rgb),0));top:0}.aa-GradientBottom{background-image:linear-gradient(#fff0,#fff);background-image:linear-gradient(rgba(var(--aa-background-color-rgb),0),rgba(var(--aa-background-color-rgb),1));border-bottom-left-radius:4px;border-bottom-left-radius:calc(var(--aa-spacing)/4);border-bottom-right-radius:4px;border-bottom-right-radius:calc(var(--aa-spacing)/4);bottom:0}.navbarHideable_m1mJ{transition:transform var(--ifm-transition-fast) ease}.navbarHidden_jGov{transform:translate3d(0,calc(-100% - 2px),0)}.errorBoundaryError_a6uf{color:red;white-space:pre-wrap}.errorBoundaryFallback_VBag{color:red;padding:.55rem}body:not(.navigation-with-keyboard) :not(input):focus{outline:0}.footerLogoLink_BH7S{opacity:.5;transition:opacity var(--ifm-transition-fast) var(--ifm-transition-timing-default)}.mainWrapper_z2l0{display:flex;flex:1 0 auto;flex-direction:column}.docusaurus-mt-lg{margin-top:3rem}#__docusaurus{display:flex;flex-direction:column;min-height:100%}.breadcrumbHomeIcon_YNFT{height:1.1rem;position:relative;top:1px;vertical-align:top;width:1.1rem}.breadcrumbsContainer_Z_bl{--ifm-breadcrumb-size-multiplier:0.8;margin-bottom:.8rem}.title_kItE{--ifm-h1-font-size:3rem;margin-bottom:calc(var(--ifm-leading)*1.25)}@media (min-width:997px){.collapseSidebarButton_PEFL,.expandButton_TmdG{background-color:var(--docusaurus-collapse-button-bg)}.lastUpdated_JAkA{text-align:right}.tocMobile_ITEo{display:none}.collapseSidebarButton_PEFL{border:1px solid var(--ifm-toc-border-color);border-radius:0;bottom:0;display:block!important;height:40px;position:sticky}.collapseSidebarButtonIcon_kv0_{margin-top:4px;transform:rotate(180deg)}.expandButtonIcon_i1dp,[dir=rtl] .collapseSidebarButtonIcon_kv0_{transform:rotate(0)}.collapseSidebarButton_PEFL:focus,.collapseSidebarButton_PEFL:hover,.expandButton_TmdG:focus,.expandButton_TmdG:hover{background-color:var(--docusaurus-collapse-button-bg-hover)}.menuHtmlItem_M9Kj{padding:var(--ifm-menu-link-padding-vertical) var(--ifm-menu-link-padding-horizontal)}.menu_SIkG{flex-grow:1;padding:.5rem}@supports (scrollbar-gutter:stable){.menu_SIkG{padding:.5rem 0 .5rem .5rem;scrollbar-gutter:stable}}.menuWithAnnouncementBar_GW3s{margin-bottom:var(--docusaurus-announcement-bar-height)}.sidebar_njMd{display:flex;flex-direction:column;height:100%;padding-top:var(--ifm-navbar-height);width:var(--doc-sidebar-width)}.sidebarWithHideableNavbar_wUlq{padding-top:0}.sidebarHidden_VK0M{opacity:0;visibility:hidden}.sidebarLogo_isFc{align-items:center;color:inherit!important;display:flex!important;margin:0 var(--ifm-navbar-padding-horizontal);max-height:var(--ifm-navbar-height);min-height:var(--ifm-navbar-height);text-decoration:none!important}.sidebarLogo_isFc img{height:2rem;margin-right:.5rem}.expandButton_TmdG{align-items:center;display:flex;height:100%;justify-content:center;position:absolute;right:0;top:0;transition:background-color var(--ifm-transition-fast) ease;width:100%}[dir=rtl] .expandButtonIcon_i1dp{transform:rotate(180deg)}.docSidebarContainer_YfHR{border-right:1px solid var(--ifm-toc-border-color);clip-path:inset(0);display:block;margin-top:calc(var(--ifm-navbar-height)*-1);transition:width var(--ifm-transition-fast) ease;width:var(--doc-sidebar-width);will-change:width}.docSidebarContainerHidden_DPk8{cursor:pointer;width:var(--doc-sidebar-hidden-width)}.sidebarViewport_aRkj{height:100%;max-height:100vh;position:sticky;top:0}.docMainContainer_TBSr{flex-grow:1;max-width:calc(100% - var(--doc-sidebar-width))}.docMainContainerEnhanced_lQrH{max-width:calc(100% - var(--doc-sidebar-hidden-width))}.docItemWrapperEnhanced_JWYK{max-width:calc(var(--ifm-container-width) + var(--doc-sidebar-width))!important}:root{--docusaurus-announcement-bar-height:30px}.announcementBarClose_gvF7,.announcementBarPlaceholder_vyr4{flex-basis:50px}.navbarSearchContainer_Bca1{padding:var(--ifm-navbar-item-padding-vertical) var(--ifm-navbar-item-padding-horizontal)}.docItemCol_VOVn,.generatedIndexPage_vN6x{max-width:75%!important}.list_eTzJ article:nth-last-child(-n+2){margin-bottom:0!important}}@media (min-width:1440px){.container{max-width:var(--ifm-container-width-xl)}}@media (max-width:996px){.col{--ifm-col-width:100%;flex-basis:var(--ifm-col-width);margin-left:0}.footer{--ifm-footer-padding-horizontal:0}.colorModeToggle_DEke,.footer__link-separator,.navbar__item,.tableOfContents_bqdL{display:none}.footer__col{margin-bottom:calc(var(--ifm-spacing-vertical)*3)}.footer__link-item{display:block;width:max-content}.hero{padding-left:0;padding-right:0}.navbar>.container,.navbar>.container-fluid{padding:0}.navbar__toggle{display:inherit}.navbar__search-input{width:9rem}.pills--block,.tabs--block{flex-direction:column}.docItemContainer_F8PC{padding:0 .3rem}.navbarSearchContainer_Bca1{position:absolute;right:var(--ifm-navbar-padding-horizontal)}}@media (max-width:576px){.markdown h1:first-child{--ifm-h1-font-size:2rem}.markdown>h2{--ifm-h2-font-size:1.5rem}.markdown>h3{--ifm-h3-font-size:1.25rem}}@media (hover:hover){.backToTopButton_sjWU:hover{background-color:var(--ifm-color-emphasis-300)}.aa-TouchOnly{display:none}}@media (hover:none) and (pointer:coarse){:root{--aa-spacing-factor:1.2;--aa-action-icon-size:22px}.aa-LoadingIndicator,.aa-SubmitButton{padding-left:3px;padding-left:calc(var(--aa-spacing-half)/ 2 - 1px);width:39px;width:calc(var(--aa-icon-size) + var(--aa-spacing)*1.25 - 1px)}.aa-ClearButton{padding:0 10.16672px;padding:0 calc(var(--aa-spacing)*.66667 - .5px)}.aa-ItemActionButton:focus svg,.aa-ItemActionButton:hover svg{color:inherit}.aa-DesktopOnly{display:none}}@media (pointer:fine){.thin-scrollbar{scrollbar-width:thin}.thin-scrollbar::-webkit-scrollbar{height:var(--ifm-scrollbar-size);width:var(--ifm-scrollbar-size)}.thin-scrollbar::-webkit-scrollbar-track{background:var(--ifm-scrollbar-track-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb{background:var(--ifm-scrollbar-thumb-background-color);border-radius:10px}.thin-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--ifm-scrollbar-thumb-hover-background-color)}}@media (prefers-reduced-motion:reduce){:root{--ifm-transition-fast:0ms;--ifm-transition-slow:0ms}}@media screen and (prefers-reduced-motion){.aa-Panel{transition:none}}@media print{.announcementBar_mb4j,.footer,.menu,.navbar,.pagination-nav,.table-of-contents,.tocMobile_ITEo{display:none}.tabs{page-break-inside:avoid}.codeBlockLines_e6Vv{white-space:pre-wrap}} \ No newline at end of file diff --git a/pr-preview/pr-976/assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg b/pr-preview/pr-976/assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg new file mode 100644 index 0000000000..f76b674710 --- /dev/null +++ b/pr-preview/pr-976/assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg @@ -0,0 +1,1127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg b/pr-preview/pr-976/assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg new file mode 100644 index 0000000000..4149941117 --- /dev/null +++ b/pr-preview/pr-976/assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg @@ -0,0 +1,1737 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg b/pr-preview/pr-976/assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg new file mode 100644 index 0000000000..7e291b4696 --- /dev/null +++ b/pr-preview/pr-976/assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg @@ -0,0 +1,1417 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/assets/images/components-dd64f006e7d6b6facb9eb16f1af59d39.svg b/pr-preview/pr-976/assets/images/components-dd64f006e7d6b6facb9eb16f1af59d39.svg new file mode 100644 index 0000000000..33f1df4223 --- /dev/null +++ b/pr-preview/pr-976/assets/images/components-dd64f006e7d6b6facb9eb16f1af59d39.svg @@ -0,0 +1,798 @@ + + diff --git a/pr-preview/pr-976/assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg b/pr-preview/pr-976/assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg new file mode 100644 index 0000000000..bd65c768ef --- /dev/null +++ b/pr-preview/pr-976/assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg @@ -0,0 +1,766 @@ + + diff --git a/pr-preview/pr-976/assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg b/pr-preview/pr-976/assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg new file mode 100644 index 0000000000..af04ecafab --- /dev/null +++ b/pr-preview/pr-976/assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg b/pr-preview/pr-976/assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg new file mode 100644 index 0000000000..386d2215c2 --- /dev/null +++ b/pr-preview/pr-976/assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg @@ -0,0 +1,4 @@ + + + +
Root CA








Root CA Certificate
Root CA
Private Key
Intermediate CA








Intermediate CA
Certificate
Intermediate CA
Private Key
Mesh CA
Certificate
Mesh








Mesh Certificate
Mesh Private Key
signs
signs
signs
signs
diff --git a/pr-preview/pr-976/assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png b/pr-preview/pr-976/assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png new file mode 100644 index 0000000000000000000000000000000000000000..9779306e0484110339fcb14b98c8d4bf15cfabc8 GIT binary patch literal 269322 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 + diff --git a/pr-preview/pr-976/assets/images/personas-1c9f2b217e0b94e0c3057df96d96b3f0.svg b/pr-preview/pr-976/assets/images/personas-1c9f2b217e0b94e0c3057df96d96b3f0.svg new file mode 100644 index 0000000000..19988f631c --- /dev/null +++ b/pr-preview/pr-976/assets/images/personas-1c9f2b217e0b94e0c3057df96d96b3f0.svg @@ -0,0 +1,573 @@ + + diff --git a/pr-preview/pr-976/assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg b/pr-preview/pr-976/assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg new file mode 100644 index 0000000000..b13d79e3ae --- /dev/null +++ b/pr-preview/pr-976/assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg @@ -0,0 +1,1376 @@ + + diff --git a/pr-preview/pr-976/assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg b/pr-preview/pr-976/assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg new file mode 100644 index 0000000000..b20ac5284c --- /dev/null +++ b/pr-preview/pr-976/assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg @@ -0,0 +1,547 @@ + + diff --git a/pr-preview/pr-976/assets/js/014daffb.28613203.js b/pr-preview/pr-976/assets/js/014daffb.28613203.js new file mode 100644 index 0000000000..6d4ca3dfd9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/014daffb.28613203.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1955],{89204:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","source":"@site/docs/architecture/secrets.md","sourceDirName":"architecture","slug":"/architecture/secrets","permalink":"/contrast/pr-preview/pr-976/next/architecture/secrets","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/architecture/secrets.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/next/architecture/attestation"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/next/architecture/certificates"}}');var r=s(74848),i=s(28453);const o={},a="Secrets & recovery",c={},d=[{value:"Persistence",id:"persistence",level:2},{value:"Recovery",id:"recovery",level:2},{value:"Workload Secrets",id:"workload-secrets",level:2},{value:"Secure persistence",id:"secure-persistence",level:3}];function h(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"secrets--recovery",children:"Secrets & recovery"})}),"\n",(0,r.jsx)(t.p,{children:"When the Coordinator is configured with the initial manifest, it generates a random secret seed.\nFrom this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history.\nThis derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state."}),"\n",(0,r.jsxs)(t.p,{children:["The secret seed is returned to the user on the first call to ",(0,r.jsx)(t.code,{children:"contrast set"}),", encrypted with the user's public seed share owner key.\nIf no seed share owner key is provided, a key is generated and stored in the working directory."]}),"\n",(0,r.jsx)(t.h2,{id:"persistence",children:"Persistence"}),"\n",(0,r.jsxs)(t.p,{children:["The Coordinator runs as a ",(0,r.jsx)(t.code,{children:"StatefulSet"})," with a dynamically provisioned persistent volume.\nThis volume stores the manifest history and the associated runtime policies.\nThe manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads.\nHowever, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users.\nThus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed."]}),"\n",(0,r.jsx)(t.h2,{id:"recovery",children:"Recovery"}),"\n",(0,r.jsxs)(t.p,{children:["When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests.\nIt needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures.\nThis procedure is called recovery and is initiated by the workload owner.\nThe CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the ",(0,r.jsx)(t.code,{children:"Recover"})," method.\nThe Coordinator recovers its key material and verifies the manifest history signature."]}),"\n",(0,r.jsx)(t.h2,{id:"workload-secrets",children:"Workload Secrets"}),"\n",(0,r.jsxs)(t.p,{children:["The Coordinator provides each workload a secret seed during attestation.\nThis secret can be used by the workload to derive additional secrets for example to encrypt persistent data.\nLike the workload certificates, it's written to the ",(0,r.jsx)(t.code,{children:"secrets/workload-secret-seed"})," path under the shared Kubernetes volume ",(0,r.jsx)(t.code,{children:"contrast-secrets"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsx)(t.p,{children:"The workload owner can decrypt data encrypted with secrets derived from the workload secret.\nThe workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner.\nIf the data owner and the workload owner is the same entity, then they can safely use the workload secrets."})}),"\n",(0,r.jsx)(t.h3,{id:"secure-persistence",children:"Secure persistence"}),"\n",(0,r.jsx)(t.p,{children:"Remember that persistent volumes from the cloud provider are untrusted.\nUsing the workload secret, applications can set up trusted storage on top of untrusted block devices.\nThe following, slightly abbreviated resource outlines how this could be realized:"}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsx)(t.p,{children:"This configuration snippet is intended to be educational and needs to be refined and adapted to your production environment.\nUsing it as-is may result in data corruption or data loss."})}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:"apiVersion: apps/v1\nkind: StatefulSet\nmetadata:\n name: volume-tester\nspec:\n template:\n spec:\n containers:\n - name: main\n image: my.registry/my-image@sha256:0123...\n command:\n - /bin/sh\n - -ec\n - | # <-- Custom script that mounts the encrypted disk and then calls the original application.\n device=/dev/csi0\n if ! cryptsetup isLuks $device; then\n cryptsetup luksFormat $device /contrast/secrets/workload-secret-seed\n cryptsetup open $device state -d /contrast/secrets/workload-secret-seed\n mkfs.ext4 /dev/mapper/state\n cryptsetup close state\n fi\n cryptsetup open $device state -d /contrast/secrets/workload-secret-seed\n /path/to/original/app\n name: volume-tester\n volumeDevices:\n - name: state\n devicePath: /dev/csi0\n securityContext:\n privileged: true # <-- This is necessary for mounting devices.\n runtimeClassName: contrast-cc\n volumeClaimTemplates:\n - apiVersion: v1\n kind: PersistentVolumeClaim\n metadata:\n name: state\n spec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 1Gi\n volumeMode: Block # <-- The requested volume needs to be a raw block device.\n"})}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["This example assumes that you can modify the container image to include a shell and the ",(0,r.jsx)(t.code,{children:"cryptsetup"})," utility.\nAlternatively, you can set up a secure mount from a sidecar container inside an ",(0,r.jsx)(t.code,{children:"emptyDir"})," mount shared with the main container.\nThe Contrast end-to-end tests include ",(0,r.jsx)(t.a,{href:"https://github.com/edgelesssys/contrast/blob/0662a2e/internal/kuberesource/sets.go#L504",children:"an example"})," of this type of mount."]})})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var n=s(96540);const r={},i=n.createContext(r);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/018595b3.560dae8b.js b/pr-preview/pr-976/assets/js/018595b3.560dae8b.js new file mode 100644 index 0000000000..4f5541a042 --- /dev/null +++ b/pr-preview/pr-976/assets/js/018595b3.560dae8b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3876],{67766:(e,t,n)=>{n.d(t,{A:()=>b});var r=n(96540),s=n(34164),o=n(85246),i=n(57880),c=n(25792);const l=["zero","one","two","few","many","other"];function a(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function j(e){let{href:t,children:n}=e;return(0,g.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:r,children:[n," ",r]}),o&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function C(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(y,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,g.jsx)(b,{items:n.items,className:t})}function b(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(C,{item:e})},t)))})}},59763:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>m,frontMatter:()=>c,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"examples/index","title":"Examples","description":"","source":"@site/versioned_docs/version-0.5/examples/index.md","sourceDirName":"examples","slug":"/examples/","permalink":"/contrast/pr-preview/pr-976/0.5/examples/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/examples/index.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"First steps","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto"}}');var s=n(74848),o=n(28453),i=n(67766);const c={},l="Examples",a={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n","\n",(0,s.jsx)(i.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/04102e85.745c04f7.js b/pr-preview/pr-976/assets/js/04102e85.745c04f7.js new file mode 100644 index 0000000000..74297c7542 --- /dev/null +++ b/pr-preview/pr-976/assets/js/04102e85.745c04f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1158],{30612:(t,e,r)=>{r.r(e),r.d(e,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/attestation/hardware","title":"hardware","description":"","source":"@site/versioned_docs/version-0.5/architecture/attestation/hardware.md","sourceDirName":"architecture/attestation","slug":"/architecture/attestation/hardware","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/attestation/hardware.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.5/category/attestation"},"next":{"title":"Pod VM","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm"}}');var a=r(74848),o=r(28453);const s={},c=void 0,i={},d=[];function u(t){return(0,a.jsx)(a.Fragment,{})}function p(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,a.jsx)(e,{...t,children:(0,a.jsx)(u,{...t})}):u()}},28453:(t,e,r)=>{r.d(e,{R:()=>s,x:()=>c});var n=r(96540);const a={},o=n.createContext(a);function s(t){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(a):t.components||a:s(t.components),n.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/06354bbe.4db69232.js b/pr-preview/pr-976/assets/js/06354bbe.4db69232.js new file mode 100644 index 0000000000..f441735fc3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/06354bbe.4db69232.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8204],{18733:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-0.9/components/overview.md","sourceDirName":"components","slug":"/components/overview","permalink":"/contrast/pr-preview/pr-976/0.9/components/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/components/overview.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.9/troubleshooting"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.9/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},l=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(77998).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},77998:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/06eada7a.0ffd2db0.js b/pr-preview/pr-976/assets/js/06eada7a.0ffd2db0.js new file mode 100644 index 0000000000..8d720f0244 --- /dev/null +++ b/pr-preview/pr-976/assets/js/06eada7a.0ffd2db0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6470],{28601:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-0.7/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/0.7/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/components/policies.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.7/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.7/components/service-mesh"}}');var s=n(74848),o=n(28453);const r={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/078f57bf.b2f92c81.js b/pr-preview/pr-976/assets/js/078f57bf.b2f92c81.js new file mode 100644 index 0000000000..0bcd5a458a --- /dev/null +++ b/pr-preview/pr-976/assets/js/078f57bf.b2f92c81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1690],{30569:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/versioned_docs/version-0.9/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/architecture/observability.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/certificates"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.9/features-limitations"}}');var s=r(74848),i=r(28453);const o={},c="Observability",a={},d=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function h(e){const t={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator exports gRPC metrics under the prefix ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_"}),".\nThese metrics are labeled with the gRPC service name and method name.\nMetrics of interest include ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handled_total"}),", which counts\nthe number of requests by return code, and\n",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handling_seconds_bucket"}),", which produces a histogram of",(0,s.jsx)(t.br,{}),"\n","request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["The gRPC service ",(0,s.jsx)(t.code,{children:"userapi.UserAPI"})," records metrics for the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"meshapi.MeshAPI"})," service records metrics for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"}),", which\ngets called by the ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures_total"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>c});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/098bf236.fb47b956.js b/pr-preview/pr-976/assets/js/098bf236.fb47b956.js new file mode 100644 index 0000000000..87f34b072a --- /dev/null +++ b/pr-preview/pr-976/assets/js/098bf236.fb47b956.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8259],{32284:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-0.8/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/0.8/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/intro.md","tags":[],"version":"0.8","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/getting-started/install",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0a09f1f2.af458bba.js b/pr-preview/pr-976/assets/js/0a09f1f2.af458bba.js new file mode 100644 index 0000000000..e0a78bd846 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0a09f1f2.af458bba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7e3],{35787:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-1.1/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/deployment.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/examples/emojivoto"},"next":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/troubleshooting"}}');var r=t(74848),a=t(28453);const i={},o="Workload deployment",l={},c=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"Security review",id:"security-review",level:3},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2},{value:"Recover the Coordinator",id:"recover-the-coordinator",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components},{TabItem:t,Tabs:s}=n;return t||u("TabItem",!0),s||u("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,r.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/getting-started/cluster-setup",children:"setup guide"})," on how to set up a cluster on AKS."]})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/getting-started/bare-metal",children:"setup guide"})," on how to set up a bare-metal cluster."]})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/getting-started/bare-metal",children:"setup guide"})," on how to set up a bare-metal cluster."]})})]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,r.jsxs)(n.p,{children:["Contrast depends on a ",(0,r.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:["custom Kubernetes ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," (",(0,r.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,r.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-aks-clh-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-k3s-qemu-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-aks-clh-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-k3s-qemu-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,r.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,r.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,r.jsx)(n.h3,{id:"security-review",children:"Security review"}),"\n",(0,r.jsxs)(n.p,{children:["Contrast ensures integrity and confidentiality of the applications, but interactions with untrusted systems require the developers' attention.\nReview the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/security-considerations",children:"security considerations"})," and the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates",children:"certificates"})," section for writing secure Contrast application."]}),"\n",(0,r.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,r.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,r.jsxs)(s,{groupId:"yaml-source",children:[(0,r.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"helm",label:"helm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"copy",label:"copy",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,r.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,r.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,r.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,r.jsxs)(n.p,{children:["In the initialization process, the ",(0,r.jsx)(n.code,{children:"contrast-secrets"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,r.jsxs)(s,{groupId:"tls",children:[(0,r.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,r.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,r.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,r.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,r.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,r.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,r.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,r.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,r.jsxs)(n.p,{children:["During the ",(0,r.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,r.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,r.jsxs)(t,{value:"go",label:"Go integration",children:[(0,r.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,r.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,r.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,r.jsxs)(s,{groupId:"golang-tls-setup",children:[(0,r.jsx)(t,{value:"client",label:"Client",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,r.jsx)(t,{value:"server",label:"Server",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,r.jsxs)(n.p,{children:["Run the ",(0,r.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,r.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp resources/\n"})})}),(0,r.jsxs)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp resources/\n"})}),(0,r.jsx)(n.admonition,{title:"Missing TCB values",type:"note",children:(0,r.jsxs)(n.p,{children:["On bare-metal SEV-SNP, ",(0,r.jsx)(n.code,{children:"contrast generate"})," is unable to fill in the ",(0,r.jsx)(n.code,{children:"MinimumTCB"})," values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,r.jsx)(n.code,{children:'{"BootloaderVersion":255,"TEEVersion":255,"SNPVersion":255,"MicrocodeVersion":255}'})," and observe the real values in the error messages in the following steps. This should only be done in a secure environment. Note that the values will differ between CPU models."]})})]}),(0,r.jsxs)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx resources/\n"})}),(0,r.jsx)(n.admonition,{title:"Missing TCB values",type:"note",children:(0,r.jsxs)(n.p,{children:["On bare-metal TDX, ",(0,r.jsx)(n.code,{children:"contrast generate"})," is unable to fill in the ",(0,r.jsx)(n.code,{children:"MinimumTeeTcbSvn"})," and ",(0,r.jsx)(n.code,{children:"MrSeam"})," TCB values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,r.jsx)(n.code,{children:"ffffffffffffffffffffffffffffffff"})," and ",(0,r.jsx)(n.code,{children:"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"})," respectively and observe the real values in the error messages in the following steps. This should only be done in a secure environment."]})})]})]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,r.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,r.jsxs)(s,{groupId:"injection",children:[(0,r.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,r.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,r.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,r.jsx)(n.code,{children:"generate"})," command."]}),(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp --skip-initializer resources/\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp --skip-initializer resources/\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx --skip-initializer resources/\n"})})})]})]}),(0,r.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,r.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,r.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,r.jsx)(n.code,{children:"contrast-secrets"})," ",(0,r.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:v1.1.0@sha256:af86d81dd673338321d655af966557faa00d354a08885b353be27462e6ffb0f1"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /contrast\n name: contrast-secrets\n volumes:\n - emptyDir: {}\n name: contrast-secrets\n'})}),"\n",(0,r.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,r.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,r.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,r.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,r.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,r.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,r.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,r.jsx)(n.p,{children:"This will use the reference values from the manifest file to attest the Coordinator.\nAfter this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,r.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,r.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the\nservice mesh root certificate and the history of manifests into the ",(0,r.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies\nreferenced in the active manifest are also written to the directory. The verification will fail if the active\nmanifest at the Coordinator doesn't match the manifest passed to the CLI."]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,r.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,r.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Using ",(0,r.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,r.jsx)(n.h2,{id:"recover-the-coordinator",children:"Recover the Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material.\nFor demonstration purposes, you can simulate this scenario by deleting the Coordinator pod."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl delete pod -l app.kubernetes.io/name=coordinator\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet.\nYou can confirm this by running ",(0,r.jsx)(n.code,{children:"verify"})," again, or you can restart a workload pod, which should stay in the initialization phase.\nHowever, the secret seed in your working directory is sufficient to recover the coordinator."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast recover -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsx)(n.p,{children:"Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state.\nYou can now verify the Coordinator again, which should return the same manifest you set before."}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The recovery process invalidates the mesh CA certificate:\nexisting workloads won't be able to communicate with workloads newly spawned.\nAll workloads should be restarted after the recovery succeeded."})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0a7a212e.4bfb0b6f.js b/pr-preview/pr-976/assets/js/0a7a212e.4bfb0b6f.js new file mode 100644 index 0000000000..c8b2dd1096 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0a7a212e.4bfb0b6f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3702],{4949:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-0.8/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/basics/confidential-containers.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"What is Contrast?","permalink":"/contrast/pr-preview/pr-976/0.8/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.8/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0b1c872d.c7834956.js b/pr-preview/pr-976/assets/js/0b1c872d.c7834956.js new file mode 100644 index 0000000000..8b32e8e555 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0b1c872d.c7834956.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3188],{25776:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-1.1/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/components/policies.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/components/service-mesh"}}');var s=n(74848),r=n(28453);const o={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2},{value:"Platform Differences",id:"platform-differences",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," or TDX ",(0,s.jsx)(t.code,{children:"MRCONFIGID"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," or ",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."}),"\n",(0,s.jsx)(t.h2,{id:"platform-differences",children:"Platform Differences"}),"\n",(0,s.jsx)(t.p,{children:"Contrast uses different rules and data sections for different platforms.\nThis results in different policy hashes for different platforms."}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"generate"})," command automatically derives the correct set of rules and data sections from the ",(0,s.jsx)(t.code,{children:"reference-values"})," flag."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"verify"}),", ",(0,s.jsx)(t.code,{children:"set"}),", and ",(0,s.jsx)(t.code,{children:"recover"})," commands need to know the coordinator's expected policy hash to verify its identity.\nBy default these commands assume that the coordinator is using the policy for the ",(0,s.jsx)(t.code,{children:"AKS-CLH-SNP"})," platform.\nIf the coordinator is running on a different platform, the correct policy hash can be looked up in the ",(0,s.jsx)(t.code,{children:"coordinator-policy.hash"})," file bundled with the ",(0,s.jsx)(t.a,{href:"https://github.com/edgelesssys/contrast/releases",children:"Contrast release"}),".\nThe coordinator policy hash can be overwritten using the ",(0,s.jsx)(t.code,{children:"--coordinator-policy-hash"})," flag."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0ba7602a.85a7f1d2.js b/pr-preview/pr-976/assets/js/0ba7602a.85a7f1d2.js new file mode 100644 index 0000000000..94a5f1fef3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0ba7602a.85a7f1d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7368],{37154:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/versioned_docs/version-0.9/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/0.9/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/features-limitations.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/observability"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/0.9/about/telemetry"}}');var r=t(74848),s=t(28453);const o={},a="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2},{value:"Automatic recovery and high availability",id:"automatic-recovery-and-high-availability",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,r.jsx)(n.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,r.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,r.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Bare-metal support"}),": Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Persistent volumes"}),": Contrast only supports volumes with ",(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode",children:(0,r.jsx)(n.code,{children:"volumeMode: Block"})}),". These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Port forwarding"}),": This feature ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,r.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,r.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,r.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,r.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,r.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,r.jsx)(n.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"automatic-recovery-and-high-availability",children:"Automatic recovery and high availability"}),"\n",(0,r.jsx)(n.p,{children:"The Contrast Coordinator is a singleton and can't be scaled to more than one instance.\nWhen this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually.\nIn a future release, we plan to support distributed Coordinator instances that can recover automatically."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0c24bc66.085b04d6.js b/pr-preview/pr-976/assets/js/0c24bc66.085b04d6.js new file mode 100644 index 0000000000..5df1b3a6f2 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0c24bc66.085b04d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6739],{73521:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-0.6/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/basics/security-benefits.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.6/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(34696).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(95662).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},95662:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-1c9f2b217e0b94e0c3057df96d96b3f0.svg"},34696:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/0e384e19.651e3adc.js b/pr-preview/pr-976/assets/js/0e384e19.651e3adc.js new file mode 100644 index 0000000000..31db189a96 --- /dev/null +++ b/pr-preview/pr-976/assets/js/0e384e19.651e3adc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3976],{73700:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/docs/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/next/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/intro.md","tags":[],"version":"current","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/next/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/install",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/10257d90.7ee2f98c.js b/pr-preview/pr-976/assets/js/10257d90.7ee2f98c.js new file mode 100644 index 0000000000..89c44e4421 --- /dev/null +++ b/pr-preview/pr-976/assets/js/10257d90.7ee2f98c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3477],{45013:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-1.1/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/basics/security-benefits.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(94074).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(72168).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},72168:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},94074:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1057c3b3.114828df.js b/pr-preview/pr-976/assets/js/1057c3b3.114828df.js new file mode 100644 index 0000000000..de760baa0a --- /dev/null +++ b/pr-preview/pr-976/assets/js/1057c3b3.114828df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5811],{26033:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-1.1/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/basics/confidential-containers.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"What is Contrast?","permalink":"/contrast/pr-preview/pr-976/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1186.8726fdba.js b/pr-preview/pr-976/assets/js/1186.8726fdba.js new file mode 100644 index 0000000000..25f91eb5a4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/1186.8726fdba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1186],{86022:(t,e,a)=>{function r(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}a.d(e,{S:()=>r}),(0,a(45567).K2)(r,"populateCommonDb")},51186:(t,e,a)=>{a.d(e,{diagram:()=>x});var r=a(86022),n=a(85039),o=a(61021),l=a(45567),c=a(78731),i={packet:[]},s=structuredClone(i),d=l.UI.packet,k=(0,l.K2)((()=>{const t=(0,n.$t)({...d,...(0,l.zj)().packet});return t.showBits&&(t.paddingY+=10),t}),"getConfig"),p=(0,l.K2)((()=>s.packet),"getPacket"),b={pushWord:(0,l.K2)((t=>{t.length>0&&s.packet.push(t)}),"pushWord"),getPacket:p,getConfig:k,clear:(0,l.K2)((()=>{(0,l.IU)(),s=structuredClone(i)}),"clear"),setAccTitle:l.SV,getAccTitle:l.iN,setDiagramTitle:l.ke,getDiagramTitle:l.ab,getAccDescription:l.m7,setAccDescription:l.EI},g=(0,l.K2)((t=>{(0,r.S)(t,b);let e=-1,a=[],n=1;const{bitsPerRow:o}=b.getConfig();for(let{start:r,end:c,label:i}of t.blocks){if(c&&c{if(void 0===t.end&&(t.end=t.start),t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);return t.end+1<=e*a?[t,void 0]:[{start:t.start,end:e*a-1,label:t.label},{start:e*a,end:t.end,label:t.label}]}),"getNextFittingBlock"),f={parse:(0,l.K2)((async t=>{const e=await(0,c.qg)("packet",t);l.Rm.debug(e),g(e)}),"parse")},u=(0,l.K2)(((t,e,a,r)=>{const n=r.db,c=n.getConfig(),{rowHeight:i,paddingY:s,bitWidth:d,bitsPerRow:k}=c,p=n.getPacket(),b=n.getDiagramTitle(),g=i+s,h=g*(p.length+1)-(b?0:i),f=d*k+2,u=(0,o.D)(e);u.attr("viewbox",`0 0 ${f} ${h}`),(0,l.a$)(u,h,f,c.useMaxWidth);for(const[o,l]of p.entries())$(u,l,o,c);u.append("text").text(b).attr("x",f/2).attr("y",h-g/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")}),"draw"),$=(0,l.K2)(((t,e,a,{rowHeight:r,paddingX:n,paddingY:o,bitWidth:l,bitsPerRow:c,showBits:i})=>{const s=t.append("g"),d=a*(r+o)+o;for(const k of e){const t=k.start%c*l+1,e=(k.end-k.start+1)*l-n;if(s.append("rect").attr("x",t).attr("y",d).attr("width",e).attr("height",r).attr("class","packetBlock"),s.append("text").attr("x",t+e/2).attr("y",d+r/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(k.label),!i)continue;const a=k.end===k.start,o=d-2;s.append("text").attr("x",t+(a?e/2:0)).attr("y",o).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",a?"middle":"start").text(k.start),a||s.append("text").attr("x",t+e).attr("y",o).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(k.end)}}),"drawWord"),w={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},x={parser:f,db:b,renderer:{draw:u},styles:(0,l.K2)((({packet:t}={})=>{const e=(0,n.$t)(w,t);return`\n\t.packetByte {\n\t\tfont-size: ${e.byteFontSize};\n\t}\n\t.packetByte.start {\n\t\tfill: ${e.startByteColor};\n\t}\n\t.packetByte.end {\n\t\tfill: ${e.endByteColor};\n\t}\n\t.packetLabel {\n\t\tfill: ${e.labelColor};\n\t\tfont-size: ${e.labelFontSize};\n\t}\n\t.packetTitle {\n\t\tfill: ${e.titleColor};\n\t\tfont-size: ${e.titleFontSize};\n\t}\n\t.packetBlock {\n\t\tstroke: ${e.blockStrokeColor};\n\t\tstroke-width: ${e.blockStrokeWidth};\n\t\tfill: ${e.blockFillColor};\n\t}\n\t`}),"styles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/137fbf80.8c6cd314.js b/pr-preview/pr-976/assets/js/137fbf80.8c6cd314.js new file mode 100644 index 0000000000..057d999cf1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/137fbf80.8c6cd314.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7664],{97086:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"0.8","label":"0.8","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.8","isLast":false,"docsSidebars":{"docs":[{"type":"link","label":"What is Contrast?","href":"/contrast/pr-preview/pr-976/0.8/","docId":"intro","unlisted":false},{"type":"category","label":"Basics","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/0.8/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/0.8/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/0.8/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false}],"collapsible":true},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/0.8/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/0.8/deployment","docId":"deployment","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/contrast/pr-preview/pr-976/0.8/troubleshooting","docId":"troubleshooting","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Overview","href":"/contrast/pr-preview/pr-976/0.8/components/overview","docId":"components/overview","unlisted":false},{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/0.8/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/0.8/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/0.8/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/0.8/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Secrets & recovery","href":"/contrast/pr-preview/pr-976/0.8/architecture/secrets","docId":"architecture/secrets","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/0.8/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/0.8/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/0.8/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/0.8/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true}]},"docs":{"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"architecture/secrets":{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/overview":{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"troubleshooting":{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1477.b147cf3f.js b/pr-preview/pr-976/assets/js/1477.b147cf3f.js new file mode 100644 index 0000000000..289c7e6b3a --- /dev/null +++ b/pr-preview/pr-976/assets/js/1477.b147cf3f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1477],{50053:(e,n,t)=>{t.d(n,{A:()=>i});var r=t(68675);const i=function(e){return(0,r.A)(e,4)}},81477:(e,n,t)=>{t.r(n),t.d(n,{render:()=>O});var r=t(6396),i=t(5081),a=(t(34483),t(52294),t(62392)),o=(t(86825),t(85039),t(45567)),d=t(62334),s=t(69592),c=t(50053),g=t(74722);t(37981);function l(e){var n={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:f(e),edges:h(e)};return s.A(e.graph())||(n.value=c.A(e.graph())),n}function f(e){return g.A(e.nodes(),(function(n){var t=e.node(n),r=e.parent(n),i={v:n};return s.A(t)||(i.value=t),s.A(r)||(i.parent=r),i}))}function h(e){return g.A(e.edges(),(function(n){var t=e.edge(n),r={v:n.v,w:n.w};return s.A(n.name)||(r.name=n.name),s.A(t)||(r.value=t),r}))}var u=t(697),p=new Map,m=new Map,w=new Map,R=(0,o.K2)((()=>{m.clear(),w.clear(),p.clear()}),"clear"),v=(0,o.K2)(((e,n)=>{const t=m.get(n)||[];return o.Rm.trace("In isDescendant",n," ",e," = ",t.includes(e)),t.includes(e)}),"isDescendant"),y=(0,o.K2)(((e,n)=>{const t=m.get(n)||[];return o.Rm.info("Descendants of ",n," is ",t),o.Rm.info("Edge is ",e),e.v!==n&&e.w!==n&&(t?t.includes(e.v)||v(e.v,n)||v(e.w,n)||t.includes(e.w):(o.Rm.debug("Tilt, ",n,",not in descendants"),!1))}),"edgeInCluster"),X=(0,o.K2)(((e,n,t,r)=>{o.Rm.warn("Copying children of ",e,"root",r,"data",n.node(e),r);const i=n.children(e)||[];e!==r&&i.push(e),o.Rm.warn("Copying (nodes) clusterId",e,"nodes",i),i.forEach((i=>{if(n.children(i).length>0)X(i,n,t,r);else{const a=n.node(i);o.Rm.info("cp ",i," to ",r," with parent ",e),t.setNode(i,a),r!==n.parent(i)&&(o.Rm.warn("Setting parent",i,n.parent(i)),t.setParent(i,n.parent(i))),e!==r&&i!==e?(o.Rm.debug("Setting parent",i,e),t.setParent(i,e)):(o.Rm.info("In copy ",e,"root",r,"data",n.node(e),r),o.Rm.debug("Not Setting parent for node=",i,"cluster!==rootId",e!==r,"node!==clusterId",i!==e));const d=n.edges(i);o.Rm.debug("Copying Edges",d),d.forEach((i=>{o.Rm.info("Edge",i);const a=n.edge(i.v,i.w,i.name);o.Rm.info("Edge data",a,r);try{y(i,r)?(o.Rm.info("Copying as ",i.v,i.w,a,i.name),t.setEdge(i.v,i.w,a,i.name),o.Rm.info("newGraph edges ",t.edges(),t.edge(t.edges()[0]))):o.Rm.info("Skipping copy of edge ",i.v,"--\x3e",i.w," rootId: ",r," clusterId:",e)}catch(d){o.Rm.error(d)}}))}o.Rm.debug("Removing node",i),n.removeNode(i)}))}),"copy"),b=(0,o.K2)(((e,n)=>{const t=n.children(e);let r=[...t];for(const i of t)w.set(i,e),r=[...r,...b(i,n)];return r}),"extractDescendants"),E=(0,o.K2)(((e,n,t)=>{const r=e.edges().filter((e=>e.v===n||e.w===n)),i=e.edges().filter((e=>e.v===t||e.w===t)),a=r.map((e=>({v:e.v===n?t:e.v,w:e.w===n?n:e.w}))),o=i.map((e=>({v:e.v,w:e.w})));return a.filter((e=>o.some((n=>e.v===n.v&&e.w===n.w))))}),"findCommonEdges"),N=(0,o.K2)(((e,n,t)=>{const r=n.children(e);if(o.Rm.trace("Searching children of id ",e,r),r.length<1)return e;let i;for(const a of r){const e=N(a,n,t),r=E(n,t,e);if(e){if(!(r.length>0))return e;i=e}}return i}),"findNonClusterChild"),C=(0,o.K2)((e=>p.has(e)&&p.get(e).externalConnections&&p.has(e)?p.get(e).id:e),"getAnchorId"),x=(0,o.K2)(((e,n)=>{if(!e||n>10)o.Rm.debug("Opting out, no graph ");else{o.Rm.debug("Opting in, graph "),e.nodes().forEach((function(n){e.children(n).length>0&&(o.Rm.warn("Cluster identified",n," Replacement id in edges: ",N(n,e,n)),m.set(n,b(n,e)),p.set(n,{id:N(n,e,n),clusterData:e.node(n)}))})),e.nodes().forEach((function(n){const t=e.children(n),r=e.edges();t.length>0?(o.Rm.debug("Cluster identified",n,m),r.forEach((e=>{v(e.v,n)^v(e.w,n)&&(o.Rm.warn("Edge: ",e," leaves cluster ",n),o.Rm.warn("Descendants of XXX ",n,": ",m.get(n)),p.get(n).externalConnections=!0)}))):o.Rm.debug("Not a cluster ",n,m)}));for(let n of p.keys()){const t=p.get(n).id,r=e.parent(t);r!==n&&p.has(r)&&!p.get(r).externalConnections&&(p.get(n).id=r)}e.edges().forEach((function(n){const t=e.edge(n);o.Rm.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),o.Rm.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let r=n.v,i=n.w;if(o.Rm.warn("Fix XXX",p,"ids:",n.v,n.w,"Translating: ",p.get(n.v)," --- ",p.get(n.w)),p.get(n.v)||p.get(n.w)){if(o.Rm.warn("Fixing and trying - removing XXX",n.v,n.w,n.name),r=C(n.v),i=C(n.w),e.removeEdge(n.v,n.w,n.name),r!==n.v){const i=e.parent(r);p.get(i).externalConnections=!0,t.fromCluster=n.v}if(i!==n.w){const r=e.parent(i);p.get(r).externalConnections=!0,t.toCluster=n.w}o.Rm.warn("Fix Replacing with XXX",r,i,n.name),e.setEdge(r,i,t,n.name)}})),o.Rm.warn("Adjusted Graph",l(e)),I(e,0),o.Rm.trace(p)}}),"adjustClustersAndEdges"),I=(0,o.K2)(((e,n)=>{if(o.Rm.warn("extractor - ",n,l(e),e.children("D")),n>10)return void o.Rm.error("Bailing out");let t=e.nodes(),r=!1;for(const i of t){const n=e.children(i);r=r||n.length>0}if(r){o.Rm.debug("Nodes = ",t,n);for(const r of t)if(o.Rm.debug("Extracting node",r,p,p.has(r)&&!p.get(r).externalConnections,!e.parent(r),e.node(r),e.children("D")," Depth ",n),p.has(r))if(!p.get(r).externalConnections&&e.children(r)&&e.children(r).length>0){o.Rm.warn("Cluster without external connections, without a parent and with children",r,n);let t="TB"===e.graph().rankdir?"LR":"TB";p.get(r)?.clusterData?.dir&&(t=p.get(r).clusterData.dir,o.Rm.warn("Fixing dir",p.get(r).clusterData.dir,t));const i=new u.T({multigraph:!0,compound:!0}).setGraph({rankdir:t,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}}));o.Rm.warn("Old graph before copy",l(e)),X(r,e,i,r),e.setNode(r,{clusterNode:!0,id:r,clusterData:p.get(r).clusterData,label:p.get(r).label,graph:i}),o.Rm.warn("New graph after copy node: (",r,")",l(i)),o.Rm.debug("Old graph after copy",l(e))}else o.Rm.warn("Cluster ** ",r," **not meeting the criteria !externalConnections:",!p.get(r).externalConnections," no parent: ",!e.parent(r)," children ",e.children(r)&&e.children(r).length>0,e.children("D"),n),o.Rm.debug(p);else o.Rm.debug("Not a cluster",r,n);t=e.nodes(),o.Rm.warn("New list of nodes",t);for(const r of t){const t=e.node(r);o.Rm.warn(" Now next level",r,t),t?.clusterNode&&I(t.graph,n+1)}}else o.Rm.debug("Done, no node has children",e.nodes())}),"extractor"),S=(0,o.K2)(((e,n)=>{if(0===n.length)return[];let t=Object.assign([],n);return n.forEach((n=>{const r=e.children(n),i=S(e,r);t=[...t,...i]})),t}),"sorter"),D=(0,o.K2)((e=>S(e,e.children())),"sortNodesByHierarchy"),A=(0,o.K2)((async(e,n,t,s,c,g)=>{o.Rm.warn("Graph in recursive render:XAX",l(n),c);const f=n.graph().rankdir;o.Rm.trace("Dir in recursive render - dir:",f);const h=e.insert("g").attr("class","root");n.nodes()?o.Rm.info("Recursive render XXX",n.nodes()):o.Rm.info("No nodes found for",n),n.edges().length>0&&o.Rm.info("Recursive edges",n.edge(n.edges()[0]));const u=h.insert("g").attr("class","clusters"),m=h.insert("g").attr("class","edgePaths"),w=h.insert("g").attr("class","edgeLabels"),R=h.insert("g").attr("class","nodes");await Promise.all(n.nodes().map((async function(e){const r=n.node(e);if(void 0!==c){const t=JSON.parse(JSON.stringify(c.clusterData));o.Rm.trace("Setting data for parent cluster XXX\n Node.id = ",e,"\n data=",t.height,"\nParent cluster",c.height),n.setNode(c.id,t),n.parent(e)||(o.Rm.trace("Setting parent",e,c.id),n.setParent(e,c.id,t))}if(o.Rm.info("(Insert) Node XXX"+e+": "+JSON.stringify(n.node(e))),r?.clusterNode){o.Rm.info("Cluster identified XBX",e,r.width,n.node(e));const{ranksep:a,nodesep:d}=n.graph();r.graph.setGraph({...r.graph.graph(),ranksep:a+25,nodesep:d});const c=await A(R,r.graph,t,s,n.node(e),g),l=c.elem;(0,i.lC)(r,l),r.diff=c.diff||0,o.Rm.info("New compound node after recursive render XAX",e,"width",r.width,"height",r.height),(0,i.U7)(l,r)}else n.children(e).length>0?(o.Rm.trace("Cluster - the non recursive path XBX",e,r.id,r,r.width,"Graph:",n),o.Rm.trace(N(r.id,n)),p.set(r.id,{id:N(r.id,n),node:r})):(o.Rm.trace("Node - the non recursive path XAX",e,R,n.node(e),f),await(0,i.on)(R,n.node(e),{config:g,dir:f}))})));const v=(0,o.K2)((async()=>{const e=n.edges().map((async function(e){const t=n.edge(e.v,e.w,e.name);o.Rm.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),o.Rm.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(n.edge(e))),o.Rm.info("Fix",p,"ids:",e.v,e.w,"Translating: ",p.get(e.v),p.get(e.w)),await(0,r.jP)(w,t)}));await Promise.all(e)}),"processEdges");await v(),o.Rm.info("Graph before layout:",JSON.stringify(l(n))),o.Rm.info("############################################# XXX"),o.Rm.info("### Layout ### XXX"),o.Rm.info("############################################# XXX"),(0,d.Zp)(n),o.Rm.info("Graph after layout:",JSON.stringify(l(n)));let y=0,{subGraphTitleTotalMargin:X}=(0,a.O)(g);return await Promise.all(D(n).map((async function(e){const t=n.node(e);if(o.Rm.info("Position XBX => "+e+": ("+t.x,","+t.y,") width: ",t.width," height: ",t.height),t?.clusterNode)t.y+=X,o.Rm.info("A tainted cluster node XBX1",e,t.id,t.width,t.height,t.x,t.y,n.parent(e)),p.get(t.id).node=t,(0,i.U_)(t);else if(n.children(e).length>0){o.Rm.info("A pure cluster node XBX1",e,t.id,t.x,t.y,t.width,t.height,n.parent(e)),t.height+=X,n.node(t.parentId);const r=t?.padding/2||0,a=t?.labelBBox?.height||0,d=a-r||0;o.Rm.debug("OffsetY",d,"labelHeight",a,"halfPadding",r),await(0,i.U)(u,t),p.get(t.id).node=t}else{const e=n.node(t.parentId);t.y+=X/2,o.Rm.info("A regular node XBX1 - using the padding",t.id,"parent",t.parentId,t.width,t.height,t.x,t.y,"offsetY",t.offsetY,"parent",e,e?.offsetY,t),(0,i.U_)(t)}}))),n.edges().forEach((function(e){const i=n.edge(e);o.Rm.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(i),i),i.points.forEach((e=>e.y+=X/2));const a=n.node(e.v);var d=n.node(e.w);const c=(0,r.Jo)(m,i,p,t,a,d,s);(0,r.T_)(i,c)})),n.nodes().forEach((function(e){const t=n.node(e);o.Rm.info(e,t.type,t.diff),t.isGroup&&(y=t.diff)})),o.Rm.warn("Returning from recursive render XAX",h,y),{elem:h,diff:y}}),"recursiveRender"),O=(0,o.K2)((async(e,n)=>{const t=new u.T({multigraph:!0,compound:!0}).setGraph({rankdir:e.direction,nodesep:e.config?.nodeSpacing||e.config?.flowchart?.nodeSpacing||e.nodeSpacing,ranksep:e.config?.rankSpacing||e.config?.flowchart?.rankSpacing||e.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel((function(){return{}})),a=n.select("g");(0,r.g0)(a,e.markers,e.type,e.diagramId),(0,i.gh)(),(0,r.IU)(),(0,i.IU)(),R(),e.nodes.forEach((e=>{t.setNode(e.id,{...e}),e.parentId&&t.setParent(e.id,e.parentId)})),o.Rm.debug("Edges:",e.edges),e.edges.forEach((e=>{if(e.start===e.end){const n=e.start,r=n+"---"+n+"---1",i=n+"---"+n+"---2",a=t.node(n);t.setNode(r,{domId:r,id:r,parentId:a.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),t.setParent(r,a.parentId),t.setNode(i,{domId:i,id:i,parentId:a.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),t.setParent(i,a.parentId);const o=structuredClone(e),d=structuredClone(e),s=structuredClone(e);o.label="",o.arrowTypeEnd="none",o.id=n+"-cyclic-special-1",d.arrowTypeEnd="none",d.id=n+"-cyclic-special-mid",s.label="",a.isGroup&&(o.fromCluster=n,s.toCluster=n),s.id=n+"-cyclic-special-2",t.setEdge(n,r,o,n+"-cyclic-special-0"),t.setEdge(r,i,d,n+"-cyclic-special-1"),t.setEdge(i,n,s,n+"-cyc{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-0.8/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/architecture/attestation.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.8/components/service-mesh"},"next":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/secrets"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(55732).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(15601).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nOn AMD SEV-SNP the hash of the policy is then added to the attestation report via the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field by the hypervisor.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(92084).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},92084:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},15601:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},55732:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/14eb3368.8cb6f0b4.js b/pr-preview/pr-976/assets/js/14eb3368.8cb6f0b4.js new file mode 100644 index 0000000000..166dd95a53 --- /dev/null +++ b/pr-preview/pr-976/assets/js/14eb3368.8cb6f0b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6969],{14333:(e,t,n)=>{n.d(t,{A:()=>g});n(96540);var s=n(34164),r=n(74717),i=n(85246),a=n(86707),l=n(57880),o=n(32032),c=n(24763),d=n(74848);function u(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,d.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const m={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function h(){const e=(0,c.Ay)("/");return(0,d.jsx)("li",{className:"breadcrumbs__item",children:(0,d.jsx)(l.A,{"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,d.jsx)(u,{className:m.breadcrumbHomeIcon})})})}const b={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function x(e){let{children:t,href:n,isLast:s}=e;const r="breadcrumbs__link";return s?(0,d.jsx)("span",{className:r,itemProp:"name",children:t}):n?(0,d.jsx)(l.A,{className:r,href:n,itemProp:"item",children:(0,d.jsx)("span",{itemProp:"name",children:t})}):(0,d.jsx)("span",{className:r,children:t})}function p(e){let{children:t,active:n,index:r,addMicrodata:i}=e;return(0,d.jsxs)("li",{...i&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,s.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,d.jsx)("meta",{itemProp:"position",content:String(r+1)})]})}function g(){const e=(0,i.OF)(),t=(0,a.Dt)();return e?(0,d.jsx)("nav",{className:(0,s.A)(r.G.docs.docBreadcrumbs,b.breadcrumbsContainer),"aria-label":(0,o.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,d.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,d.jsx)(h,{}),e.map(((t,n)=>{const s=n===e.length-1,r="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,d.jsx)(p,{active:s,index:n,addMicrodata:!!r,children:(0,d.jsx)(x,{href:r,isLast:s,children:t.label})},n)}))]})}):null}},67766:(e,t,n)=>{n.d(t,{A:()=>_});var s=n(96540),r=n(34164),i=n(85246),a=n(57880),l=n(25792);const o=["zero","one","two","few","many","other"];function c(e){return o.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:c(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,l.A)();return(0,s.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:c(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const s=e.split("|");if(1===s.length)return s[0];s.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${s.length}: ${e}`);const r=n.select(t),i=n.pluralForms.indexOf(r);return s[Math.min(i,s.length-1)]}(n,t,e)}}var h=n(77056),b=n(32032),x=n(98445);const p={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function v(e){let{href:t,children:n}=e;return(0,g.jsx)(a.A,{href:t,className:(0,r.A)("card padding--lg",p.cardContainer),children:n})}function f(e){let{href:t,icon:n,title:s,description:i}=e;return(0,g.jsxs)(v,{href:t,children:[(0,g.jsxs)(x.A,{as:"h2",className:(0,r.A)("text--truncate",p.cardTitle),title:s,children:[n," ",s]}),i&&(0,g.jsx)("p",{className:(0,r.A)("text--truncate",p.cardDescription),title:i,children:i})]})}function j(e){let{item:t}=e;const n=(0,i.Nr)(t),s=function(){const{selectMessage:e}=m();return t=>e(t,(0,b.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(f,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??s(t.items.length)}):null}function A(e){let{item:t}=e;const n=(0,h.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",s=(0,i.cC)(t.docId??void 0);return(0,g.jsx)(f,{href:t.href,icon:n,title:t.label,description:t.description??s?.description})}function N(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(A,{item:t});case"category":return(0,g.jsx)(j,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function T(e){let{className:t}=e;const n=(0,i.$S)();return(0,g.jsx)(_,{items:n.items,className:t})}function _(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(T,{...e});const s=(0,i.d1)(t);return(0,g.jsx)("section",{className:(0,r.A)("row",n),children:s.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(N,{item:e})},t)))})}},6893:(e,t,n)=>{n.r(t),n.d(t,{default:()=>p});n(96540);var s=n(63523),r=n(85246),i=n(24763),a=n(67766),l=n(86359),o=n(43088),c=n(96073),d=n(14333),u=n(98445);const m={generatedIndexPage:"generatedIndexPage_vN6x",list:"list_eTzJ",title:"title_kItE"};var h=n(74848);function b(e){let{categoryGeneratedIndex:t}=e;return(0,h.jsx)(s.be,{title:t.title,description:t.description,keywords:t.keywords,image:(0,i.Ay)(t.image)})}function x(e){let{categoryGeneratedIndex:t}=e;const n=(0,r.$S)();return(0,h.jsxs)("div",{className:m.generatedIndexPage,children:[(0,h.jsx)(o.A,{}),(0,h.jsx)(d.A,{}),(0,h.jsx)(c.A,{}),(0,h.jsxs)("header",{children:[(0,h.jsx)(u.A,{as:"h1",className:m.title,children:t.title}),t.description&&(0,h.jsx)("p",{children:t.description})]}),(0,h.jsx)("article",{className:"margin-top--lg",children:(0,h.jsx)(a.A,{items:n.items,className:m.list})}),(0,h.jsx)("footer",{className:"margin-top--lg",children:(0,h.jsx)(l.A,{previous:t.navigation.previous,next:t.navigation.next})})]})}function p(e){return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(b,{...e}),(0,h.jsx)(x,{...e})]})}},86359:(e,t,n)=>{n.d(t,{A:()=>o});n(96540);var s=n(32032),r=n(34164),i=n(57880),a=n(74848);function l(e){const{permalink:t,title:n,subLabel:s,isNext:l}=e;return(0,a.jsxs)(i.A,{className:(0,r.A)("pagination-nav__link",l?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[s&&(0,a.jsx)("div",{className:"pagination-nav__sublabel",children:s}),(0,a.jsx)("div",{className:"pagination-nav__label",children:n})]})}function o(e){const{previous:t,next:n}=e;return(0,a.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,s.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,a.jsx)(l,{...t,subLabel:(0,a.jsx)(s.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,a.jsx)(l,{...n,subLabel:(0,a.jsx)(s.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},96073:(e,t,n)=>{n.d(t,{A:()=>o});n(96540);var s=n(34164),r=n(32032),i=n(74717),a=n(18875),l=n(74848);function o(e){let{className:t}=e;const n=(0,a.r)();return n.badge?(0,l.jsx)("span",{className:(0,s.A)(t,i.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,l.jsx)(r.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}},43088:(e,t,n)=>{n.d(t,{A:()=>p});n(96540);var s=n(34164),r=n(25792),i=n(57880),a=n(32032),l=n(80869),o=n(74717),c=n(36220),d=n(18875),u=n(74848);const m={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,u.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function h(e){const t=m[e.versionMetadata.banner];return(0,u.jsx)(t,{...e})}function b(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(i.A,{to:n,onClick:s,children:(0,u.jsx)(a.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function x(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:i}}=(0,r.A)(),{pluginId:a}=(0,l.vT)({failfast:!0}),{savePreferredVersionName:d}=(0,c.g1)(a),{latestDocSuggestion:m,latestVersionSuggestion:x}=(0,l.HW)(a),p=m??(g=x).docs.find((e=>e.id===g.mainDocId));var g;return(0,u.jsxs)("div",{className:(0,s.A)(t,o.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(h,{siteTitle:i,versionMetadata:n})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(b,{versionLabel:x.label,to:p.path,onClick:()=>d(x.name)})})]})}function p(e){let{className:t}=e;const n=(0,d.r)();return n.banner?(0,u.jsx)(x,{className:t,versionMetadata:n}):null}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/155.48c4e908.js b/pr-preview/pr-976/assets/js/155.48c4e908.js new file mode 100644 index 0000000000..51497e3340 --- /dev/null +++ b/pr-preview/pr-976/assets/js/155.48c4e908.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[155],{60155:(t,e,a)=>{a.d(e,{diagram:()=>Nt});var n=a(59347),i=a(85039),r=a(45567),s=a(20007),l=a(16750),o=function(){var t=(0,r.K2)((function(t,e,a,n){for(a=a||{},n=t.length;n--;a[t[n]]=e);return a}),"o"),e=[1,24],a=[1,25],n=[1,26],i=[1,27],s=[1,28],l=[1,63],o=[1,64],h=[1,65],d=[1,66],u=[1,67],p=[1,68],y=[1,69],g=[1,29],f=[1,30],b=[1,31],x=[1,32],_=[1,33],m=[1,34],E=[1,35],S=[1,36],A=[1,37],C=[1,38],w=[1,39],k=[1,40],O=[1,41],T=[1,42],v=[1,43],R=[1,44],D=[1,45],N=[1,46],P=[1,47],B=[1,48],I=[1,50],M=[1,51],j=[1,52],K=[1,53],L=[1,54],Y=[1,55],U=[1,56],F=[1,57],X=[1,58],z=[1,59],W=[1,60],Q=[14,42],$=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],H=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],q=[1,82],V=[1,83],G=[1,84],J=[1,85],Z=[12,14,42],tt=[12,14,33,42],et=[12,14,33,42,76,77,79,80],at=[12,33],nt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],it={trace:(0,r.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:(0,r.K2)((function(t,e,a,n,i,r,s){var l=r.length-1;switch(i){case 3:n.setDirection("TB");break;case 4:n.setDirection("BT");break;case 5:n.setDirection("RL");break;case 6:n.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:n.setC4Type(r[l-3]);break;case 19:n.setTitle(r[l].substring(6)),this.$=r[l].substring(6);break;case 20:n.setAccDescription(r[l].substring(15)),this.$=r[l].substring(15);break;case 21:this.$=r[l].trim(),n.setTitle(this.$);break;case 22:case 23:this.$=r[l].trim(),n.setAccDescription(this.$);break;case 28:r[l].splice(2,0,"ENTERPRISE"),n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 29:r[l].splice(2,0,"SYSTEM"),n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 30:n.addPersonOrSystemBoundary(...r[l]),this.$=r[l];break;case 31:r[l].splice(2,0,"CONTAINER"),n.addContainerBoundary(...r[l]),this.$=r[l];break;case 32:n.addDeploymentNode("node",...r[l]),this.$=r[l];break;case 33:n.addDeploymentNode("nodeL",...r[l]),this.$=r[l];break;case 34:n.addDeploymentNode("nodeR",...r[l]),this.$=r[l];break;case 35:n.popBoundaryParseStack();break;case 39:n.addPersonOrSystem("person",...r[l]),this.$=r[l];break;case 40:n.addPersonOrSystem("external_person",...r[l]),this.$=r[l];break;case 41:n.addPersonOrSystem("system",...r[l]),this.$=r[l];break;case 42:n.addPersonOrSystem("system_db",...r[l]),this.$=r[l];break;case 43:n.addPersonOrSystem("system_queue",...r[l]),this.$=r[l];break;case 44:n.addPersonOrSystem("external_system",...r[l]),this.$=r[l];break;case 45:n.addPersonOrSystem("external_system_db",...r[l]),this.$=r[l];break;case 46:n.addPersonOrSystem("external_system_queue",...r[l]),this.$=r[l];break;case 47:n.addContainer("container",...r[l]),this.$=r[l];break;case 48:n.addContainer("container_db",...r[l]),this.$=r[l];break;case 49:n.addContainer("container_queue",...r[l]),this.$=r[l];break;case 50:n.addContainer("external_container",...r[l]),this.$=r[l];break;case 51:n.addContainer("external_container_db",...r[l]),this.$=r[l];break;case 52:n.addContainer("external_container_queue",...r[l]),this.$=r[l];break;case 53:n.addComponent("component",...r[l]),this.$=r[l];break;case 54:n.addComponent("component_db",...r[l]),this.$=r[l];break;case 55:n.addComponent("component_queue",...r[l]),this.$=r[l];break;case 56:n.addComponent("external_component",...r[l]),this.$=r[l];break;case 57:n.addComponent("external_component_db",...r[l]),this.$=r[l];break;case 58:n.addComponent("external_component_queue",...r[l]),this.$=r[l];break;case 60:n.addRel("rel",...r[l]),this.$=r[l];break;case 61:n.addRel("birel",...r[l]),this.$=r[l];break;case 62:n.addRel("rel_u",...r[l]),this.$=r[l];break;case 63:n.addRel("rel_d",...r[l]),this.$=r[l];break;case 64:n.addRel("rel_l",...r[l]),this.$=r[l];break;case 65:n.addRel("rel_r",...r[l]),this.$=r[l];break;case 66:n.addRel("rel_b",...r[l]),this.$=r[l];break;case 67:r[l].splice(0,1),n.addRel("rel",...r[l]),this.$=r[l];break;case 68:n.updateElStyle("update_el_style",...r[l]),this.$=r[l];break;case 69:n.updateRelStyle("update_rel_style",...r[l]),this.$=r[l];break;case 70:n.updateLayoutConfig("update_layout_config",...r[l]),this.$=r[l];break;case 71:this.$=[r[l]];break;case 72:r[l].unshift(r[l-1]),this.$=r[l];break;case 73:case 75:this.$=r[l].trim();break;case 74:let t={};t[r[l-1].trim()]=r[l].trim(),this.$=t;break;case 76:this.$=""}}),"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:s,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:70,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:s,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:71,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:s,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:72,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:s,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{13:73,19:20,20:21,21:22,22:e,23:a,24:n,26:i,28:s,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{14:[1,74]},t(Q,[2,13],{43:23,29:49,30:61,32:62,20:75,34:l,36:o,37:h,38:d,39:u,40:p,41:y,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W}),t(Q,[2,14]),t($,[2,16],{12:[1,76]}),t(Q,[2,36],{12:[1,77]}),t(H,[2,19]),t(H,[2,20]),{25:[1,78]},{27:[1,79]},t(H,[2,23]),{35:80,75:81,76:q,77:V,79:G,80:J},{35:86,75:81,76:q,77:V,79:G,80:J},{35:87,75:81,76:q,77:V,79:G,80:J},{35:88,75:81,76:q,77:V,79:G,80:J},{35:89,75:81,76:q,77:V,79:G,80:J},{35:90,75:81,76:q,77:V,79:G,80:J},{35:91,75:81,76:q,77:V,79:G,80:J},{35:92,75:81,76:q,77:V,79:G,80:J},{35:93,75:81,76:q,77:V,79:G,80:J},{35:94,75:81,76:q,77:V,79:G,80:J},{35:95,75:81,76:q,77:V,79:G,80:J},{35:96,75:81,76:q,77:V,79:G,80:J},{35:97,75:81,76:q,77:V,79:G,80:J},{35:98,75:81,76:q,77:V,79:G,80:J},{35:99,75:81,76:q,77:V,79:G,80:J},{35:100,75:81,76:q,77:V,79:G,80:J},{35:101,75:81,76:q,77:V,79:G,80:J},{35:102,75:81,76:q,77:V,79:G,80:J},{35:103,75:81,76:q,77:V,79:G,80:J},{35:104,75:81,76:q,77:V,79:G,80:J},t(Z,[2,59]),{35:105,75:81,76:q,77:V,79:G,80:J},{35:106,75:81,76:q,77:V,79:G,80:J},{35:107,75:81,76:q,77:V,79:G,80:J},{35:108,75:81,76:q,77:V,79:G,80:J},{35:109,75:81,76:q,77:V,79:G,80:J},{35:110,75:81,76:q,77:V,79:G,80:J},{35:111,75:81,76:q,77:V,79:G,80:J},{35:112,75:81,76:q,77:V,79:G,80:J},{35:113,75:81,76:q,77:V,79:G,80:J},{35:114,75:81,76:q,77:V,79:G,80:J},{35:115,75:81,76:q,77:V,79:G,80:J},{20:116,29:49,30:61,32:62,34:l,36:o,37:h,38:d,39:u,40:p,41:y,43:23,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W},{12:[1,118],33:[1,117]},{35:119,75:81,76:q,77:V,79:G,80:J},{35:120,75:81,76:q,77:V,79:G,80:J},{35:121,75:81,76:q,77:V,79:G,80:J},{35:122,75:81,76:q,77:V,79:G,80:J},{35:123,75:81,76:q,77:V,79:G,80:J},{35:124,75:81,76:q,77:V,79:G,80:J},{35:125,75:81,76:q,77:V,79:G,80:J},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},t(Q,[2,15]),t($,[2,17],{21:22,19:130,22:e,23:a,24:n,26:i,28:s}),t(Q,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:e,23:a,24:n,26:i,28:s,34:l,36:o,37:h,38:d,39:u,40:p,41:y,44:g,45:f,46:b,47:x,48:_,49:m,50:E,51:S,52:A,53:C,54:w,55:k,56:O,57:T,58:v,59:R,60:D,61:N,62:P,63:B,64:I,65:M,66:j,67:K,68:L,69:Y,70:U,71:F,72:X,73:z,74:W}),t(H,[2,21]),t(H,[2,22]),t(Z,[2,39]),t(tt,[2,71],{75:81,35:132,76:q,77:V,79:G,80:J}),t(et,[2,73]),{78:[1,133]},t(et,[2,75]),t(et,[2,76]),t(Z,[2,40]),t(Z,[2,41]),t(Z,[2,42]),t(Z,[2,43]),t(Z,[2,44]),t(Z,[2,45]),t(Z,[2,46]),t(Z,[2,47]),t(Z,[2,48]),t(Z,[2,49]),t(Z,[2,50]),t(Z,[2,51]),t(Z,[2,52]),t(Z,[2,53]),t(Z,[2,54]),t(Z,[2,55]),t(Z,[2,56]),t(Z,[2,57]),t(Z,[2,58]),t(Z,[2,60]),t(Z,[2,61]),t(Z,[2,62]),t(Z,[2,63]),t(Z,[2,64]),t(Z,[2,65]),t(Z,[2,66]),t(Z,[2,67]),t(Z,[2,68]),t(Z,[2,69]),t(Z,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},t(at,[2,28]),t(at,[2,29]),t(at,[2,30]),t(at,[2,31]),t(at,[2,32]),t(at,[2,33]),t(at,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},t($,[2,18]),t(Q,[2,38]),t(tt,[2,72]),t(et,[2,74]),t(Z,[2,24]),t(Z,[2,35]),t(nt,[2,25]),t(nt,[2,26],{12:[1,138]}),t(nt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:(0,r.K2)((function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)}),"parseError"),parse:(0,r.K2)((function(t){var e=this,a=[0],n=[],i=[null],s=[],l=this.table,o="",c=0,h=0,d=0,u=s.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;s.push(f);var b=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=n.pop()||p.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,r.K2)((function(t){a.length=a.length-2*t,i.length=i.length-t,s.length=s.length-t}),"popStack"),(0,r.K2)(x,"lex");for(var _,m,E,S,A,C,w,k,O,T={};;){if(E=a[a.length-1],this.defaultActions[E]?S=this.defaultActions[E]:(null==_&&(_=x()),S=l[E]&&l[E][_]),void 0===S||!S.length||!S[0]){var v="";for(C in O=[],l[E])this.terminals_[C]&&C>2&&O.push("'"+this.terminals_[C]+"'");v=p.showPosition?"Parse error on line "+(c+1)+":\n"+p.showPosition()+"\nExpecting "+O.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(v,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:f,expected:O})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+_);switch(S[0]){case 1:a.push(_),i.push(p.yytext),s.push(p.yylloc),a.push(S[1]),_=null,m?(_=m,m=null):(h=p.yyleng,o=p.yytext,c=p.yylineno,f=p.yylloc,d>0&&d--);break;case 2:if(w=this.productions_[S[1]][1],T.$=i[i.length-w],T._$={first_line:s[s.length-(w||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(w||1)].first_column,last_column:s[s.length-1].last_column},b&&(T._$.range=[s[s.length-(w||1)].range[0],s[s.length-1].range[1]]),void 0!==(A=this.performAction.apply(T,[o,h,c,y.yy,S[1],i,s].concat(u))))return A;w&&(a=a.slice(0,-1*w*2),i=i.slice(0,-1*w),s=s.slice(0,-1*w)),a.push(this.productions_[S[1]][0]),i.push(T.$),s.push(T._$),k=l[a[a.length-2]][a[a.length-1]],a.push(k);break;case 3:return!0}}return!0}),"parse")},rt=function(){return{EOF:1,parseError:(0,r.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,r.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,r.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,r.K2)((function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===n.length?this.yylloc.first_column:0)+n[n.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,r.K2)((function(){return this._more=!0,this}),"more"),reject:(0,r.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,r.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,r.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,r.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,r.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,r.K2)((function(t,e){var a,n,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var r in i)this[r]=i[r];return!1}return!1}),"test_match"),next:(0,r.K2)((function(){if(this.done)return this.EOF;var t,e,a,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),r=0;re[0].length)){if(e=a,n=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,i[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,r.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,r.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,r.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,r.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,r.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,r.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,r.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{},performAction:(0,r.K2)((function(t,e,a,n){switch(a){case 0:return 6;case 1:return 7;case 2:return 8;case 3:return 9;case 4:return 22;case 5:return 23;case 6:return this.begin("acc_title"),24;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),26;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 73:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 16:case 70:break;case 14:c;break;case 15:return 12;case 17:return 11;case 18:return 15;case 19:return 16;case 20:return 17;case 21:return 18;case 22:return this.begin("person_ext"),45;case 23:return this.begin("person"),44;case 24:return this.begin("system_ext_queue"),51;case 25:return this.begin("system_ext_db"),50;case 26:return this.begin("system_ext"),49;case 27:return this.begin("system_queue"),48;case 28:return this.begin("system_db"),47;case 29:return this.begin("system"),46;case 30:return this.begin("boundary"),37;case 31:return this.begin("enterprise_boundary"),34;case 32:return this.begin("system_boundary"),36;case 33:return this.begin("container_ext_queue"),57;case 34:return this.begin("container_ext_db"),56;case 35:return this.begin("container_ext"),55;case 36:return this.begin("container_queue"),54;case 37:return this.begin("container_db"),53;case 38:return this.begin("container"),52;case 39:return this.begin("container_boundary"),38;case 40:return this.begin("component_ext_queue"),63;case 41:return this.begin("component_ext_db"),62;case 42:return this.begin("component_ext"),61;case 43:return this.begin("component_queue"),60;case 44:return this.begin("component_db"),59;case 45:return this.begin("component"),58;case 46:case 47:return this.begin("node"),39;case 48:return this.begin("node_l"),40;case 49:return this.begin("node_r"),41;case 50:return this.begin("rel"),64;case 51:return this.begin("birel"),65;case 52:case 53:return this.begin("rel_u"),66;case 54:case 55:return this.begin("rel_d"),67;case 56:case 57:return this.begin("rel_l"),68;case 58:case 59:return this.begin("rel_r"),69;case 60:return this.begin("rel_b"),70;case 61:return this.begin("rel_index"),71;case 62:return this.begin("update_el_style"),72;case 63:return this.begin("update_rel_style"),73;case 64:return this.begin("update_layout_config"),74;case 65:return"EOF_IN_STRUCT";case 66:return this.begin("attribute"),"ATTRIBUTE_EMPTY";case 67:this.begin("attribute");break;case 68:case 79:this.popState(),this.popState();break;case 69:case 71:return 80;case 72:this.begin("string");break;case 74:case 80:return"STR";case 75:this.begin("string_kv");break;case 76:return this.begin("string_kv_key"),"STR_KEY";case 77:this.popState(),this.begin("string_kv_value");break;case 78:return"STR_VALUE";case 81:return"LBRACE";case 82:return"RBRACE";case 83:return"SPACE";case 84:return"EOL";case 85:return 14}}),"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:title\s[^#\n;]+)/,/^(?:accDescription\s[^#\n;]+)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:C4Context\b)/,/^(?:C4Container\b)/,/^(?:C4Component\b)/,/^(?:C4Dynamic\b)/,/^(?:C4Deployment\b)/,/^(?:Person_Ext\b)/,/^(?:Person\b)/,/^(?:SystemQueue_Ext\b)/,/^(?:SystemDb_Ext\b)/,/^(?:System_Ext\b)/,/^(?:SystemQueue\b)/,/^(?:SystemDb\b)/,/^(?:System\b)/,/^(?:Boundary\b)/,/^(?:Enterprise_Boundary\b)/,/^(?:System_Boundary\b)/,/^(?:ContainerQueue_Ext\b)/,/^(?:ContainerDb_Ext\b)/,/^(?:Container_Ext\b)/,/^(?:ContainerQueue\b)/,/^(?:ContainerDb\b)/,/^(?:Container\b)/,/^(?:Container_Boundary\b)/,/^(?:ComponentQueue_Ext\b)/,/^(?:ComponentDb_Ext\b)/,/^(?:Component_Ext\b)/,/^(?:ComponentQueue\b)/,/^(?:ComponentDb\b)/,/^(?:Component\b)/,/^(?:Deployment_Node\b)/,/^(?:Node\b)/,/^(?:Node_L\b)/,/^(?:Node_R\b)/,/^(?:Rel\b)/,/^(?:BiRel\b)/,/^(?:Rel_Up\b)/,/^(?:Rel_U\b)/,/^(?:Rel_Down\b)/,/^(?:Rel_D\b)/,/^(?:Rel_Left\b)/,/^(?:Rel_L\b)/,/^(?:Rel_Right\b)/,/^(?:Rel_R\b)/,/^(?:Rel_Back\b)/,/^(?:RelIndex\b)/,/^(?:UpdateElementStyle\b)/,/^(?:UpdateRelStyle\b)/,/^(?:UpdateLayoutConfig\b)/,/^(?:$)/,/^(?:[(][ ]*[,])/,/^(?:[(])/,/^(?:[)])/,/^(?:,,)/,/^(?:,)/,/^(?:[ ]*["]["])/,/^(?:[ ]*["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:[ ]*[\$])/,/^(?:[^=]*)/,/^(?:[=][ ]*["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:[^,]+)/,/^(?:\{)/,/^(?:\})/,/^(?:[\s]+)/,/^(?:[\n\r]+)/,/^(?:$)/],conditions:{acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},string_kv_value:{rules:[78,79],inclusive:!1},string_kv_key:{rules:[77],inclusive:!1},string_kv:{rules:[76],inclusive:!1},string:{rules:[73,74],inclusive:!1},attribute:{rules:[68,69,70,71,72,75,80],inclusive:!1},update_layout_config:{rules:[65,66,67,68],inclusive:!1},update_rel_style:{rules:[65,66,67,68],inclusive:!1},update_el_style:{rules:[65,66,67,68],inclusive:!1},rel_b:{rules:[65,66,67,68],inclusive:!1},rel_r:{rules:[65,66,67,68],inclusive:!1},rel_l:{rules:[65,66,67,68],inclusive:!1},rel_d:{rules:[65,66,67,68],inclusive:!1},rel_u:{rules:[65,66,67,68],inclusive:!1},rel_bi:{rules:[],inclusive:!1},rel:{rules:[65,66,67,68],inclusive:!1},node_r:{rules:[65,66,67,68],inclusive:!1},node_l:{rules:[65,66,67,68],inclusive:!1},node:{rules:[65,66,67,68],inclusive:!1},index:{rules:[],inclusive:!1},rel_index:{rules:[65,66,67,68],inclusive:!1},component_ext_queue:{rules:[],inclusive:!1},component_ext_db:{rules:[65,66,67,68],inclusive:!1},component_ext:{rules:[65,66,67,68],inclusive:!1},component_queue:{rules:[65,66,67,68],inclusive:!1},component_db:{rules:[65,66,67,68],inclusive:!1},component:{rules:[65,66,67,68],inclusive:!1},container_boundary:{rules:[65,66,67,68],inclusive:!1},container_ext_queue:{rules:[65,66,67,68],inclusive:!1},container_ext_db:{rules:[65,66,67,68],inclusive:!1},container_ext:{rules:[65,66,67,68],inclusive:!1},container_queue:{rules:[65,66,67,68],inclusive:!1},container_db:{rules:[65,66,67,68],inclusive:!1},container:{rules:[65,66,67,68],inclusive:!1},birel:{rules:[65,66,67,68],inclusive:!1},system_boundary:{rules:[65,66,67,68],inclusive:!1},enterprise_boundary:{rules:[65,66,67,68],inclusive:!1},boundary:{rules:[65,66,67,68],inclusive:!1},system_ext_queue:{rules:[65,66,67,68],inclusive:!1},system_ext_db:{rules:[65,66,67,68],inclusive:!1},system_ext:{rules:[65,66,67,68],inclusive:!1},system_queue:{rules:[65,66,67,68],inclusive:!1},system_db:{rules:[65,66,67,68],inclusive:!1},system:{rules:[65,66,67,68],inclusive:!1},person_ext:{rules:[65,66,67,68],inclusive:!1},person:{rules:[65,66,67,68],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,81,82,83,84,85],inclusive:!0}}}}();function st(){this.yy={}}return it.lexer=rt,(0,r.K2)(st,"Parser"),st.prototype=it,it.Parser=st,new st}();o.parser=o;var h,d=o,u=[],p=[""],y="global",g="",f=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],b=[],x="",_=!1,m=4,E=2,S=(0,r.K2)((function(){return h}),"getC4Type"),A=(0,r.K2)((function(t){let e=(0,r.jZ)(t,(0,r.D7)());h=e}),"setC4Type"),C=(0,r.K2)((function(t,e,a,n,i,r,s,l,o){if(null==t||null==e||null==a||null==n)return;let c={};const h=b.find((t=>t.from===e&&t.to===a));if(h?c=h:b.push(c),c.type=t,c.from=e,c.to=a,c.label={text:n},null==i)c.techn={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];c[t]={text:e}}else c.techn={text:i};if(null==r)c.descr={text:""};else if("object"==typeof r){let[t,e]=Object.entries(r)[0];c[t]={text:e}}else c.descr={text:r};if("object"==typeof s){let[t,e]=Object.entries(s)[0];c[t]=e}else c.sprite=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];c[t]=e}else c.tags=l;if("object"==typeof o){let[t,e]=Object.entries(o)[0];c[t]=e}else c.link=o;c.wrap=$()}),"addRel"),w=(0,r.K2)((function(t,e,a,n,i,r,s){if(null===e||null===a)return;let l={};const o=u.find((t=>t.alias===e));if(o&&e===o.alias?l=o:(l.alias=e,u.push(l)),l.label=null==a?{text:""}:{text:a},null==n)l.descr={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]={text:e}}else l.descr={text:n};if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.sprite=i;if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=e}else l.tags=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=e}else l.link=s;l.typeC4Shape={text:t},l.parentBoundary=y,l.wrap=$()}),"addPersonOrSystem"),k=(0,r.K2)((function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=u.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,u.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.sprite=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=$(),o.typeC4Shape={text:t},o.parentBoundary=y}),"addContainer"),O=(0,r.K2)((function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=u.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,u.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.techn={text:""};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.techn={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof r){let[t,e]=Object.entries(r)[0];o[t]=e}else o.sprite=r;if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.wrap=$(),o.typeC4Shape={text:t},o.parentBoundary=y}),"addComponent"),T=(0,r.K2)((function(t,e,a,n,i){if(null===t||null===e)return;let r={};const s=f.find((e=>e.alias===t));if(s&&t===s.alias?r=s:(r.alias=t,f.push(r)),r.label=null==e?{text:""}:{text:e},null==a)r.type={text:"system"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];r[t]={text:e}}else r.type={text:a};if("object"==typeof n){let[t,e]=Object.entries(n)[0];r[t]=e}else r.tags=n;if("object"==typeof i){let[t,e]=Object.entries(i)[0];r[t]=e}else r.link=i;r.parentBoundary=y,r.wrap=$(),g=y,y=t,p.push(g)}),"addPersonOrSystemBoundary"),v=(0,r.K2)((function(t,e,a,n,i){if(null===t||null===e)return;let r={};const s=f.find((e=>e.alias===t));if(s&&t===s.alias?r=s:(r.alias=t,f.push(r)),r.label=null==e?{text:""}:{text:e},null==a)r.type={text:"container"};else if("object"==typeof a){let[t,e]=Object.entries(a)[0];r[t]={text:e}}else r.type={text:a};if("object"==typeof n){let[t,e]=Object.entries(n)[0];r[t]=e}else r.tags=n;if("object"==typeof i){let[t,e]=Object.entries(i)[0];r[t]=e}else r.link=i;r.parentBoundary=y,r.wrap=$(),g=y,y=t,p.push(g)}),"addContainerBoundary"),R=(0,r.K2)((function(t,e,a,n,i,r,s,l){if(null===e||null===a)return;let o={};const c=f.find((t=>t.alias===e));if(c&&e===c.alias?o=c:(o.alias=e,f.push(o)),o.label=null==a?{text:""}:{text:a},null==n)o.type={text:"node"};else if("object"==typeof n){let[t,e]=Object.entries(n)[0];o[t]={text:e}}else o.type={text:n};if(null==i)o.descr={text:""};else if("object"==typeof i){let[t,e]=Object.entries(i)[0];o[t]={text:e}}else o.descr={text:i};if("object"==typeof s){let[t,e]=Object.entries(s)[0];o[t]=e}else o.tags=s;if("object"==typeof l){let[t,e]=Object.entries(l)[0];o[t]=e}else o.link=l;o.nodeType=t,o.parentBoundary=y,o.wrap=$(),g=y,y=e,p.push(g)}),"addDeploymentNode"),D=(0,r.K2)((function(){y=g,p.pop(),g=p.pop(),p.push(g)}),"popBoundaryParseStack"),N=(0,r.K2)((function(t,e,a,n,i,r,s,l,o,c,h){let d=u.find((t=>t.alias===e));if(void 0!==d||(d=f.find((t=>t.alias===e)),void 0!==d)){if(null!=a)if("object"==typeof a){let[t,e]=Object.entries(a)[0];d[t]=e}else d.bgColor=a;if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];d[t]=e}else d.fontColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];d[t]=e}else d.borderColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];d[t]=e}else d.shadowing=r;if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];d[t]=e}else d.shape=s;if(null!=l)if("object"==typeof l){let[t,e]=Object.entries(l)[0];d[t]=e}else d.sprite=l;if(null!=o)if("object"==typeof o){let[t,e]=Object.entries(o)[0];d[t]=e}else d.techn=o;if(null!=c)if("object"==typeof c){let[t,e]=Object.entries(c)[0];d[t]=e}else d.legendText=c;if(null!=h)if("object"==typeof h){let[t,e]=Object.entries(h)[0];d[t]=e}else d.legendSprite=h}}),"updateElStyle"),P=(0,r.K2)((function(t,e,a,n,i,r,s){const l=b.find((t=>t.from===e&&t.to===a));if(void 0!==l){if(null!=n)if("object"==typeof n){let[t,e]=Object.entries(n)[0];l[t]=e}else l.textColor=n;if(null!=i)if("object"==typeof i){let[t,e]=Object.entries(i)[0];l[t]=e}else l.lineColor=i;if(null!=r)if("object"==typeof r){let[t,e]=Object.entries(r)[0];l[t]=parseInt(e)}else l.offsetX=parseInt(r);if(null!=s)if("object"==typeof s){let[t,e]=Object.entries(s)[0];l[t]=parseInt(e)}else l.offsetY=parseInt(s)}}),"updateRelStyle"),B=(0,r.K2)((function(t,e,a){let n=m,i=E;if("object"==typeof e){const t=Object.values(e)[0];n=parseInt(t)}else n=parseInt(e);if("object"==typeof a){const t=Object.values(a)[0];i=parseInt(t)}else i=parseInt(a);n>=1&&(m=n),i>=1&&(E=i)}),"updateLayoutConfig"),I=(0,r.K2)((function(){return m}),"getC4ShapeInRow"),M=(0,r.K2)((function(){return E}),"getC4BoundaryInRow"),j=(0,r.K2)((function(){return y}),"getCurrentBoundaryParse"),K=(0,r.K2)((function(){return g}),"getParentBoundaryParse"),L=(0,r.K2)((function(t){return null==t?u:u.filter((e=>e.parentBoundary===t))}),"getC4ShapeArray"),Y=(0,r.K2)((function(t){return u.find((e=>e.alias===t))}),"getC4Shape"),U=(0,r.K2)((function(t){return Object.keys(L(t))}),"getC4ShapeKeys"),F=(0,r.K2)((function(t){return null==t?f:f.filter((e=>e.parentBoundary===t))}),"getBoundaries"),X=F,z=(0,r.K2)((function(){return b}),"getRels"),W=(0,r.K2)((function(){return x}),"getTitle"),Q=(0,r.K2)((function(t){_=t}),"setWrap"),$=(0,r.K2)((function(){return _}),"autoWrap"),H=(0,r.K2)((function(){u=[],f=[{alias:"global",label:{text:"global"},type:{text:"global"},tags:null,link:null,parentBoundary:""}],g="",y="global",p=[""],b=[],p=[""],x="",_=!1,m=4,E=2}),"clear"),q=(0,r.K2)((function(t){let e=(0,r.jZ)(t,(0,r.D7)());x=e}),"setTitle"),V={addPersonOrSystem:w,addPersonOrSystemBoundary:T,addContainer:k,addContainerBoundary:v,addComponent:O,addDeploymentNode:R,popBoundaryParseStack:D,addRel:C,updateElStyle:N,updateRelStyle:P,updateLayoutConfig:B,autoWrap:$,setWrap:Q,getC4ShapeArray:L,getC4Shape:Y,getC4ShapeKeys:U,getBoundaries:F,getBoundarys:X,getCurrentBoundaryParse:j,getParentBoundaryParse:K,getRels:z,getTitle:W,getC4Type:S,getC4ShapeInRow:I,getC4BoundaryInRow:M,setAccTitle:r.SV,getAccTitle:r.iN,getAccDescription:r.m7,setAccDescription:r.EI,getConfig:(0,r.K2)((()=>(0,r.D7)().c4),"getConfig"),clear:H,LINETYPE:{SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25},ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},setTitle:q,setC4Type:A},G=(0,r.K2)((function(t,e){return(0,n.tk)(t,e)}),"drawRect"),J=(0,r.K2)((function(t,e,a,n,i,r){const s=t.append("image");s.attr("width",e),s.attr("height",a),s.attr("x",n),s.attr("y",i);let o=r.startsWith("data:image/png;base64")?r:(0,l.J)(r);s.attr("xlink:href",o)}),"drawImage"),Z=(0,r.K2)(((t,e,a)=>{const n=t.append("g");let i=0;for(let r of e){let t=r.textColor?r.textColor:"#444444",e=r.lineColor?r.lineColor:"#444444",s=r.offsetX?parseInt(r.offsetX):0,l=r.offsetY?parseInt(r.offsetY):0,o="";if(0===i){let t=n.append("line");t.attr("x1",r.startPoint.x),t.attr("y1",r.startPoint.y),t.attr("x2",r.endPoint.x),t.attr("y2",r.endPoint.y),t.attr("stroke-width","1"),t.attr("stroke",e),t.style("fill","none"),"rel_b"!==r.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==r.type&&"rel_b"!==r.type||t.attr("marker-start","url("+o+"#arrowend)"),i=-1}else{let t=n.append("path");t.attr("fill","none").attr("stroke-width","1").attr("stroke",e).attr("d","Mstartx,starty Qcontrolx,controly stopx,stopy ".replaceAll("startx",r.startPoint.x).replaceAll("starty",r.startPoint.y).replaceAll("controlx",r.startPoint.x+(r.endPoint.x-r.startPoint.x)/2-(r.endPoint.x-r.startPoint.x)/4).replaceAll("controly",r.startPoint.y+(r.endPoint.y-r.startPoint.y)/2).replaceAll("stopx",r.endPoint.x).replaceAll("stopy",r.endPoint.y)),"rel_b"!==r.type&&t.attr("marker-end","url("+o+"#arrowhead)"),"birel"!==r.type&&"rel_b"!==r.type||t.attr("marker-start","url("+o+"#arrowend)")}let c=a.messageFont();dt(a)(r.label.text,n,Math.min(r.startPoint.x,r.endPoint.x)+Math.abs(r.endPoint.x-r.startPoint.x)/2+s,Math.min(r.startPoint.y,r.endPoint.y)+Math.abs(r.endPoint.y-r.startPoint.y)/2+l,r.label.width,r.label.height,{fill:t},c),r.techn&&""!==r.techn.text&&(c=a.messageFont(),dt(a)("["+r.techn.text+"]",n,Math.min(r.startPoint.x,r.endPoint.x)+Math.abs(r.endPoint.x-r.startPoint.x)/2+s,Math.min(r.startPoint.y,r.endPoint.y)+Math.abs(r.endPoint.y-r.startPoint.y)/2+a.messageFontSize+5+l,Math.max(r.label.width,r.techn.width),r.techn.height,{fill:t,"font-style":"italic"},c))}}),"drawRels"),tt=(0,r.K2)((function(t,e,a){const n=t.append("g");let i=e.bgColor?e.bgColor:"none",r=e.borderColor?e.borderColor:"#444444",s=e.fontColor?e.fontColor:"black",l={"stroke-width":1,"stroke-dasharray":"7.0,7.0"};e.nodeType&&(l={"stroke-width":1});let o={x:e.x,y:e.y,fill:i,stroke:r,width:e.width,height:e.height,rx:2.5,ry:2.5,attrs:l};G(n,o);let c=a.boundaryFont();c.fontWeight="bold",c.fontSize=c.fontSize+2,c.fontColor=s,dt(a)(e.label.text,n,e.x,e.y+e.label.Y,e.width,e.height,{fill:"#444444"},c),e.type&&""!==e.type.text&&(c=a.boundaryFont(),c.fontColor=s,dt(a)(e.type.text,n,e.x,e.y+e.type.Y,e.width,e.height,{fill:"#444444"},c)),e.descr&&""!==e.descr.text&&(c=a.boundaryFont(),c.fontSize=c.fontSize-2,c.fontColor=s,dt(a)(e.descr.text,n,e.x,e.y+e.descr.Y,e.width,e.height,{fill:"#444444"},c))}),"drawBoundary"),et=(0,r.K2)((function(t,e,a){let i=e.bgColor?e.bgColor:a[e.typeC4Shape.text+"_bg_color"],r=e.borderColor?e.borderColor:a[e.typeC4Shape.text+"_border_color"],s=e.fontColor?e.fontColor:"#FFFFFF",l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";switch(e.typeC4Shape.text){case"person":l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAACD0lEQVR4Xu2YoU4EMRCGT+4j8Ai8AhaH4QHgAUjQuFMECUgMIUgwJAgMhgQsAYUiJCiQIBBY+EITsjfTdme6V24v4c8vyGbb+ZjOtN0bNcvjQXmkH83WvYBWto6PLm6v7p7uH1/w2fXD+PBycX1Pv2l3IdDm/vn7x+dXQiAubRzoURa7gRZWd0iGRIiJbOnhnfYBQZNJjNbuyY2eJG8fkDE3bbG4ep6MHUAsgYxmE3nVs6VsBWJSGccsOlFPmLIViMzLOB7pCVO2AtHJMohH7Fh6zqitQK7m0rJvAVYgGcEpe//PLdDz65sM4pF9N7ICcXDKIB5Nv6j7tD0NoSdM2QrU9Gg0ewE1LqBhHR3BBdvj2vapnidjHxD/q6vd7Pvhr31AwcY8eXMTXAKECZZJFXuEq27aLgQK5uLMohCenGGuGewOxSjBvYBqeG6B+Nqiblggdjnc+ZXDy+FNFpFzw76O3UBAROuXh6FoiAcf5g9eTvUgzy0nWg6I8cXHRUpg5bOVBCo+KDpFajOf23GgPme7RSQ+lacIENUgJ6gg1k6HjgOlqnLqip4tEuhv0hNEMXUD0clyXE3p6pZA0S2nnvTlXwLJEZWlb7cTQH1+USgTN4VhAenm/wea1OCAOmqo6fE1WCb9WSKBah+rbUWPWAmE2Rvk0ApiB45eOyNAzU8xcTvj8KvkKEoOaIYeHNA3ZuygAvFMUO0AAAAASUVORK5CYII=";break;case"external_person":l="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAB6ElEQVR4Xu2YLY+EMBCG9+dWr0aj0Wg0Go1Go0+j8Xdv2uTCvv1gpt0ebHKPuhDaeW4605Z9mJvx4AdXUyTUdd08z+u6flmWZRnHsWkafk9DptAwDPu+f0eAYtu2PEaGWuj5fCIZrBAC2eLBAnRCsEkkxmeaJp7iDJ2QMDdHsLg8SxKFEJaAo8lAXnmuOFIhTMpxxKATebo4UiFknuNo4OniSIXQyRxEA3YsnjGCVEjVXD7yLUAqxBGUyPv/Y4W2beMgGuS7kVQIBycH0fD+oi5pezQETxdHKmQKGk1eQEYldK+jw5GxPfZ9z7Mk0Qnhf1W1m3w//EUn5BDmSZsbR44QQLBEqrBHqOrmSKaQAxdnLArCrxZcM7A7ZKs4ioRq8LFC+NpC3WCBJsvpVw5edm9iEXFuyNfxXAgSwfrFQ1c0iNda8AdejvUgnktOtJQQxmcfFzGglc5WVCj7oDgFqU18boeFSs52CUh8LE8BIVQDT1ABrB0HtgSEYlX5doJnCwv9TXocKCaKbnwhdDKPq4lf3SwU3HLq4V/+WYhHVMa/3b4IlfyikAduCkcBc7mQ3/z/Qq/cTuikhkzB12Ae/mcJC9U+Vo8Ej1gWAtgbeGgFsAMHr50BIWOLCbezvhpBFUdY6EJuJ/QDW0XoMX60zZ0AAAAASUVORK5CYII="}const o=t.append("g");o.attr("class","person-man");const c=(0,n.PB)();switch(e.typeC4Shape.text){case"person":case"external_person":case"system":case"external_system":case"container":case"external_container":case"component":case"external_component":c.x=e.x,c.y=e.y,c.fill=i,c.width=e.width,c.height=e.height,c.stroke=r,c.rx=2.5,c.ry=2.5,c.attrs={"stroke-width":.5},G(o,c);break;case"system_db":case"external_system_db":case"container_db":case"external_container_db":case"component_db":case"external_component_db":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,-10 half,-10 half,-10c0,0 half,0 half,10l0,heightc0,10 -half,10 -half,10c0,0 -half,0 -half,-10l0,-height".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2).replaceAll("height",e.height)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc0,10 half,10 half,10c0,0 half,0 half,-10".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("half",e.width/2));break;case"system_queue":case"external_system_queue":case"container_queue":case"external_container_queue":case"component_queue":case"external_component_queue":o.append("path").attr("fill",i).attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startylwidth,0c5,0 5,half 5,halfc0,0 0,half -5,halfl-width,0c-5,0 -5,-half -5,-halfc0,0 0,-half 5,-half".replaceAll("startx",e.x).replaceAll("starty",e.y).replaceAll("width",e.width).replaceAll("half",e.height/2)),o.append("path").attr("fill","none").attr("stroke-width","0.5").attr("stroke",r).attr("d","Mstartx,startyc-5,0 -5,half -5,halfc0,half 5,half 5,half".replaceAll("startx",e.x+e.width).replaceAll("starty",e.y).replaceAll("half",e.height/2))}let h=ht(a,e.typeC4Shape.text);switch(o.append("text").attr("fill",s).attr("font-family",h.fontFamily).attr("font-size",h.fontSize-2).attr("font-style","italic").attr("lengthAdjust","spacing").attr("textLength",e.typeC4Shape.width).attr("x",e.x+e.width/2-e.typeC4Shape.width/2).attr("y",e.y+e.typeC4Shape.Y).text("<<"+e.typeC4Shape.text+">>"),e.typeC4Shape.text){case"person":case"external_person":J(o,48,48,e.x+e.width/2-24,e.y+e.image.Y,l)}let d=a[e.typeC4Shape.text+"Font"]();return d.fontWeight="bold",d.fontSize=d.fontSize+2,d.fontColor=s,dt(a)(e.label.text,o,e.x,e.y+e.label.Y,e.width,e.height,{fill:s},d),d=a[e.typeC4Shape.text+"Font"](),d.fontColor=s,e.techn&&""!==e.techn?.text?dt(a)(e.techn.text,o,e.x,e.y+e.techn.Y,e.width,e.height,{fill:s,"font-style":"italic"},d):e.type&&""!==e.type.text&&dt(a)(e.type.text,o,e.x,e.y+e.type.Y,e.width,e.height,{fill:s,"font-style":"italic"},d),e.descr&&""!==e.descr.text&&(d=a.personFont(),d.fontColor=s,dt(a)(e.descr.text,o,e.x,e.y+e.descr.Y,e.width,e.height,{fill:s},d)),e.height}),"drawC4Shape"),at=(0,r.K2)((function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")}),"insertDatabaseIcon"),nt=(0,r.K2)((function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")}),"insertComputerIcon"),it=(0,r.K2)((function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")}),"insertClockIcon"),rt=(0,r.K2)((function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z")}),"insertArrowHead"),st=(0,r.K2)((function(t){t.append("defs").append("marker").attr("id","arrowend").attr("refX",1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z")}),"insertArrowEnd"),lt=(0,r.K2)((function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",18).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")}),"insertArrowFilledHead"),ot=(0,r.K2)((function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)}),"insertDynamicNumber"),ct=(0,r.K2)((function(t){const e=t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",16).attr("refY",4);e.append("path").attr("fill","black").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 9,2 V 6 L16,4 Z"),e.append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1px").attr("d","M 0,1 L 6,7 M 6,1 L 0,7")}),"insertArrowCrossHead"),ht=(0,r.K2)(((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]})),"getC4ShapeFont"),dt=function(){function t(t,e,a,i,r,s,l){n(e.append("text").attr("x",a+r/2).attr("y",i+s/2+5).style("text-anchor","middle").text(t),l)}function e(t,e,a,i,s,l,o,c){const{fontSize:h,fontFamily:d,fontWeight:u}=c,p=t.split(r.Y2.lineBreakRegex);for(let r=0;r=this.data.widthLimit||a>=this.data.widthLimit||this.nextData.cnt>gt)&&(e=this.nextData.startx+t.margin+bt.nextLinePaddingX,n=this.nextData.stopy+2*t.margin,this.nextData.stopx=a=e+t.width,this.nextData.starty=this.nextData.stopy,this.nextData.stopy=i=n+t.height,this.nextData.cnt=1),t.x=e,t.y=n,this.updateVal(this.data,"startx",e,Math.min),this.updateVal(this.data,"starty",n,Math.min),this.updateVal(this.data,"stopx",a,Math.max),this.updateVal(this.data,"stopy",i,Math.max),this.updateVal(this.nextData,"startx",e,Math.min),this.updateVal(this.nextData,"starty",n,Math.min),this.updateVal(this.nextData,"stopx",a,Math.max),this.updateVal(this.nextData,"stopy",i,Math.max)}init(t){this.name="",this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,widthLimit:void 0},this.nextData={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0,cnt:0},_t(t.db.getConfig())}bumpLastMargin(t){this.data.stopx+=t,this.data.stopy+=t}},_t=(0,r.K2)((function(t){(0,r.hH)(bt,t),t.fontFamily&&(bt.personFontFamily=bt.systemFontFamily=bt.messageFontFamily=t.fontFamily),t.fontSize&&(bt.personFontSize=bt.systemFontSize=bt.messageFontSize=t.fontSize),t.fontWeight&&(bt.personFontWeight=bt.systemFontWeight=bt.messageFontWeight=t.fontWeight)}),"setConf"),mt=(0,r.K2)(((t,e)=>({fontFamily:t[e+"FontFamily"],fontSize:t[e+"FontSize"],fontWeight:t[e+"FontWeight"]})),"c4ShapeFont"),Et=(0,r.K2)((t=>({fontFamily:t.boundaryFontFamily,fontSize:t.boundaryFontSize,fontWeight:t.boundaryFontWeight})),"boundaryFont"),St=(0,r.K2)((t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight})),"messageFont");function At(t,e,a,n,s){if(!e[t].width)if(a)e[t].text=(0,i.bH)(e[t].text,s,n),e[t].textLines=e[t].text.split(r.Y2.lineBreakRegex).length,e[t].width=s,e[t].height=(0,i.ru)(e[t].text,n);else{let a=e[t].text.split(r.Y2.lineBreakRegex);e[t].textLines=a.length;let s=0;e[t].height=0,e[t].width=0;for(const r of a)e[t].width=Math.max((0,i.Un)(r,n),e[t].width),s=(0,i.ru)(r,n),e[t].height=e[t].height+s}}(0,r.K2)(At,"calcC4ShapeTextWH");var Ct=(0,r.K2)((function(t,e,a){e.x=a.data.startx,e.y=a.data.starty,e.width=a.data.stopx-a.data.startx,e.height=a.data.stopy-a.data.starty,e.label.y=bt.c4ShapeMargin-35;let n=e.wrap&&bt.wrap,r=Et(bt);r.fontSize=r.fontSize+2,r.fontWeight="bold",At("label",e,n,r,(0,i.Un)(e.label.text,r)),ut.drawBoundary(t,e,bt)}),"drawBoundary"),wt=(0,r.K2)((function(t,e,a,n){let r=0;for(const s of n){r=0;const n=a[s];let l=mt(bt,n.typeC4Shape.text);switch(l.fontSize=l.fontSize-2,n.typeC4Shape.width=(0,i.Un)("\xab"+n.typeC4Shape.text+"\xbb",l),n.typeC4Shape.height=l.fontSize+2,n.typeC4Shape.Y=bt.c4ShapePadding,r=n.typeC4Shape.Y+n.typeC4Shape.height-4,n.image={width:0,height:0,Y:0},n.typeC4Shape.text){case"person":case"external_person":n.image.width=48,n.image.height=48,n.image.Y=r,r=n.image.Y+n.image.height}n.sprite&&(n.image.width=48,n.image.height=48,n.image.Y=r,r=n.image.Y+n.image.height);let o=n.wrap&&bt.wrap,c=bt.width-2*bt.c4ShapePadding,h=mt(bt,n.typeC4Shape.text);if(h.fontSize=h.fontSize+2,h.fontWeight="bold",At("label",n,o,h,c),n.label.Y=r+8,r=n.label.Y+n.label.height,n.type&&""!==n.type.text){n.type.text="["+n.type.text+"]",At("type",n,o,mt(bt,n.typeC4Shape.text),c),n.type.Y=r+5,r=n.type.Y+n.type.height}else if(n.techn&&""!==n.techn.text){n.techn.text="["+n.techn.text+"]",At("techn",n,o,mt(bt,n.techn.text),c),n.techn.Y=r+5,r=n.techn.Y+n.techn.height}let d=r,u=n.label.width;if(n.descr&&""!==n.descr.text){At("descr",n,o,mt(bt,n.typeC4Shape.text),c),n.descr.Y=r+20,r=n.descr.Y+n.descr.height,u=Math.max(n.label.width,n.descr.width),d=r-5*n.descr.textLines}u+=bt.c4ShapePadding,n.width=Math.max(n.width||bt.width,u,bt.width),n.height=Math.max(n.height||bt.height,d,bt.height),n.margin=n.margin||bt.c4ShapeMargin,t.insert(n),ut.drawC4Shape(e,n,bt)}t.bumpLastMargin(bt.c4ShapeMargin)}),"drawC4ShapeArray"),kt=class{static{(0,r.K2)(this,"Point")}constructor(t,e){this.x=t,this.y=e}},Ot=(0,r.K2)((function(t,e){let a=t.x,n=t.y,i=e.x,r=e.y,s=a+t.width/2,l=n+t.height/2,o=Math.abs(a-i),c=Math.abs(n-r),h=c/o,d=t.height/t.width,u=null;return n==r&&ai?u=new kt(a,l):a==i&&nr&&(u=new kt(s,n)),a>i&&n=h?new kt(a,l+h*t.width/2):new kt(s-o/c*t.height/2,n+t.height):a=h?new kt(a+t.width,l+h*t.width/2):new kt(s+o/c*t.height/2,n+t.height):ar?u=d>=h?new kt(a+t.width,l-h*t.width/2):new kt(s+t.height/2*o/c,n):a>i&&n>r&&(u=d>=h?new kt(a,l-t.width/2*h):new kt(s-t.height/2*o/c,n)),u}),"getIntersectPoint"),Tt=(0,r.K2)((function(t,e){let a={x:0,y:0};a.x=e.x+e.width/2,a.y=e.y+e.height/2;let n=Ot(t,a);return a.x=t.x+t.width/2,a.y=t.y+t.height/2,{startPoint:n,endPoint:Ot(e,a)}}),"getIntersectPoints"),vt=(0,r.K2)((function(t,e,a,n){let r=0;for(let s of e){r+=1;let t=s.wrap&&bt.wrap,e=St(bt);"C4Dynamic"===n.db.getC4Type()&&(s.label.text=r+": "+s.label.text);let l=(0,i.Un)(s.label.text,e);At("label",s,t,e,l),s.techn&&""!==s.techn.text&&(l=(0,i.Un)(s.techn.text,e),At("techn",s,t,e,l)),s.descr&&""!==s.descr.text&&(l=(0,i.Un)(s.descr.text,e),At("descr",s,t,e,l));let o=a(s.from),c=a(s.to),h=Tt(o,c);s.startPoint=h.startPoint,s.endPoint=h.endPoint}ut.drawRels(t,e,bt)}),"drawRels");function Rt(t,e,a,n,i){let r=new xt(i);r.data.widthLimit=a.data.widthLimit/Math.min(ft,n.length);for(let[s,l]of n.entries()){let n=0;l.image={width:0,height:0,Y:0},l.sprite&&(l.image.width=48,l.image.height=48,l.image.Y=n,n=l.image.Y+l.image.height);let o=l.wrap&&bt.wrap,c=Et(bt);if(c.fontSize=c.fontSize+2,c.fontWeight="bold",At("label",l,o,c,r.data.widthLimit),l.label.Y=n+8,n=l.label.Y+l.label.height,l.type&&""!==l.type.text){l.type.text="["+l.type.text+"]",At("type",l,o,Et(bt),r.data.widthLimit),l.type.Y=n+5,n=l.type.Y+l.type.height}if(l.descr&&""!==l.descr.text){let t=Et(bt);t.fontSize=t.fontSize-2,At("descr",l,o,t,r.data.widthLimit),l.descr.Y=n+20,n=l.descr.Y+l.descr.height}if(0==s||s%ft==0){let t=a.data.startx+bt.diagramMarginX,e=a.data.stopy+bt.diagramMarginY+n;r.setData(t,t,e,e)}else{let t=r.data.stopx!==r.data.startx?r.data.stopx+bt.diagramMarginX:r.data.startx,e=r.data.starty;r.setData(t,t,e,e)}r.name=l.alias;let h=i.db.getC4ShapeArray(l.alias),d=i.db.getC4ShapeKeys(l.alias);d.length>0&&wt(r,t,h,d),e=l.alias;let u=i.db.getBoundarys(e);u.length>0&&Rt(t,e,r,u,i),"global"!==l.alias&&Ct(t,l,r),a.data.stopy=Math.max(r.data.stopy+bt.c4ShapeMargin,a.data.stopy),a.data.stopx=Math.max(r.data.stopx+bt.c4ShapeMargin,a.data.stopx),pt=Math.max(pt,a.data.stopx),yt=Math.max(yt,a.data.stopy)}}(0,r.K2)(Rt,"drawInsideBoundary");var Dt={drawPersonOrSystemArray:wt,drawBoundary:Ct,setConf:_t,draw:(0,r.K2)((function(t,e,a,n){bt=(0,r.D7)().c4;const i=(0,r.D7)().securityLevel;let l;"sandbox"===i&&(l=(0,s.Ltv)("#i"+e));const o="sandbox"===i?(0,s.Ltv)(l.nodes()[0].contentDocument.body):(0,s.Ltv)("body");let c=n.db;n.db.setWrap(bt.wrap),gt=c.getC4ShapeInRow(),ft=c.getC4BoundaryInRow(),r.Rm.debug(`C:${JSON.stringify(bt,null,2)}`);const h="sandbox"===i?o.select(`[id="${e}"]`):(0,s.Ltv)(`[id="${e}"]`);ut.insertComputerIcon(h),ut.insertDatabaseIcon(h),ut.insertClockIcon(h);let d=new xt(n);d.setData(bt.diagramMarginX,bt.diagramMarginX,bt.diagramMarginY,bt.diagramMarginY),d.data.widthLimit=screen.availWidth,pt=bt.diagramMarginX,yt=bt.diagramMarginY;const u=n.db.getTitle();Rt(h,"",d,n.db.getBoundarys(""),n),ut.insertArrowHead(h),ut.insertArrowEnd(h),ut.insertArrowCrossHead(h),ut.insertArrowFilledHead(h),vt(h,n.db.getRels(),n.db.getC4Shape,n),d.data.stopx=pt,d.data.stopy=yt;const p=d.data;let y=p.stopy-p.starty+2*bt.diagramMarginY;const g=p.stopx-p.startx+2*bt.diagramMarginX;u&&h.append("text").text(u).attr("x",(p.stopx-p.startx)/2-4*bt.diagramMarginX).attr("y",p.starty+bt.diagramMarginY),(0,r.a$)(h,y,g,bt.useMaxWidth);const f=u?60:0;h.attr("viewBox",p.startx-bt.diagramMarginX+" -"+(bt.diagramMarginY+f)+" "+g+" "+(y+f)),r.Rm.debug("models:",p)}),"draw")},Nt={parser:d,db:V,renderer:Dt,styles:(0,r.K2)((t=>`.person {\n stroke: ${t.personBorder};\n fill: ${t.personBkg};\n }\n`),"getStyles"),init:(0,r.K2)((({c4:t,wrap:e})=>{Dt.setConf(t),V.setWrap(e)}),"init")}},59347:(t,e,a)=>{a.d(e,{CP:()=>c,HT:()=>d,PB:()=>h,aC:()=>o,lC:()=>s,m:()=>l,tk:()=>r});var n=a(45567),i=a(16750),r=(0,n.K2)(((t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),e.rx&&a.attr("rx",e.rx),e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const n in e.attrs)a.attr(n,e.attrs[n]);return e.class&&a.attr("class",e.class),a}),"drawRect"),s=(0,n.K2)(((t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};r(t,a).lower()}),"drawBackgroundRect"),l=(0,n.K2)(((t,e)=>{const a=e.text.replace(n.H1," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),e.class&&i.attr("class",e.class);const r=i.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(a),i}),"drawText"),o=(0,n.K2)(((t,e,a,n)=>{const r=t.append("image");r.attr("x",e),r.attr("y",a);const s=(0,i.J)(n);r.attr("xlink:href",s)}),"drawImage"),c=(0,n.K2)(((t,e,a,n)=>{const r=t.append("use");r.attr("x",e),r.attr("y",a);const s=(0,i.J)(n);r.attr("xlink:href",`#${s}`)}),"drawEmbeddedImage"),h=(0,n.K2)((()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0})),"getNoteRect"),d=(0,n.K2)((()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})),"getTextObj")}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/15b9bf06.b97730a3.js b/pr-preview/pr-976/assets/js/15b9bf06.b97730a3.js new file mode 100644 index 0000000000..3337a68116 --- /dev/null +++ b/pr-preview/pr-976/assets/js/15b9bf06.b97730a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5388],{12988:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"architecture/confidential-containers","title":"confidential-containers","description":"","source":"@site/versioned_docs/version-0.5/architecture/confidential-containers.md","sourceDirName":"architecture","slug":"/architecture/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/confidential-containers.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"CLI","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.5/category/attestation"}}');var o=n(74848),c=n(28453);const i={},s=void 0,a={},d=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>s});var r=n(96540);const o={},c=r.createContext(o);function i(t){const e=r.useContext(c);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:i(t.components),r.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/165.8f94caaa.js b/pr-preview/pr-976/assets/js/165.8f94caaa.js new file mode 100644 index 0000000000..6d20bf8308 --- /dev/null +++ b/pr-preview/pr-976/assets/js/165.8f94caaa.js @@ -0,0 +1,2 @@ +/*! For license information please see 165.8f94caaa.js.LICENSE.txt */ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[165],{90165:(e,t,n)=>{function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){for(var n=0;ne.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:a}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var i,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,i=e},f:function(){try{o||null==n.return||n.return()}finally{if(s)throw i}}}}n.d(t,{A:()=>Xc});var h="undefined"==typeof window?null:window,p=h?h.navigator:null;h&&h.document;var f=r(""),g=r({}),v=r((function(){})),y="undefined"==typeof HTMLElement?"undefined":r(HTMLElement),m=function(e){return e&&e.instanceString&&x(e.instanceString)?e.instanceString():null},b=function(e){return null!=e&&r(e)==f},x=function(e){return null!=e&&r(e)===v},w=function(e){return!S(e)&&(Array.isArray?Array.isArray(e):null!=e&&e instanceof Array)},E=function(e){return null!=e&&r(e)===g&&!w(e)&&e.constructor===Object},k=function(e){return null!=e&&r(e)===r(1)&&!isNaN(e)},C=function(e){return"undefined"===y?void 0:null!=e&&e instanceof HTMLElement},S=function(e){return P(e)||D(e)},P=function(e){return"collection"===m(e)&&e._private.single},D=function(e){return"collection"===m(e)&&!e._private.single},T=function(e){return"core"===m(e)},_=function(e){return"stylesheet"===m(e)},M=function(e){return null==e||!(""!==e&&!e.match(/^\s+$/))},B=function(e){return function(e){return null!=e&&r(e)===g}(e)&&x(e.then)},N=function(e,t){t||(t=function(){if(1===arguments.length)return arguments[0];if(0===arguments.length)return"undefined";for(var e=[],t=0;tt?1:0},Y=null!=Object.assign?Object.assign.bind(Object):function(e){for(var t=arguments,n=1;n255)return;t.push(Math.floor(i))}var o=r[1]||r[2]||r[3],s=r[1]&&r[2]&&r[3];if(o&&!s)return;var l=n[4];if(void 0!==l){if((l=parseFloat(l))<0||l>1)return;t.push(l)}}return t}(e)||function(e){var t,n,r,a,i,o,s,l;function u(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}var c=new RegExp("^"+F+"$").exec(e);if(c){if((n=parseInt(c[1]))<0?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,(r=parseFloat(c[2]))<0||r>100)return;if(r/=100,(a=parseFloat(c[3]))<0||a>100)return;if(a/=100,void 0!==(i=c[4])&&((i=parseFloat(i))<0||i>1))return;if(0===r)o=s=l=Math.round(255*a);else{var d=a<.5?a*(1+r):a+r-a*r,h=2*a-d;o=Math.round(255*u(h,d,n+1/3)),s=Math.round(255*u(h,d,n)),l=Math.round(255*u(h,d,n-1/3))}t=[o,s,l,i]}return t}(e)},W={transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},H=function(e){for(var t=e.map,n=e.keys,r=n.length,a=0;a=t||n<0||d&&e-u>=i}function g(){var e=J();if(f(e))return v(e);s=setTimeout(g,function(e){var n=t-(e-l);return d?Ee(n,i-(e-u)):n}(e))}function v(e){return s=void 0,h&&r?p(e):(r=a=void 0,o)}function y(){var e=J(),n=f(e);if(r=arguments,a=this,l=e,n){if(void 0===s)return function(e){return u=e,s=setTimeout(g,t),c?p(e):o}(l);if(d)return clearTimeout(s),s=setTimeout(g,t),p(l)}return void 0===s&&(s=setTimeout(g,t)),o}return t=xe(t)||0,G(n)&&(c=!!n.leading,i=(d="maxWait"in n)?we(xe(n.maxWait)||0,t):i,h="trailing"in n?!!n.trailing:h),y.cancel=function(){void 0!==s&&clearTimeout(s),u=0,r=l=a=s=void 0},y.flush=function(){return void 0===s?o:v(J())},y},Ce=h?h.performance:null,Se=Ce&&Ce.now?function(){return Ce.now()}:function(){return Date.now()},Pe=function(){if(h){if(h.requestAnimationFrame)return function(e){h.requestAnimationFrame(e)};if(h.mozRequestAnimationFrame)return function(e){h.mozRequestAnimationFrame(e)};if(h.webkitRequestAnimationFrame)return function(e){h.webkitRequestAnimationFrame(e)};if(h.msRequestAnimationFrame)return function(e){h.msRequestAnimationFrame(e)}}return function(e){e&&setTimeout((function(){e(Se())}),1e3/60)}}(),De=function(e){return Pe(e)},Te=Se,_e=9261,Me=5381,Be=function(e){for(var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:_e;!(t=e.next()).done;)n=65599*n+t.value|0;return n},Ne=function(e){return 65599*(arguments.length>1&&void 0!==arguments[1]?arguments[1]:_e)+e|0},ze=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Me;return(t<<5)+t+e|0},Ie=function(e){return 2097152*e[0]+e[1]},Ae=function(e,t){return[Ne(e[0],t[0]),ze(e[1],t[1])]},Le=function(e,t){var n={value:0,done:!1},r=0,a=e.length;return Be({next:function(){return r=0&&(e[r]!==t||(e.splice(r,1),!n));r--);},nt=function(e){e.splice(0,e.length)},rt=function(e,t,n){return n&&(t=A(n,t)),e[t]},at=function(e,t,n,r){n&&(t=A(n,t)),e[t]=r},it="undefined"!=typeof Map?Map:function(){function e(){a(this,e),this._obj={}}return o(e,[{key:"set",value:function(e,t){return this._obj[e]=t,this}},{key:"delete",value:function(e){return this._obj[e]=void 0,this}},{key:"clear",value:function(){this._obj={}}},{key:"has",value:function(e){return void 0!==this._obj[e]}},{key:"get",value:function(e){return this._obj[e]}}]),e}(),ot=function(){function e(t){if(a(this,e),this._obj=Object.create(null),this.size=0,null!=t){var n;n=null!=t.instanceString&&t.instanceString()===this.instanceString()?t.toArray():t;for(var r=0;r2&&void 0!==arguments[2])||arguments[2];if(void 0!==e&&void 0!==t&&T(e)){var r=t.group;if(null==r&&(r=t.data&&null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"===r||"edges"===r){this.length=1,this[0]=this;var a=this._private={cy:e,single:!0,data:t.data||{},position:t.position||{x:0,y:0},autoWidth:void 0,autoHeight:void 0,autoPadding:void 0,compoundBoundsClean:!1,listeners:[],group:r,style:{},rstyle:{},styleCxts:[],styleKeys:{},removed:!0,selected:!!t.selected,selectable:void 0===t.selectable||!!t.selectable,locked:!!t.locked,grabbed:!1,grabbable:void 0===t.grabbable||!!t.grabbable,pannable:void 0===t.pannable?"edges"===r:!!t.pannable,active:!1,classes:new st,animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[],parent:t.parent&&t.parent.isNode()?t.parent:null,traversalCache:{},backgrounding:!1,bbCache:null,bbCacheShift:{x:0,y:0},bodyBounds:null,overlayBounds:null,labelBounds:{all:null,source:null,target:null,main:null},arrowBounds:{source:null,target:null,"mid-source":null,"mid-target":null}};if(null==a.position.x&&(a.position.x=0),null==a.position.y&&(a.position.y=0),t.renderedPosition){var i=t.renderedPosition,o=e.pan(),s=e.zoom();a.position={x:(i.x-o.x)/s,y:(i.y-o.y)/s}}var l=[];w(t.classes)?l=t.classes:b(t.classes)&&(l=t.classes.split(/\s+/));for(var u=0,c=l.length;ut?1:0},u=function(e,t,a,i,o){var s;if(null==a&&(a=0),null==o&&(o=n),a<0)throw new Error("lo must be non-negative");for(null==i&&(i=e.length);an;0<=n?t++:t--)u.push(t);return u}.apply(this).reverse()).length;ig;0<=g?++h:--h)v.push(i(e,r));return v},f=function(e,t,r,a){var i,o,s;for(null==a&&(a=n),i=e[r];r>t&&a(i,o=e[s=r-1>>1])<0;)e[r]=o,r=s;return e[r]=i},g=function(e,t,r){var a,i,o,s,l;for(null==r&&(r=n),i=e.length,l=t,o=e[t],a=2*t+1;a0;){var k=y.pop(),C=g(k),S=k.id();if(d[S]=C,C!==1/0)for(var P=k.neighborhood().intersect(p),D=0;D0)for(n.unshift(t);c[a];){var i=c[a];n.unshift(i.edge),n.unshift(i.node),a=(r=i.node).id()}return o.spawn(n)}}}},gt={kruskal:function(e){e=e||function(e){return 1};for(var t=this.byGroup(),n=t.nodes,r=t.edges,a=n.length,i=new Array(a),o=n,s=function(e){for(var t=0;t0;){if(l=g.pop(),u=l.id(),v.delete(u),w++,u===d){for(var E=[],k=a,C=d,S=m[C];E.unshift(k),null!=S&&E.unshift(S),null!=(k=y[C]);)S=m[C=k.id()];return{found:!0,distance:h[u],path:this.spawn(E),steps:w}}f[u]=!0;for(var P=l._private.edges,D=0;DD&&(p[P]=D,y[P]=S,m[P]=w),!a){var T=S*u+C;!a&&p[T]>D&&(p[T]=D,y[T]=C,m[T]=w)}}}for(var _=0;_1&&void 0!==arguments[1]?arguments[1]:i,r=[],a=m(e);;){if(null==a)return t.spawn();var o=y(a),l=o.edge,u=o.pred;if(r.unshift(a[0]),a.same(n)&&r.length>0)break;null!=l&&r.unshift(l),a=u}return s.spawn(r)},hasNegativeWeightCycle:f,negativeWeightCycles:g}}},Et=Math.sqrt(2),kt=function(e,t,n){0===n.length&&Ke("Karger-Stein must be run on a connected (sub)graph");for(var r=n[e],a=r[1],i=r[2],o=t[a],s=t[i],l=n,u=l.length-1;u>=0;u--){var c=l[u],d=c[1],h=c[2];(t[d]===o&&t[h]===s||t[d]===s&&t[h]===o)&&l.splice(u,1)}for(var p=0;pr;){var a=Math.floor(Math.random()*t.length);t=kt(a,e,t),n--}return t},St={kargerStein:function(){var e=this,t=this.byGroup(),n=t.nodes,r=t.edges;r.unmergeBy((function(e){return e.isLoop()}));var a=n.length,i=r.length,o=Math.ceil(Math.pow(Math.log(a)/Math.LN2,2)),s=Math.floor(a/Et);if(!(a<2)){for(var l=[],u=0;u0?1:e<0?-1:0},Nt=function(e,t){return Math.sqrt(zt(e,t))},zt=function(e,t){var n=t.x-e.x,r=t.y-e.y;return n*n+r*r},It=function(e){for(var t=e.length,n=0,r=0;r=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},Vt=function(e,t){e.x1=Math.min(e.x1,t.x1),e.x2=Math.max(e.x2,t.x2),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,t.y1),e.y2=Math.max(e.y2,t.y2),e.h=e.y2-e.y1},Ft=function(e,t,n){e.x1=Math.min(e.x1,t),e.x2=Math.max(e.x2,t),e.w=e.x2-e.x1,e.y1=Math.min(e.y1,n),e.y2=Math.max(e.y2,n),e.h=e.y2-e.y1},jt=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e.x1-=t,e.x2+=t,e.y1-=t,e.y2+=t,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},qt=function(e){var t,n,r,a,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[0];if(1===i.length)t=n=r=a=i[0];else if(2===i.length)t=r=i[0],a=n=i[1];else if(4===i.length){var o=l(i,4);t=o[0],n=o[1],r=o[2],a=o[3]}return e.x1-=a,e.x2+=n,e.y1-=t,e.y2+=r,e.w=e.x2-e.x1,e.h=e.y2-e.y1,e},Yt=function(e,t){e.x1=t.x1,e.y1=t.y1,e.x2=t.x2,e.y2=t.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1},Xt=function(e,t){return!(e.x1>t.x2)&&(!(t.x1>e.x2)&&(!(e.x2t.y2)&&!(t.y1>e.y2)))))))},Wt=function(e,t,n){return e.x1<=t&&t<=e.x2&&e.y1<=n&&n<=e.y2},Ht=function(e,t){return Wt(e,t.x1,t.y1)&&Wt(e,t.x2,t.y2)},Kt=function(e,t,n,r,a,i,o){var s,l,u=arguments.length>7&&void 0!==arguments[7]?arguments[7]:"auto",c="auto"===u?hn(a,i):u,d=a/2,h=i/2,p=(c=Math.min(c,d,h))!==d,f=c!==h;if(p){var g=r-h-o;if((s=on(e,t,n,r,n-d+c-o,g,n+d-c+o,g,!1)).length>0)return s}if(f){var v=n+d+o;if((s=on(e,t,n,r,v,r-h+c-o,v,r+h-c+o,!1)).length>0)return s}if(p){var y=r+h+o;if((s=on(e,t,n,r,n-d+c-o,y,n+d-c+o,y,!1)).length>0)return s}if(f){var m=n-d-o;if((s=on(e,t,n,r,m,r-h+c-o,m,r+h-c+o,!1)).length>0)return s}var b=n-d+c,x=r-h+c;if((l=rn(e,t,n,r,b,x,c+o)).length>0&&l[0]<=b&&l[1]<=x)return[l[0],l[1]];var w=n+d-c,E=r-h+c;if((l=rn(e,t,n,r,w,E,c+o)).length>0&&l[0]>=w&&l[1]<=E)return[l[0],l[1]];var k=n+d-c,C=r+h-c;if((l=rn(e,t,n,r,k,C,c+o)).length>0&&l[0]>=k&&l[1]>=C)return[l[0],l[1]];var S=n-d+c,P=r+h-c;return(l=rn(e,t,n,r,S,P,c+o)).length>0&&l[0]<=S&&l[1]>=P?[l[0],l[1]]:[]},Gt=function(e,t,n,r,a,i,o){var s=o,l=Math.min(n,a),u=Math.max(n,a),c=Math.min(r,i),d=Math.max(r,i);return l-s<=e&&e<=u+s&&c-s<=t&&t<=d+s},Ut=function(e,t,n,r,a,i,o,s,l){var u=Math.min(n,o,a)-l,c=Math.max(n,o,a)+l,d=Math.min(r,s,i)-l,h=Math.max(r,s,i)+l;return!(ec||th)},Zt=function(e,t,n,r,a,i,o,s){var l=[];!function(e,t,n,r,a){var i,o,s,l,u,c,d,h;0===e&&(e=1e-5),s=-27*(r/=e)+(t/=e)*(9*(n/=e)-t*t*2),i=(o=(3*n-t*t)/9)*o*o+(s/=54)*s,a[1]=0,d=t/3,i>0?(u=(u=s+Math.sqrt(i))<0?-Math.pow(-u,1/3):Math.pow(u,1/3),c=(c=s-Math.sqrt(i))<0?-Math.pow(-c,1/3):Math.pow(c,1/3),a[0]=-d+u+c,d+=(u+c)/2,a[4]=a[2]=-d,d=Math.sqrt(3)*(-c+u)/2,a[3]=d,a[5]=-d):(a[5]=a[3]=0,0===i?(h=s<0?-Math.pow(-s,1/3):Math.pow(s,1/3),a[0]=2*h-d,a[4]=a[2]=-(h+d)):(l=(o=-o)*o*o,l=Math.acos(s/Math.sqrt(l)),h=2*Math.sqrt(o),a[0]=-d+h*Math.cos(l/3),a[2]=-d+h*Math.cos((l+2*Math.PI)/3),a[4]=-d+h*Math.cos((l+4*Math.PI)/3)))}(1*n*n-4*n*a+2*n*o+4*a*a-4*a*o+o*o+r*r-4*r*i+2*r*s+4*i*i-4*i*s+s*s,9*n*a-3*n*n-3*n*o-6*a*a+3*a*o+9*r*i-3*r*r-3*r*s-6*i*i+3*i*s,3*n*n-6*n*a+n*o-n*e+2*a*a+2*a*e-o*e+3*r*r-6*r*i+r*s-r*t+2*i*i+2*i*t-s*t,1*n*a-n*n+n*e-a*e+r*i-r*r+r*t-i*t,l);for(var u=[],c=0;c<6;c+=2)Math.abs(l[c+1])<1e-7&&l[c]>=0&&l[c]<=1&&u.push(l[c]);u.push(1),u.push(0);for(var d,h,p,f=-1,g=0;g=0?pl?(e-a)*(e-a)+(t-i)*(t-i):u-d},Qt=function(e,t,n){for(var r,a,i,o,s=0,l=0;l=e&&e>=i||r<=e&&e<=i))continue;(e-r)/(i-r)*(o-a)+a>t&&s++}return s%2!=0},Jt=function(e,t,n,r,a,i,o,s,l){var u,c=new Array(n.length);null!=s[0]?(u=Math.atan(s[1]/s[0]),s[0]<0?u+=Math.PI/2:u=-u-Math.PI/2):u=s;for(var d,h=Math.cos(-u),p=Math.sin(-u),f=0;f0){var g=tn(c,-l);d=en(g)}else d=c;return Qt(e,t,d)},en=function(e){for(var t,n,r,a,i,o,s,l,u=new Array(e.length/2),c=0;c=0&&f<=1&&v.push(f),g>=0&&g<=1&&v.push(g),0===v.length)return[];var y=v[0]*s[0]+e,m=v[0]*s[1]+t;return v.length>1?v[0]==v[1]?[y,m]:[y,m,v[1]*s[0]+e,v[1]*s[1]+t]:[y,m]},an=function(e,t,n){return t<=e&&e<=n||n<=e&&e<=t?e:e<=t&&t<=n||n<=t&&t<=e?t:n},on=function(e,t,n,r,a,i,o,s,l){var u=e-a,c=n-e,d=o-a,h=t-i,p=r-t,f=s-i,g=d*h-f*u,v=c*h-p*u,y=f*c-d*p;if(0!==y){var m=g/y,b=v/y,x=-.001;return x<=m&&m<=1.001&&x<=b&&b<=1.001||l?[e+m*c,t+m*p]:[]}return 0===g||0===v?an(e,n,o)===o?[o,s]:an(e,n,a)===a?[a,i]:an(a,o,n)===n?[n,r]:[]:[]},sn=function(e,t,n,r,a,i,o,s){var l,u,c,d,h,p,f=[],g=new Array(n.length),v=!0;if(null==i&&(v=!1),v){for(var y=0;y0){var m=tn(g,-s);u=en(m)}else u=g}else u=n;for(var b=0;bu&&(u=t)},d=function(e){return l[e]},h=0;h0?b.edgesTo(m)[0]:m.edgesTo(b)[0];var w=r(x);m=m.id(),h[m]>h[v]+w&&(h[m]=h[v]+w,p.nodes.indexOf(m)<0?p.push(m):p.updateItem(m),u[m]=0,l[m]=[]),h[m]==h[v]+w&&(u[m]=u[m]+u[v],l[m].push(v))}else for(var E=0;E0;){for(var P=n.pop(),D=0;D0&&o.push(n[s]);0!==o.length&&a.push(r.collection(o))}return a}(c,l,t,r);return b=function(e){for(var t=0;t5&&void 0!==arguments[5]?arguments[5]:zn,o=r,s=0;s=2?Vn(e,t,n,0,Ln,On):Vn(e,t,n,0,An)},squaredEuclidean:function(e,t,n){return Vn(e,t,n,0,Ln)},manhattan:function(e,t,n){return Vn(e,t,n,0,An)},max:function(e,t,n){return Vn(e,t,n,-1/0,Rn)}};function jn(e,t,n,r,a,i){var o;return o=x(e)?e:Fn[e]||Fn.euclidean,0===t&&x(e)?o(a,i):o(t,n,r,a,i)}Fn["squared-euclidean"]=Fn.squaredEuclidean,Fn.squaredeuclidean=Fn.squaredEuclidean;var qn=et({k:2,m:2,sensitivityThreshold:1e-4,distance:"euclidean",maxIterations:10,attributes:[],testMode:!1,testCentroids:null}),Yn=function(e){return qn(e)},Xn=function(e,t,n,r,a){var i="kMedoids"!==a?function(e){return n[e]}:function(e){return r[e](n)},o=n,s=t;return jn(e,r.length,i,(function(e){return r[e](t)}),o,s)},Wn=function(e,t,n){for(var r=n.length,a=new Array(r),i=new Array(r),o=new Array(t),s=null,l=0;ln)return!1}return!0},Zn=function(e,t,n){for(var r=0;ra&&(a=t[l][u],i=u);o[i].push(e[l])}for(var c=0;c=a.threshold||"dendrogram"===a.mode&&1===e.length)return!1;var p,f=t[o],g=t[r[o]];p="dendrogram"===a.mode?{left:f,right:g,key:f.key}:{value:f.value.concat(g.value),key:f.key},e[f.index]=p,e.splice(g.index,1),t[f.key]=p;for(var v=0;vn[g.key][y.key]&&(i=n[g.key][y.key])):"max"===a.linkage?(i=n[f.key][y.key],n[f.key][y.key]1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],a=!(arguments.length>5&&void 0!==arguments[5])||arguments[5];arguments.length>3&&void 0!==arguments[3]&&!arguments[3]?(n0&&e.splice(0,t)):e=e.slice(t,n);for(var i=0,o=e.length-1;o>=0;o--){var s=e[o];a?isFinite(s)||(e[o]=-1/0,i++):e.splice(o,1)}r&&e.sort((function(e,t){return e-t}));var l=e.length,u=Math.floor(l/2);return l%2!=0?e[u+1+i]:(e[u-1+i]+e[u+i])/2}(e):"mean"===t?function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=0,a=0,i=t;i1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=1/0,a=t;a1&&void 0!==arguments[1]?arguments[1]:0,n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:e.length,r=-1/0,a=t;ao&&(i=l,o=t[a*e+l])}i>0&&r.push(i)}for(var u=0;u=D?(T=D,D=M,_=B):M>T&&(T=M);for(var N=0;N0?1:0;C[E%u.minIterations*t+R]=V,O+=V}if(O>0&&(E>=u.minIterations-1||E==u.maxIterations-1)){for(var F=0,j=0;j0&&r.push(a);return r}(t,i,o),X=function(e,t,n){for(var r=fr(e,t,n),a=0;al&&(s=u,l=c)}n[a]=i[s]}return fr(e,t,n)}(t,r,Y),W={},H=0;H1||o>1)&&(u=!0),c[t]=[],e.outgoers().forEach((function(e){e.isEdge()&&c[t].push(e.id())}))}else d[t]=[void 0,e.target().id()]})):l.forEach((function(e){var t=e.id();e.isNode()?(e.degree(!0)%2&&(n?r?u=!0:r=t:n=t),c[t]=[],e.connectedEdges().forEach((function(e){return c[t].push(e.id())}))):d[t]=[e.source().id(),e.target().id()]}));var h={found:!1,trail:void 0};if(u)return h;if(r&&n)if(s){if(a&&r!=a)return h;a=r}else{if(a&&r!=a&&n!=a)return h;a||(a=r)}else a||(a=l[0].id());var p=function(e){for(var t,n,r,a=e,i=[e];c[a].length;)t=c[a].shift(),n=d[t][0],a!=(r=d[t][1])?(c[r]=c[r].filter((function(e){return e!=t})),a=r):s||a==n||(c[n]=c[n].filter((function(e){return e!=t})),a=n),i.unshift(t),i.unshift(a);return i},f=[],g=[];for(g=p(a);1!=g.length;)0==c[g[0]].length?(f.unshift(l.getElementById(g.shift())),f.unshift(l.getElementById(g.shift()))):g=p(g.shift()).concat(g);for(var v in f.unshift(l.getElementById(g.shift())),c)if(c[v].length)return h;return h.found=!0,h.trail=this.spawn(f,!0),h}},br=function(){var e=this,t={},n=0,r=0,a=[],i=[],o={},s=function s(l,u,c){l===c&&(r+=1),t[u]={id:n,low:n++,cutVertex:!1};var d,h,p,f,g=e.getElementById(u).connectedEdges().intersection(e);0===g.size()?a.push(e.spawn(e.getElementById(u))):g.forEach((function(n){d=n.source().id(),h=n.target().id(),(p=d===u?h:d)!==c&&(f=n.id(),o[f]||(o[f]=!0,i.push({x:u,y:p,edge:n})),p in t?t[u].low=Math.min(t[u].low,t[p].id):(s(l,p,u),t[u].low=Math.min(t[u].low,t[p].low),t[u].id<=t[p].low&&(t[u].cutVertex=!0,function(n,r){for(var o=i.length-1,s=[],l=e.spawn();i[o].x!=n||i[o].y!=r;)s.push(i.pop().edge),o--;s.push(i.pop().edge),s.forEach((function(n){var r=n.connectedNodes().intersection(e);l.merge(n),r.forEach((function(n){var r=n.id(),a=n.connectedEdges().intersection(e);l.merge(n),t[r].cutVertex?l.merge(a.filter((function(e){return e.isLoop()}))):l.merge(a)}))})),a.push(l)}(u,p))))}))};e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||(r=0,s(n,n),t[n].cutVertex=r>1)}}));var l=Object.keys(t).filter((function(e){return t[e].cutVertex})).map((function(t){return e.getElementById(t)}));return{cut:e.spawn(l),components:a}},xr=function(){var e=this,t={},n=0,r=[],a=[],i=e.spawn(e),o=function o(s){if(a.push(s),t[s]={index:n,low:n++,explored:!1},e.getElementById(s).connectedEdges().intersection(e).forEach((function(e){var n=e.target().id();n!==s&&(n in t||o(n),t[n].explored||(t[s].low=Math.min(t[s].low,t[n].low)))})),t[s].index===t[s].low){for(var l=e.spawn();;){var u=a.pop();if(l.merge(e.getElementById(u)),t[u].low=t[s].index,t[u].explored=!0,u===s)break}var c=l.edgesWith(l),d=l.merge(c);r.push(d),i=i.difference(d)}};return e.forEach((function(e){if(e.isNode()){var n=e.id();n in t||o(n)}})),{cut:i,components:r}},wr={};[ct,ft,gt,yt,bt,wt,St,vn,mn,xn,En,Nn,nr,cr,vr,mr,{hopcroftTarjanBiconnected:br,htbc:br,htb:br,hopcroftTarjanBiconnectedComponents:br},{tarjanStronglyConnected:xr,tsc:xr,tscc:xr,tarjanStronglyConnectedComponents:xr}].forEach((function(e){Y(wr,e)}));var Er=function e(t){if(!(this instanceof e))return new e(t);this.id="Thenable/1.0.7",this.state=0,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},"function"==typeof t&&t.call(this,this.fulfill.bind(this),this.reject.bind(this))};Er.prototype={fulfill:function(e){return kr(this,1,"fulfillValue",e)},reject:function(e){return kr(this,2,"rejectReason",e)},then:function(e,t){var n=this,r=new Er;return n.onFulfilled.push(Pr(e,r,"fulfill")),n.onRejected.push(Pr(t,r,"reject")),Cr(n),r.proxy}};var kr=function(e,t,n,r){return 0===e.state&&(e.state=t,e[n]=r,Cr(e)),e},Cr=function(e){1===e.state?Sr(e,"onFulfilled",e.fulfillValue):2===e.state&&Sr(e,"onRejected",e.rejectReason)},Sr=function(e,t,n){if(0!==e[t].length){var r=e[t];e[t]=[];var a=function(){for(var e=0;e0:void 0}},clearQueue:function(){return function(){var e=this,t=void 0!==e.length?e:[e];if(!(this._private.cy||this).styleEnabled())return this;for(var n=0;n-1};var ga=function(e,t){var n=this.__data__,r=ca(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this};function va(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e0&&this.spawn(r).updateStyle().emit("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes.has(e)},toggleClass:function(e,t){w(e)||(e=e.match(/\S+/g)||[]);for(var n=this,r=void 0===t,a=[],i=0,o=n.length;i0&&this.spawn(a).updateStyle().emit("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var n=this;if(null==t)t=250;else if(0===t)return n;return n.addClass(e),setTimeout((function(){n.removeClass(e)}),t),n}};ai.className=ai.classNames=ai.classes;var ii={metaChar:"[\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:"\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*'",number:O,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$",group:"node|edge|\\*",directedEdge:"\\s+->\\s+",undirectedEdge:"\\s+<->\\s+"};ii.variable="(?:[\\w-.]|(?:\\\\"+ii.metaChar+"))+",ii.className="(?:[\\w-]|(?:\\\\"+ii.metaChar+"))+",ii.value=ii.string+"|"+ii.number,ii.id=ii.variable,function(){var e,t,n;for(e=ii.comparatorOp.split("|"),n=0;n=0||"="!==t&&(ii.comparatorOp+="|\\!"+t)}();var oi=0,si=1,li=2,ui=3,ci=4,di=5,hi=6,pi=7,fi=8,gi=9,vi=10,yi=11,mi=12,bi=13,xi=14,wi=15,Ei=16,ki=17,Ci=18,Si=19,Pi=20,Di=[{selector:":selected",matches:function(e){return e.selected()}},{selector:":unselected",matches:function(e){return!e.selected()}},{selector:":selectable",matches:function(e){return e.selectable()}},{selector:":unselectable",matches:function(e){return!e.selectable()}},{selector:":locked",matches:function(e){return e.locked()}},{selector:":unlocked",matches:function(e){return!e.locked()}},{selector:":visible",matches:function(e){return e.visible()}},{selector:":hidden",matches:function(e){return!e.visible()}},{selector:":transparent",matches:function(e){return e.transparent()}},{selector:":grabbed",matches:function(e){return e.grabbed()}},{selector:":free",matches:function(e){return!e.grabbed()}},{selector:":removed",matches:function(e){return e.removed()}},{selector:":inside",matches:function(e){return!e.removed()}},{selector:":grabbable",matches:function(e){return e.grabbable()}},{selector:":ungrabbable",matches:function(e){return!e.grabbable()}},{selector:":animated",matches:function(e){return e.animated()}},{selector:":unanimated",matches:function(e){return!e.animated()}},{selector:":parent",matches:function(e){return e.isParent()}},{selector:":childless",matches:function(e){return e.isChildless()}},{selector:":child",matches:function(e){return e.isChild()}},{selector:":orphan",matches:function(e){return e.isOrphan()}},{selector:":nonorphan",matches:function(e){return e.isChild()}},{selector:":compound",matches:function(e){return e.isNode()?e.isParent():e.source().isParent()||e.target().isParent()}},{selector:":loop",matches:function(e){return e.isLoop()}},{selector:":simple",matches:function(e){return e.isSimple()}},{selector:":active",matches:function(e){return e.active()}},{selector:":inactive",matches:function(e){return!e.active()}},{selector:":backgrounding",matches:function(e){return e.backgrounding()}},{selector:":nonbackgrounding",matches:function(e){return!e.backgrounding()}}].sort((function(e,t){return function(e,t){return-1*q(e,t)}(e.selector,t.selector)})),Ti=function(){for(var e,t={},n=0;n0&&u.edgeCount>0)return Ue("The selector `"+e+"` is invalid because it uses both a compound selector and an edge selector"),!1;if(u.edgeCount>1)return Ue("The selector `"+e+"` is invalid because it uses multiple edge selectors"),!1;1===u.edgeCount&&Ue("The selector `"+e+"` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.")}return!0},toString:function(){if(null!=this.toStringCache)return this.toStringCache;for(var e=function(e){return null==e?"":e},t=function(t){return b(t)?'"'+t+'"':e(t)},n=function(e){return" "+e+" "},r=function(r,i){var o=r.type,s=r.value;switch(o){case oi:var l=e(s);return l.substring(0,l.length-1);case ui:var u=r.field,c=r.operator;return"["+u+n(e(c))+t(s)+"]";case di:var d=r.operator,h=r.field;return"["+e(d)+h+"]";case ci:return"["+r.field+"]";case hi:var p=r.operator;return"[["+r.field+n(e(p))+t(s)+"]]";case pi:return s;case fi:return"#"+s;case gi:return"."+s;case ki:case wi:return a(r.parent,i)+n(">")+a(r.child,i);case Ci:case Ei:return a(r.ancestor,i)+" "+a(r.descendant,i);case Si:var f=a(r.left,i),g=a(r.subject,i),v=a(r.right,i);return f+(f.length>0?" ":"")+g+v;case Pi:return""}},a=function(e,t){return e.checks.reduce((function(n,a,i){return n+(t===e&&0===i?"$":"")+r(a,t)}),"")},i="",o=0;o1&&o=0&&(t=t.replace("!",""),c=!0),t.indexOf("@")>=0&&(t=t.replace("@",""),u=!0),(o||l||u)&&(a=o||s?""+e:"",i=""+n),u&&(e=a=a.toLowerCase(),n=i=i.toLowerCase()),t){case"*=":r=a.indexOf(i)>=0;break;case"$=":r=a.indexOf(i,a.length-i.length)>=0;break;case"^=":r=0===a.indexOf(i);break;case"=":r=e===n;break;case">":d=!0,r=e>n;break;case">=":d=!0,r=e>=n;break;case"<":d=!0,r=e0;){var u=a.shift();t(u),i.add(u.id()),o&&r(a,i,u)}return e}function Gi(e,t,n){if(n.isParent())for(var r=n._private.children,a=0;a1&&void 0!==arguments[1])||arguments[1],Gi)},Hi.forEachUp=function(e){return Ki(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Ui)},Hi.forEachUpAndDown=function(e){return Ki(this,e,!(arguments.length>1&&void 0!==arguments[1])||arguments[1],Zi)},Hi.ancestors=Hi.parents,(Yi=Xi={data:ni.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),removeData:ni.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateStyle:!0}),scratch:ni.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ni.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),rscratch:ni.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:ni.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];if(e)return e._private.data.id}}).attr=Yi.data,Yi.removeAttr=Yi.removeData;var $i,Qi,Ji=Xi,eo={};function to(e){return function(t){var n=this;if(void 0===t&&(t=!0),0!==n.length&&n.isNode()&&!n.removed()){for(var r=0,a=n[0],i=a._private.edges,o=0;ot})),minIndegree:no("indegree",(function(e,t){return et})),minOutdegree:no("outdegree",(function(e,t){return et}))}),Y(eo,{totalDegree:function(e){for(var t=0,n=this.nodes(),r=0;r0,c=u;u&&(l=l[0]);var d=c?l.position():{x:0,y:0};return a={x:s.x-d.x,y:s.y-d.y},void 0===e?a:a[e]}for(var h=0;h0,v=g;g&&(f=f[0]);var y=v?f.position():{x:0,y:0};void 0!==t?p.position(e,t+y[e]):void 0!==a&&p.position({x:a.x+y.x,y:a.y+y.y})}}else if(!i)return;return this}},$i.modelPosition=$i.point=$i.position,$i.modelPositions=$i.points=$i.positions,$i.renderedPoint=$i.renderedPosition,$i.relativePoint=$i.relativePosition;var io,oo,so=Qi;io=oo={},oo.renderedBoundingBox=function(e){var t=this.boundingBox(e),n=this.cy(),r=n.zoom(),a=n.pan(),i=t.x1*r+a.x,o=t.x2*r+a.x,s=t.y1*r+a.y,l=t.y2*r+a.y;return{x1:i,x2:o,y1:s,y2:l,w:o-i,h:l-s}},oo.dirtyCompoundBoundsCache=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();return t.styleEnabled()&&t.hasCompoundNodes()?(this.forEachUp((function(t){if(t.isParent()){var n=t._private;n.compoundBoundsClean=!1,n.bbCache=null,e||t.emitAndNotify("bounds")}})),this):this},oo.updateCompoundBounds=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return this;if(!e&&t.batching())return this;function n(e){if(e.isParent()){var t=e._private,n=e.children(),r="include"===e.pstyle("compound-sizing-wrt-labels").value,a={width:{val:e.pstyle("min-width").pfValue,left:e.pstyle("min-width-bias-left"),right:e.pstyle("min-width-bias-right")},height:{val:e.pstyle("min-height").pfValue,top:e.pstyle("min-height-bias-top"),bottom:e.pstyle("min-height-bias-bottom")}},i=n.boundingBox({includeLabels:r,includeOverlays:!1,useCache:!1}),o=t.position;0!==i.w&&0!==i.h||((i={w:e.pstyle("width").pfValue,h:e.pstyle("height").pfValue}).x1=o.x-i.w/2,i.x2=o.x+i.w/2,i.y1=o.y-i.h/2,i.y2=o.y+i.h/2);var s=a.width.left.value;"px"===a.width.left.units&&a.width.val>0&&(s=100*s/a.width.val);var l=a.width.right.value;"px"===a.width.right.units&&a.width.val>0&&(l=100*l/a.width.val);var u=a.height.top.value;"px"===a.height.top.units&&a.height.val>0&&(u=100*u/a.height.val);var c=a.height.bottom.value;"px"===a.height.bottom.units&&a.height.val>0&&(c=100*c/a.height.val);var d=y(a.width.val-i.w,s,l),h=d.biasDiff,p=d.biasComplementDiff,f=y(a.height.val-i.h,u,c),g=f.biasDiff,v=f.biasComplementDiff;t.autoPadding=function(e,t,n,r){if("%"!==n.units)return"px"===n.units?n.pfValue:0;switch(r){case"width":return e>0?n.pfValue*e:0;case"height":return t>0?n.pfValue*t:0;case"average":return e>0&&t>0?n.pfValue*(e+t)/2:0;case"min":return e>0&&t>0?e>t?n.pfValue*t:n.pfValue*e:0;case"max":return e>0&&t>0?e>t?n.pfValue*e:n.pfValue*t:0;default:return 0}}(i.w,i.h,e.pstyle("padding"),e.pstyle("padding-relative-to").value),t.autoWidth=Math.max(i.w,a.width.val),o.x=(-h+i.x1+i.x2+p)/2,t.autoHeight=Math.max(i.h,a.height.val),o.y=(-g+i.y1+i.y2+v)/2}function y(e,t,n){var r=0,a=0,i=t+n;return e>0&&i>0&&(r=t/i*e,a=n/i*e),{biasDiff:r,biasComplementDiff:a}}}for(var r=0;re.x2?r:e.x2,e.y1=ne.y2?a:e.y2,e.w=e.x2-e.x1,e.h=e.y2-e.y1)},co=function(e,t){return null==t?e:uo(e,t.x1,t.y1,t.x2,t.y2)},ho=function(e,t,n){return rt(e,t,n)},po=function(e,t,n){if(!t.cy().headless()){var r,a,i=t._private,o=i.rstyle,s=o.arrowWidth/2;if("none"!==t.pstyle(n+"-arrow-shape").value){"source"===n?(r=o.srcX,a=o.srcY):"target"===n?(r=o.tgtX,a=o.tgtY):(r=o.midX,a=o.midY);var l=i.arrowBounds=i.arrowBounds||{},u=l[n]=l[n]||{};u.x1=r-s,u.y1=a-s,u.x2=r+s,u.y2=a+s,u.w=u.x2-u.x1,u.h=u.y2-u.y1,jt(u,1),uo(e,u.x1,u.y1,u.x2,u.y2)}}},fo=function(e,t,n){if(!t.cy().headless()){var r;r=n?n+"-":"";var a=t._private,i=a.rstyle;if(t.pstyle(r+"label").strValue){var o,s,l,u,c=t.pstyle("text-halign"),d=t.pstyle("text-valign"),h=ho(i,"labelWidth",n),p=ho(i,"labelHeight",n),f=ho(i,"labelX",n),g=ho(i,"labelY",n),v=t.pstyle(r+"text-margin-x").pfValue,y=t.pstyle(r+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle(r+"text-rotation"),x=t.pstyle("text-outline-width").pfValue,w=t.pstyle("text-border-width").pfValue/2,E=t.pstyle("text-background-padding").pfValue,k=p,C=h,S=C/2,P=k/2;if(m)o=f-S,s=f+S,l=g-P,u=g+P;else{switch(c.value){case"left":o=f-C,s=f;break;case"center":o=f-S,s=f+S;break;case"right":o=f,s=f+C}switch(d.value){case"top":l=g-k,u=g;break;case"center":l=g-P,u=g+P;break;case"bottom":l=g,u=g+k}}var D=v-Math.max(x,w)-E-2,T=v+Math.max(x,w)+E+2,_=y-Math.max(x,w)-E-2,M=y+Math.max(x,w)+E+2;o+=D,s+=T,l+=_,u+=M;var B=n||"main",N=a.labelBounds,z=N[B]=N[B]||{};z.x1=o,z.y1=l,z.x2=s,z.y2=u,z.w=s-o,z.h=u-l,z.leftPad=D,z.rightPad=T,z.topPad=_,z.botPad=M;var I=m&&"autorotate"===b.strValue,A=null!=b.pfValue&&0!==b.pfValue;if(I||A){var L=I?ho(a.rstyle,"labelAngle",n):b.pfValue,O=Math.cos(L),R=Math.sin(L),V=(o+s)/2,F=(l+u)/2;if(!m){switch(c.value){case"left":V=s;break;case"right":V=o}switch(d.value){case"top":F=u;break;case"bottom":F=l}}var j=function(e,t){return{x:(e-=V)*O-(t-=F)*R+V,y:e*R+t*O+F}},q=j(o,l),Y=j(o,u),X=j(s,l),W=j(s,u);o=Math.min(q.x,Y.x,X.x,W.x),s=Math.max(q.x,Y.x,X.x,W.x),l=Math.min(q.y,Y.y,X.y,W.y),u=Math.max(q.y,Y.y,X.y,W.y)}var H=B+"Rot",K=N[H]=N[H]||{};K.x1=o,K.y1=l,K.x2=s,K.y2=u,K.w=s-o,K.h=u-l,uo(e,o,l,s,u),uo(a.labelBounds.all,o,l,s,u)}return e}},go=function(e,t){var n,r,a,i,o,s,l,u=e._private.cy,c=u.styleEnabled(),d=u.headless(),h=Rt(),p=e._private,f=e.isNode(),g=e.isEdge(),v=p.rstyle,y=f&&c?e.pstyle("bounds-expansion").pfValue:[0],m=function(e){return"none"!==e.pstyle("display").value},b=!c||m(e)&&(!g||m(e.source())&&m(e.target()));if(b){var x=0;c&&t.includeOverlays&&0!==e.pstyle("overlay-opacity").value&&(x=e.pstyle("overlay-padding").value);var w=0;c&&t.includeUnderlays&&0!==e.pstyle("underlay-opacity").value&&(w=e.pstyle("underlay-padding").value);var E=Math.max(x,w),k=0;if(c&&(k=e.pstyle("width").pfValue/2),f&&t.includeNodes){var C=e.position();o=C.x,s=C.y;var S=e.outerWidth()/2,P=e.outerHeight()/2;uo(h,n=o-S,a=s-P,r=o+S,i=s+P),c&&t.includeOutlines&&function(e,t){if(!t.cy().headless()){var n,r,a,i=t.pstyle("outline-opacity").value,o=t.pstyle("outline-width").value;if(i>0&&o>0){var s=t.pstyle("outline-offset").value,l=t.pstyle("shape").value,u=o+s,c=(e.w+2*u)/e.w,d=(e.h+2*u)/e.h,h=0;["diamond","pentagon","round-triangle"].includes(l)?(c=(e.w+2.4*u)/e.w,h=-u/3.6):["concave-hexagon","rhomboid","right-rhomboid"].includes(l)?c=(e.w+2.4*u)/e.w:"star"===l?(c=(e.w+2.8*u)/e.w,d=(e.h+2.6*u)/e.h,h=-u/3.8):"triangle"===l?(c=(e.w+2.8*u)/e.w,d=(e.h+2.4*u)/e.h,h=-u/1.4):"vee"===l&&(c=(e.w+4.4*u)/e.w,d=(e.h+3.8*u)/e.h,h=.5*-u);var p=e.h*d-e.h,f=e.w*c-e.w;if(qt(e,[Math.ceil(p/2),Math.ceil(f/2)]),0!==h){var g=(r=0,a=h,{x1:(n=e).x1+r,x2:n.x2+r,y1:n.y1+a,y2:n.y2+a,w:n.w,h:n.h});Vt(e,g)}}}}(h,e)}else if(g&&t.includeEdges)if(c&&!d){var D=e.pstyle("curve-style").strValue;if(n=Math.min(v.srcX,v.midX,v.tgtX),r=Math.max(v.srcX,v.midX,v.tgtX),a=Math.min(v.srcY,v.midY,v.tgtY),i=Math.max(v.srcY,v.midY,v.tgtY),uo(h,n-=k,a-=k,r+=k,i+=k),"haystack"===D){var T=v.haystackPts;if(T&&2===T.length){if(n=T[0].x,a=T[0].y,n>(r=T[1].x)){var _=n;n=r,r=_}if(a>(i=T[1].y)){var M=a;a=i,i=M}uo(h,n-k,a-k,r+k,i+k)}}else if("bezier"===D||"unbundled-bezier"===D||D.endsWith("segments")||D.endsWith("taxi")){var B;switch(D){case"bezier":case"unbundled-bezier":B=v.bezierPts;break;case"segments":case"taxi":case"round-segments":case"round-taxi":B=v.linePts}if(null!=B)for(var N=0;N(r=A.x)){var L=n;n=r,r=L}if((a=I.y)>(i=A.y)){var O=a;a=i,i=O}uo(h,n-=k,a-=k,r+=k,i+=k)}if(c&&t.includeEdges&&g&&(po(h,e,"mid-source"),po(h,e,"mid-target"),po(h,e,"source"),po(h,e,"target")),c)if("yes"===e.pstyle("ghost").value){var R=e.pstyle("ghost-offset-x").pfValue,V=e.pstyle("ghost-offset-y").pfValue;uo(h,h.x1+R,h.y1+V,h.x2+R,h.y2+V)}var F=p.bodyBounds=p.bodyBounds||{};Yt(F,h),qt(F,y),jt(F,1),c&&(n=h.x1,r=h.x2,a=h.y1,i=h.y2,uo(h,n-E,a-E,r+E,i+E));var j=p.overlayBounds=p.overlayBounds||{};Yt(j,h),qt(j,y),jt(j,1);var q=p.labelBounds=p.labelBounds||{};null!=q.all?((l=q.all).x1=1/0,l.y1=1/0,l.x2=-1/0,l.y2=-1/0,l.w=0,l.h=0):q.all=Rt(),c&&t.includeLabels&&(t.includeMainLabels&&fo(h,e,null),g&&(t.includeSourceLabels&&fo(h,e,"source"),t.includeTargetLabels&&fo(h,e,"target")))}return h.x1=lo(h.x1),h.y1=lo(h.y1),h.x2=lo(h.x2),h.y2=lo(h.y2),h.w=lo(h.x2-h.x1),h.h=lo(h.y2-h.y1),h.w>0&&h.h>0&&b&&(qt(h,y),jt(h,1)),h},vo=function(e){var t=0,n=function(e){return(e?1:0)<0&&void 0!==arguments[0]?arguments[0]:Lo,t=arguments.length>1?arguments[1]:void 0,n=0;n=0;s--)o(s);return this},Ro.removeAllListeners=function(){return this.removeListener("*")},Ro.emit=Ro.trigger=function(e,t,n){var r=this.listeners,a=r.length;return this.emitting++,w(t)||(t=[t]),jo(this,(function(e,i){null!=n&&(r=[{event:i.event,type:i.type,namespace:i.namespace,callback:n}],a=r.length);for(var o=function(n){var a=r[n];if(a.type===i.type&&(!a.namespace||a.namespace===i.namespace||".*"===a.namespace)&&e.eventMatches(e.context,a,i)){var o=[i];null!=t&&function(e,t){for(var n=0;n1&&!r){var a=this.length-1,i=this[a],o=i._private.data.id;this[a]=void 0,this[e]=i,n.set(o,{ele:i,index:e})}return this.length--,this},unmergeOne:function(e){e=e[0];var t=this._private,n=e._private.data.id,r=t.map.get(n);if(!r)return this;var a=r.index;return this.unmergeAt(a),this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(e&&b(e)){var n=e;e=t.mutableElements().filter(n)}for(var r=0;r=0;t--){e(this[t])&&this.unmergeAt(t)}return this},map:function(e,t){for(var n=[],r=this,a=0;ar&&(r=s,n=o)}return{value:r,ele:n}},min:function(e,t){for(var n,r=1/0,a=this,i=0;i=0&&a1&&void 0!==arguments[1])||arguments[1],n=this[0],r=n.cy();if(r.styleEnabled()&&n){this.cleanStyle();var a=n._private.style[e];return null!=a?a:t?r.style().getDefaultProperty(e):null}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var n=t.pstyle(e);return void 0!==n.pfValue?n.pfValue:n.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled())return t?t.pstyle(e).units:void 0},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=this[0];return n?t.style().getRenderedStyle(n,e):void 0},style:function(e,t){var n=this.cy();if(!n.styleEnabled())return this;var r=!1,a=n.style();if(E(e)){var i=e;a.applyBypass(this,i,r),this.emitAndNotify("style")}else if(b(e)){if(void 0===t){var o=this[0];return o?a.getStylePropertyValue(o,e):void 0}a.applyBypass(this,e,t,r),this.emitAndNotify("style")}else if(void 0===e){var s=this[0];return s?a.getRawStyle(s):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var n=!1,r=t.style(),a=this;if(void 0===e)for(var i=0;i0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,!0).filter(e)}),"neighborhood"),closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),hs.neighbourhood=hs.neighborhood,hs.closedNeighbourhood=hs.closedNeighborhood,hs.openNeighbourhood=hs.openNeighborhood,Y(hs,{source:Wi((function(e){var t,n=this[0];return n&&(t=n._private.source||n.cy().collection()),t&&e?t.filter(e):t}),"source"),target:Wi((function(e){var t,n=this[0];return n&&(t=n._private.target||n.cy().collection()),t&&e?t.filter(e):t}),"target"),sources:vs({attr:"source"}),targets:vs({attr:"target"})}),Y(hs,{edgesWith:Wi(ys(),"edgesWith"),edgesTo:Wi(ys({thisIsSrc:!0}),"edgesTo")}),Y(hs,{connectedEdges:Wi((function(e){for(var t=[],n=0;n0);return i},component:function(){var e=this[0];return e.cy().mutableElements().components(e)[0]}}),hs.componentsOf=hs.components;var bs=function(e,t){var n=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(void 0!==e){var a=new it,i=!1;if(t){if(t.length>0&&E(t[0])&&!P(t[0])){i=!0;for(var o=[],s=new st,l=0,u=t.length;l0&&void 0!==arguments[0])||arguments[0],r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=this,i=a.cy(),o=i._private,s=[],l=[],u=0,c=a.length;u0){for(var O=e.length===a.length?a:new bs(i,e),R=0;R0&&void 0!==arguments[0])||arguments[0],t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=this,r=[],a={},i=n._private.cy;function o(e){var n=a[e.id()];t&&e.removed()||n||(a[e.id()]=!0,e.isNode()?(r.push(e),function(e){for(var t=e._private.edges,n=0;n0&&(e?k.emitAndNotify("remove"):t&&k.emit("remove"));for(var C=0;C=.001?function(t,r){for(var i=0;i0?a=l:r=l}while(Math.abs(s)>i&&++ud&&Math.abs(s.v)>d;);return i?function(e){return u[e*(u.length-1)|0]}:c}}(),Cs=function(e,t,n,r){var a=Es(e,t,n,r);return function(e,t,n){return e+(t-e)*a(n)}},Ss={linear:function(e,t,n){return e+(t-e)*n},ease:Cs(.25,.1,.25,1),"ease-in":Cs(.42,0,1,1),"ease-out":Cs(0,0,.58,1),"ease-in-out":Cs(.42,0,.58,1),"ease-in-sine":Cs(.47,0,.745,.715),"ease-out-sine":Cs(.39,.575,.565,1),"ease-in-out-sine":Cs(.445,.05,.55,.95),"ease-in-quad":Cs(.55,.085,.68,.53),"ease-out-quad":Cs(.25,.46,.45,.94),"ease-in-out-quad":Cs(.455,.03,.515,.955),"ease-in-cubic":Cs(.55,.055,.675,.19),"ease-out-cubic":Cs(.215,.61,.355,1),"ease-in-out-cubic":Cs(.645,.045,.355,1),"ease-in-quart":Cs(.895,.03,.685,.22),"ease-out-quart":Cs(.165,.84,.44,1),"ease-in-out-quart":Cs(.77,0,.175,1),"ease-in-quint":Cs(.755,.05,.855,.06),"ease-out-quint":Cs(.23,1,.32,1),"ease-in-out-quint":Cs(.86,0,.07,1),"ease-in-expo":Cs(.95,.05,.795,.035),"ease-out-expo":Cs(.19,1,.22,1),"ease-in-out-expo":Cs(1,0,0,1),"ease-in-circ":Cs(.6,.04,.98,.335),"ease-out-circ":Cs(.075,.82,.165,1),"ease-in-out-circ":Cs(.785,.135,.15,.86),spring:function(e,t,n){if(0===n)return Ss.linear;var r=ks(e,t,n);return function(e,t,n){return e+(t-e)*r(n)}},"cubic-bezier":Cs};function Ps(e,t,n,r,a){if(1===r)return n;if(t===n)return n;var i=a(t,n,r);return null==e||((e.roundValue||e.color)&&(i=Math.round(i)),void 0!==e.min&&(i=Math.max(i,e.min)),void 0!==e.max&&(i=Math.min(i,e.max))),i}function Ds(e,t){return null!=e.pfValue||null!=e.value?null==e.pfValue||null!=t&&"%"===t.type.units?e.value:e.pfValue:e}function Ts(e,t,n,r,a){var i=null!=a?a.type:null;n<0?n=0:n>1&&(n=1);var o=Ds(e,a),s=Ds(t,a);if(k(o)&&k(s))return Ps(i,o,s,n,r);if(w(o)&&w(s)){for(var l=[],u=0;u0?("spring"===d&&h.push(o.duration),o.easingImpl=Ss[d].apply(null,h)):o.easingImpl=Ss[d]}var p,f=o.easingImpl;if(p=0===o.duration?1:(n-l)/o.duration,o.applying&&(p=o.progress),p<0?p=0:p>1&&(p=1),null==o.delay){var g=o.startPosition,v=o.position;if(v&&a&&!e.locked()){var y={};Ms(g.x,v.x)&&(y.x=Ts(g.x,v.x,p,f)),Ms(g.y,v.y)&&(y.y=Ts(g.y,v.y,p,f)),e.position(y)}var m=o.startPan,x=o.pan,w=i.pan,E=null!=x&&r;E&&(Ms(m.x,x.x)&&(w.x=Ts(m.x,x.x,p,f)),Ms(m.y,x.y)&&(w.y=Ts(m.y,x.y,p,f)),e.emit("pan"));var k=o.startZoom,C=o.zoom,S=null!=C&&r;S&&(Ms(k,C)&&(i.zoom=Ot(i.minZoom,Ts(k,C,p,f),i.maxZoom)),e.emit("zoom")),(E||S)&&e.emit("viewport");var P=o.style;if(P&&P.length>0&&a){for(var D=0;D=0;t--){(0,e[t])()}e.splice(0,e.length)},c=i.length-1;c>=0;c--){var d=i[c],h=d._private;h.stopped?(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.frames)):(h.playing||h.applying)&&(h.playing&&h.applying&&(h.applying=!1),h.started||Bs(0,d,e),_s(t,d,e,n),h.applying&&(h.applying=!1),u(h.frames),null!=h.step&&h.step(e),d.completed()&&(i.splice(c,1),h.hooked=!1,h.playing=!1,h.started=!1,u(h.completes)),s=!0)}return n||0!==i.length||0!==o.length||r.push(t),s}for(var i=!1,o=0;o0?t.notify("draw",n):t.notify("draw")),n.unmerge(r),t.emit("step")}var zs={animate:ni.animate(),animation:ni.animation(),animated:ni.animated(),clearQueue:ni.clearQueue(),delay:ni.delay(),delayAnimation:ni.delayAnimation(),stop:ni.stop(),addToAnimationPool:function(e){this.styleEnabled()&&this._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){var e=this;if(e._private.animationsRunning=!0,e.styleEnabled()){var t=e.renderer();t&&t.beforeRender?t.beforeRender((function(t,n){Ns(n,e)}),t.beforeRenderPriorities.animations):function t(){e._private.animationsRunning&&De((function(n){Ns(n,e),t()}))}()}}},Is={qualifierCompare:function(e,t){return null==e||null==t?null==e&&null==t:e.sameText(t)},eventMatches:function(e,t,n){var r=t.qualifier;return null==r||e!==n.target&&P(n.target)&&r.matches(n.target)},addEventFields:function(e,t){t.cy=e,t.target=e},callbackContext:function(e,t,n){return null!=t.qualifier?n.target:e}},As=function(e){return b(e)?new Fi(e):e},Ls={createEmitter:function(){var e=this._private;return e.emitter||(e.emitter=new Oo(Is,this)),this},emitter:function(){return this._private.emitter},on:function(e,t,n){return this.emitter().on(e,As(t),n),this},removeListener:function(e,t,n){return this.emitter().removeListener(e,As(t),n),this},removeAllListeners:function(){return this.emitter().removeAllListeners(),this},one:function(e,t,n){return this.emitter().one(e,As(t),n),this},once:function(e,t,n){return this.emitter().one(e,As(t),n),this},emit:function(e,t){return this.emitter().emit(e,t),this},emitAndNotify:function(e,t){return this.emit(e),this.notify(e,t),this}};ni.eventAliasesOn(Ls);var Os={png:function(e){return e=e||{},this._private.renderer.png(e)},jpg:function(e){var t=this._private.renderer;return(e=e||{}).bg=e.bg||"#fff",t.jpg(e)}};Os.jpeg=Os.jpg;var Rs={layout:function(e){var t=this;if(null!=e)if(null!=e.name){var n=e.name,r=t.extension("layout",n);if(null!=r){var a;a=b(e.eles)?t.$(e.eles):null!=e.eles?e.eles:t.$();var i=new r(Y({},e,{cy:t,eles:a}));return i}Ke("No such layout `"+n+"` found. Did you forget to import it and `cytoscape.use()` it?")}else Ke("A `name` must be specified to make a layout");else Ke("Layout options must be specified to make a layout")}};Rs.createLayout=Rs.makeLayout=Rs.layout;var Vs={notify:function(e,t){var n=this._private;if(this.batching()){n.batchNotifications=n.batchNotifications||{};var r=n.batchNotifications[e]=n.batchNotifications[e]||this.collection();null!=t&&r.merge(t)}else if(n.notificationsEnabled){var a=this.renderer();!this.destroyed()&&a&&a.notify(e,t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:(t.notificationsEnabled=!!e,this)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)},batching:function(){return this._private.batchCount>0},startBatch:function(){var e=this._private;return null==e.batchCount&&(e.batchCount=0),0===e.batchCount&&(e.batchStyleEles=this.collection(),e.batchNotifications={}),e.batchCount++,this},endBatch:function(){var e=this._private;if(0===e.batchCount)return this;if(e.batchCount--,0===e.batchCount){e.batchStyleEles.updateStyle();var t=this.renderer();Object.keys(e.batchNotifications).forEach((function(n){var r=e.batchNotifications[n];r.empty()?t.notify(n):t.notify(n,r)}))}return this},batch:function(e){return this.startBatch(),e(),this.endBatch(),this},batchData:function(e){var t=this;return this.batch((function(){for(var n=Object.keys(e),r=0;r0;)t.removeChild(t.childNodes[0]);e._private.renderer=null,e.mutableElements().forEach((function(e){var t=e._private;t.rscratch={},t.rstyle={},t.animation.current=[],t.animation.queue=[]}))},onRender:function(e){return this.on("render",e)},offRender:function(e){return this.off("render",e)}};js.invalidateDimensions=js.resize;var qs={collection:function(e,t){return b(e)?this.$(e):S(e)?e.collection():w(e)?(t||(t={}),new bs(this,e,t.unique,t.removed)):new bs(this)},nodes:function(e){var t=this.$((function(e){return e.isNode()}));return e?t.filter(e):t},edges:function(e){var t=this.$((function(e){return e.isEdge()}));return e?t.filter(e):t},$:function(e){var t=this._private.elements;return e?t.filter(e):t.spawnSelf()},mutableElements:function(){return this._private.elements}};qs.elements=qs.filter=qs.$;var Ys={},Xs="t";Ys.apply=function(e){for(var t=this,n=t._private.cy.collection(),r=0;r0;if(h||d&&p){var f=void 0;h&&p||h?f=u.properties:p&&(f=u.mappedProperties);for(var g=0;g1&&(v=1),s.color){var w=a.valueMin[0],E=a.valueMax[0],C=a.valueMin[1],S=a.valueMax[1],P=a.valueMin[2],D=a.valueMax[2],T=null==a.valueMin[3]?1:a.valueMin[3],_=null==a.valueMax[3]?1:a.valueMax[3],M=[Math.round(w+(E-w)*v),Math.round(C+(S-C)*v),Math.round(P+(D-P)*v),Math.round(T+(_-T)*v)];n={bypass:a.bypass,name:a.name,value:M,strValue:"rgb("+M[0]+", "+M[1]+", "+M[2]+")"}}else{if(!s.number)return!1;var B=a.valueMin+(a.valueMax-a.valueMin)*v;n=this.parse(a.name,B,a.bypass,h)}if(!n)return g(),!1;n.mapping=a,a=n;break;case o.data:for(var N=a.field.split("."),z=d.data,I=0;I0&&i>0){for(var s={},l=!1,u=0;u0?e.delayAnimation(o).play().promise().then(t):t()})).then((function(){return e.animation({style:s,duration:i,easing:e.pstyle("transition-timing-function").value,queue:!1}).play().promise()})).then((function(){n.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1}))}else r.transitioning&&(this.removeBypasses(e,a),e.emitAndNotify("style"),r.transitioning=!1)},Ys.checkTrigger=function(e,t,n,r,a,i){var o=this.properties[t],s=a(o);null!=s&&s(n,r)&&i(o)},Ys.checkZOrderTrigger=function(e,t,n,r){var a=this;this.checkTrigger(e,t,n,r,(function(e){return e.triggersZOrder}),(function(){a._private.cy.notify("zorder",e)}))},Ys.checkBoundsTrigger=function(e,t,n,r){this.checkTrigger(e,t,n,r,(function(e){return e.triggersBounds}),(function(a){e.dirtyCompoundBoundsCache(),e.dirtyBoundingBoxCache(),!a.triggersBoundsOfParallelBeziers||"curve-style"!==t||"bezier"!==n&&"bezier"!==r||e.parallelEdges().forEach((function(e){e.isBundledBezier()&&e.dirtyBoundingBoxCache()})),!a.triggersBoundsOfConnectedEdges||"display"!==t||"none"!==n&&"none"!==r||e.connectedEdges().forEach((function(e){e.dirtyBoundingBoxCache()}))}))},Ys.checkTriggers=function(e,t,n,r){e.dirtyStyleCache(),this.checkZOrderTrigger(e,t,n,r),this.checkBoundsTrigger(e,t,n,r)};var Ws={applyBypass:function(e,t,n,r){var a=[];if("*"===t||"**"===t){if(void 0!==n)for(var i=0;it.length?i.substr(t.length):""}function s(){n=n.length>r.length?n.substr(r.length):""}for(i=i.replace(/[/][*](\s|.)+?[*][/]/g,"");;){if(i.match(/^\s*$/))break;var l=i.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!l){Ue("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+i);break}t=l[0];var u=l[1];if("core"!==u)if(new Fi(u).invalid){Ue("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),o();continue}var c=l[2],d=!1;n=c;for(var h=[];;){if(n.match(/^\s*$/))break;var p=n.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);if(!p){Ue("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+c),d=!0;break}r=p[0];var f=p[1],g=p[2];if(this.properties[f])a.parse(f,g)?(h.push({name:f,val:g}),s()):(Ue("Skipping property: Invalid property definition in: "+r),s());else Ue("Skipping property: Invalid property name in: "+r),s()}if(d){o();break}a.selector(u);for(var v=0;v=7&&"d"===t[0]&&(u=new RegExp(s.data.regex).exec(t))){if(n)return!1;var h=s.data;return{name:e,value:u,strValue:""+t,mapped:h,field:u[1],bypass:n}}if(t.length>=10&&"m"===t[0]&&(c=new RegExp(s.mapData.regex).exec(t))){if(n)return!1;if(d.multiple)return!1;var p=s.mapData;if(!d.color&&!d.number)return!1;var f=this.parse(e,c[4]);if(!f||f.mapped)return!1;var g=this.parse(e,c[5]);if(!g||g.mapped)return!1;if(f.pfValue===g.pfValue||f.strValue===g.strValue)return Ue("`"+e+": "+t+"` is not a valid mapper because the output range is zero; converting to `"+e+": "+f.strValue+"`"),this.parse(e,f.strValue);if(d.color){var v=f.value,y=g.value;if(!(v[0]!==y[0]||v[1]!==y[1]||v[2]!==y[2]||v[3]!==y[3]&&(null!=v[3]&&1!==v[3]||null!=y[3]&&1!==y[3])))return!1}return{name:e,value:c,strValue:""+t,mapped:p,field:c[1],fieldMin:parseFloat(c[2]),fieldMax:parseFloat(c[3]),valueMin:f.value,valueMax:g.value,bypass:n}}}if(d.multiple&&"multiple"!==r){var m;if(m=l?t.split(/\s+/):w(t)?t:[t],d.evenMultiple&&m.length%2!=0)return null;for(var E=[],C=[],S=[],P="",D=!1,T=0;T0?" ":"")+_.strValue}return d.validate&&!d.validate(E,C)?null:d.singleEnum&&D?1===E.length&&b(E[0])?{name:e,value:E[0],strValue:E[0],bypass:n}:null:{name:e,value:E,pfValue:S,strValue:P,bypass:n,units:C}}var M,B,N=function(){for(var r=0;rd.max||d.strictMax&&t===d.max))return null;var V={name:e,value:t,strValue:""+t+(I||""),units:I,bypass:n};return d.unitless||"px"!==I&&"em"!==I?V.pfValue=t:V.pfValue="px"!==I&&I?this.getEmSizeInPixels()*t:t,"ms"!==I&&"s"!==I||(V.pfValue="ms"===I?t:1e3*t),"deg"!==I&&"rad"!==I||(V.pfValue="rad"===I?t:(M=t,Math.PI*M/180)),"%"===I&&(V.pfValue=t/100),V}if(d.propList){var F=[],j=""+t;if("none"===j);else{for(var q=j.split(/\s*,\s*|\s+/),Y=0;Y0&&l>0&&!isNaN(n.w)&&!isNaN(n.h)&&n.w>0&&n.h>0)return{zoom:o=(o=(o=Math.min((s-2*t)/n.w,(l-2*t)/n.h))>this._private.maxZoom?this._private.maxZoom:o)=n.minZoom&&(n.maxZoom=t),this},minZoom:function(e){return void 0===e?this._private.minZoom:this.zoomRange({min:e})},maxZoom:function(e){return void 0===e?this._private.maxZoom:this.zoomRange({max:e})},getZoomedViewport:function(e){var t,n,r=this._private,a=r.pan,i=r.zoom,o=!1;if(r.zoomingEnabled||(o=!0),k(e)?n=e:E(e)&&(n=e.level,null!=e.position?t=Pt(e.position,i,a):null!=e.renderedPosition&&(t=e.renderedPosition),null==t||r.panningEnabled||(o=!0)),n=(n=n>r.maxZoom?r.maxZoom:n)t.maxZoom||!t.zoomingEnabled?i=!0:(t.zoom=s,a.push("zoom"))}if(r&&(!i||!e.cancelOnFailedZoom)&&t.panningEnabled){var l=e.pan;k(l.x)&&(t.pan.x=l.x,o=!1),k(l.y)&&(t.pan.y=l.y,o=!1),o||a.push("pan")}return a.length>0&&(a.push("viewport"),this.emit(a.join(" ")),this.notify("viewport")),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.emit("pan viewport"),this.notify("viewport")),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(b(e)){var n=e;e=this.mutableElements().filter(n)}else S(e)||(e=this.mutableElements());if(0!==e.length){var r=e.boundingBox(),a=this.width(),i=this.height();return{x:(a-(t=void 0===t?this._private.zoom:t)*(r.x1+r.x2))/2,y:(i-t*(r.y1+r.y2))/2}}}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},invalidateSize:function(){this._private.sizeCache=null},size:function(){var e,t,n=this._private,r=n.container,a=this;return n.sizeCache=n.sizeCache||(r?(e=a.window().getComputedStyle(r),t=function(t){return parseFloat(e.getPropertyValue(t))},{width:r.clientWidth-t("padding-left")-t("padding-right"),height:r.clientHeight-t("padding-top")-t("padding-bottom")}):{width:1,height:1})},width:function(){return this.size().width},height:function(){return this.size().height},extent:function(){var e=this._private.pan,t=this._private.zoom,n=this.renderedExtent(),r={x1:(n.x1-e.x)/t,x2:(n.x2-e.x)/t,y1:(n.y1-e.y)/t,y2:(n.y2-e.y)/t};return r.w=r.x2-r.x1,r.h=r.y2-r.y1,r},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}},multiClickDebounceTime:function(e){return e?(this._private.multiClickDebounceTime=e,this):this._private.multiClickDebounceTime}};tl.centre=tl.center,tl.autolockNodes=tl.autolock,tl.autoungrabifyNodes=tl.autoungrabify;var nl={data:ni.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeData:ni.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0}),scratch:ni.data({field:"scratch",bindingEvent:"scratch",allowBinding:!0,allowSetting:!0,settingEvent:"scratch",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,updateStyle:!0}),removeScratch:ni.removeData({field:"scratch",event:"scratch",triggerFnName:"trigger",triggerEvent:!0,updateStyle:!0})};nl.attr=nl.data,nl.removeAttr=nl.removeData;var rl=function(e){var t=this,n=(e=Y({},e)).container;n&&!C(n)&&C(n[0])&&(n=n[0]);var r=n?n._cyreg:null;(r=r||{})&&r.cy&&(r.cy.destroy(),r={});var a=r.readies=r.readies||[];n&&(n._cyreg=r),r.cy=t;var i=void 0!==h&&void 0!==n&&!e.headless,o=e;o.layout=Y({name:i?"grid":"null"},o.layout),o.renderer=Y({name:i?"canvas":"null"},o.renderer);var s=function(e,t,n){return void 0!==t?t:void 0!==n?n:e},l=this._private={container:n,ready:!1,options:o,elements:new bs(this),listeners:[],aniEles:new bs(this),data:o.data||{},scratch:{},layout:null,renderer:null,destroyed:!1,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:s(!0,o.zoomingEnabled),userZoomingEnabled:s(!0,o.userZoomingEnabled),panningEnabled:s(!0,o.panningEnabled),userPanningEnabled:s(!0,o.userPanningEnabled),boxSelectionEnabled:s(!0,o.boxSelectionEnabled),autolock:s(!1,o.autolock,o.autolockNodes),autoungrabify:s(!1,o.autoungrabify,o.autoungrabifyNodes),autounselectify:s(!1,o.autounselectify),styleEnabled:void 0===o.styleEnabled?i:o.styleEnabled,zoom:k(o.zoom)?o.zoom:1,pan:{x:E(o.pan)&&k(o.pan.x)?o.pan.x:0,y:E(o.pan)&&k(o.pan.y)?o.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,multiClickDebounceTime:s(250,o.multiClickDebounceTime)};this.createEmitter(),this.selectionType(o.selectionType),this.zoomRange({min:o.minZoom,max:o.maxZoom});l.styleEnabled&&t.setStyle([]);var u=Y({},o,o.renderer);t.initRenderer(u);!function(e,t){if(e.some(B))return Tr.all(e).then(t);t(e)}([o.style,o.elements],(function(e){var n=e[0],i=e[1];l.styleEnabled&&t.style().append(n),function(e,n,r){t.notifications(!1);var a=t.mutableElements();a.length>0&&a.remove(),null!=e&&(E(e)||w(e))&&t.add(e),t.one("layoutready",(function(e){t.notifications(!0),t.emit(e),t.one("load",n),t.emitAndNotify("load")})).one("layoutstop",(function(){t.one("done",r),t.emit("done")}));var i=Y({},t._private.options.layout);i.eles=t.elements(),t.layout(i).run()}(i,(function(){t.startAnimationLoop(),l.ready=!0,x(o.ready)&&t.on("ready",o.ready);for(var e=0;e0,u=Rt(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()});if(S(n.roots))e=n.roots;else if(w(n.roots)){for(var c=[],d=0;d0;){var N=_.shift(),z=T(N,M);if(z)N.outgoers().filter((function(e){return e.isNode()&&a.has(e)})).forEach(B);else if(null===z){Ue("Detected double maximal shift for node `"+N.id()+"`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.");break}}}D();var I=0;if(n.avoidOverlap)for(var A=0;A0&&y[0].length<=3?l/2:0),d=2*Math.PI/y[r].length*a;return 0===r&&1===y[0].length&&(c=1),{x:G+c*Math.cos(d),y:U+c*Math.sin(d)}}return{x:G+(a+1-(i+1)/2)*o,y:(r+1)*s}})),this};var cl={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,radius:void 0,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function dl(e){this.options=Y({},cl,e)}dl.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,i=r.nodes().not(":parent");t.sort&&(i=i.sort(t.sort));for(var o,s=Rt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l=s.x1+s.w/2,u=s.y1+s.h/2,c=(void 0===t.sweep?2*Math.PI-2*Math.PI/i.length:t.sweep)/Math.max(1,i.length-1),d=0,h=0;h1&&t.avoidOverlap){d*=1.75;var v=Math.cos(c)-Math.cos(0),y=Math.sin(c)-Math.sin(0),m=Math.sqrt(d*d/(v*v+y*y));o=Math.max(m,o)}return r.nodes().layoutPositions(this,t,(function(e,n){var r=t.startAngle+n*c*(a?1:-1),i=o*Math.cos(r),s=o*Math.sin(r);return{x:l+i,y:u+s}})),this};var hl,pl={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,nodeDimensionsIncludeLabels:!1,height:void 0,width:void 0,spacingFactor:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function fl(e){this.options=Y({},pl,e)}fl.prototype.run=function(){for(var e=this.options,t=e,n=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,r=e.cy,a=t.eles,i=a.nodes().not(":parent"),o=Rt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:r.width(),h:r.height()}),s=o.x1+o.w/2,l=o.y1+o.h/2,u=[],c=0,d=0;d0)Math.abs(m[0].value-x.value)>=v&&(m=[],y.push(m));m.push(x)}var w=c+t.minNodeSpacing;if(!t.avoidOverlap){var E=y.length>0&&y[0].length>1,k=(Math.min(o.w,o.h)/2-w)/(y.length+E?1:0);w=Math.min(w,k)}for(var C=0,S=0;S1&&t.avoidOverlap){var _=Math.cos(T)-Math.cos(0),M=Math.sin(T)-Math.sin(0),B=Math.sqrt(w*w/(_*_+M*M));C=Math.max(B,C)}P.r=C,C+=w}if(t.equidistant){for(var N=0,z=0,I=0;I=e.numIter)&&(kl(r,e),r.temperature=r.temperature*e.coolingFactor,!(r.temperature=e.animationThreshold&&i(),De(t)):(Al(r,e),s())}()}else{for(;u;)u=o(l),l++;Al(r,e),s()}return this},vl.prototype.stop=function(){return this.stopped=!0,this.thread&&this.thread.stop(),this.emit("layoutstop"),this},vl.prototype.destroy=function(){return this.thread&&this.thread.stop(),this};var yl=function(e,t,n){for(var r=n.eles.edges(),a=n.eles.nodes(),i=Rt(n.boundingBox?n.boundingBox:{x1:0,y1:0,w:e.width(),h:e.height()}),o={isCompound:e.hasCompoundNodes(),layoutNodes:[],idToIndex:{},nodeSize:a.size(),graphSet:[],indexToGraph:[],layoutEdges:[],edgeSize:r.size(),temperature:n.initialTemp,clientWidth:i.w,clientHeight:i.h,boundingBox:i},s=n.eles.components(),l={},u=0;u0){o.graphSet.push(E);for(u=0;ur.count?0:r.graph},bl=function e(t,n,r,a){var i=a.graphSet[r];if(-10)var s=(u=r.nodeOverlap*o)*a/(g=Math.sqrt(a*a+i*i)),l=u*i/g;else{var u,c=Tl(e,a,i),d=Tl(t,-1*a,-1*i),h=d.x-c.x,p=d.y-c.y,f=h*h+p*p,g=Math.sqrt(f);s=(u=(e.nodeRepulsion+t.nodeRepulsion)/f)*h/g,l=u*p/g}e.isLocked||(e.offsetX-=s,e.offsetY-=l),t.isLocked||(t.offsetX+=s,t.offsetY+=l)}},Dl=function(e,t,n,r){if(n>0)var a=e.maxX-t.minX;else a=t.maxX-e.minX;if(r>0)var i=e.maxY-t.minY;else i=t.maxY-e.minY;return a>=0&&i>=0?Math.sqrt(a*a+i*i):0},Tl=function(e,t,n){var r=e.positionX,a=e.positionY,i=e.height||1,o=e.width||1,s=n/t,l=i/o,u={};return 0===t&&0n?(u.x=r,u.y=a+i/2,u):0t&&-1*l<=s&&s<=l?(u.x=r-o/2,u.y=a-o*n/2/t,u):0=l)?(u.x=r+i*t/2/n,u.y=a+i/2,u):0>n&&(s<=-1*l||s>=l)?(u.x=r-i*t/2/n,u.y=a-i/2,u):u},_l=function(e,t){for(var n=0;n1){var f=t.gravity*d/p,g=t.gravity*h/p;c.offsetX+=f,c.offsetY+=g}}}}},Bl=function(e,t){var n=[],r=0,a=-1;for(n.push.apply(n,e.graphSet[0]),a+=e.graphSet[0].length;r<=a;){var i=n[r++],o=e.idToIndex[i],s=e.layoutNodes[o],l=s.children;if(0n)var a={x:n*e/r,y:n*t/r};else a={x:e,y:t};return a},Il=function e(t,n){var r=t.parentId;if(null!=r){var a=n.layoutNodes[n.idToIndex[r]],i=!1;return(null==a.maxX||t.maxX+a.padRight>a.maxX)&&(a.maxX=t.maxX+a.padRight,i=!0),(null==a.minX||t.minX-a.padLefta.maxY)&&(a.maxY=t.maxY+a.padBottom,i=!0),(null==a.minY||t.minY-a.padTopf&&(d+=p+t.componentSpacing,c=0,h=0,p=0)}}},Ll={fit:!0,padding:30,boundingBox:void 0,avoidOverlap:!0,avoidOverlapPadding:10,nodeDimensionsIncludeLabels:!1,spacingFactor:void 0,condense:!1,rows:void 0,cols:void 0,position:function(e){},sort:void 0,animate:!1,animationDuration:500,animationEasing:void 0,animateFilter:function(e,t){return!0},ready:void 0,stop:void 0,transform:function(e,t){return t}};function Ol(e){this.options=Y({},Ll,e)}Ol.prototype.run=function(){var e=this.options,t=e,n=e.cy,r=t.eles,a=r.nodes().not(":parent");t.sort&&(a=a.sort(t.sort));var i=Rt(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()});if(0===i.h||0===i.w)r.nodes().layoutPositions(this,t,(function(e){return{x:i.x1,y:i.y1}}));else{var o=a.size(),s=Math.sqrt(o*i.h/i.w),l=Math.round(s),u=Math.round(i.w/i.h*s),c=function(e){if(null==e)return Math.min(l,u);Math.min(l,u)==l?l=e:u=e},d=function(e){if(null==e)return Math.max(l,u);Math.max(l,u)==l?l=e:u=e},h=t.rows,p=null!=t.cols?t.cols:t.columns;if(null!=h&&null!=p)l=h,u=p;else if(null!=h&&null==p)l=h,u=Math.ceil(o/l);else if(null==h&&null!=p)u=p,l=Math.ceil(o/u);else if(u*l>o){var f=c(),g=d();(f-1)*g>=o?c(f-1):(g-1)*f>=o&&d(g-1)}else for(;u*l=o?d(y+1):c(v+1)}var m=i.w/u,b=i.h/l;if(t.condense&&(m=0,b=0),t.avoidOverlap)for(var x=0;x=u&&(B=0,M++)},z={},I=0;I(r=$t(e,t,x[w],x[w+1],x[w+2],x[w+3])))return v(n,r),!0}else if("bezier"===i.edgeType||"multibezier"===i.edgeType||"self"===i.edgeType||"compound"===i.edgeType)for(x=i.allpts,w=0;w+5(r=Zt(e,t,x[w],x[w+1],x[w+2],x[w+3],x[w+4],x[w+5])))return v(n,r),!0;m=m||a.source,b=b||a.target;var E=o.getArrowWidth(l,c),k=[{name:"source",x:i.arrowStartX,y:i.arrowStartY,angle:i.srcArrowAngle},{name:"target",x:i.arrowEndX,y:i.arrowEndY,angle:i.tgtArrowAngle},{name:"mid-source",x:i.midX,y:i.midY,angle:i.midsrcArrowAngle},{name:"mid-target",x:i.midX,y:i.midY,angle:i.midtgtArrowAngle}];for(w=0;w0&&(y(m),y(b))}function b(e,t,n){return rt(e,t,n)}function x(n,r){var a,i=n._private,o=f;a=r?r+"-":"",n.boundingBox();var s=i.labelBounds[r||"main"],l=n.pstyle(a+"label").value;if("yes"===n.pstyle("text-events").strValue&&l){var u=b(i.rscratch,"labelX",r),c=b(i.rscratch,"labelY",r),d=b(i.rscratch,"labelAngle",r),h=n.pstyle(a+"text-margin-x").pfValue,p=n.pstyle(a+"text-margin-y").pfValue,g=s.x1-o-h,y=s.x2+o-h,m=s.y1-o-p,x=s.y2+o-p;if(d){var w=Math.cos(d),E=Math.sin(d),k=function(e,t){return{x:(e-=u)*w-(t-=c)*E+u,y:e*E+t*w+c}},C=k(g,m),S=k(g,x),P=k(y,m),D=k(y,x),T=[C.x+h,C.y+p,P.x+h,P.y+p,D.x+h,D.y+p,S.x+h,S.y+p];if(Qt(e,t,T))return v(n),!0}else if(Wt(s,e,t))return v(n),!0}}n&&(l=l.interactive);for(var w=l.length-1;w>=0;w--){var E=l[w];E.isNode()?y(E)||x(E):m(E)||x(E)||x(E,"source")||x(E,"target")}return u},getAllInBox:function(e,t,n,r){for(var a,i,o=this.getCachedZSortedEles().interactive,s=[],l=Math.min(e,n),u=Math.max(e,n),c=Math.min(t,r),d=Math.max(t,r),h=Rt({x1:e=l,y1:t=c,x2:n=u,y2:r=d}),p=0;p0?-(Math.PI-i.ang):Math.PI+i.ang),vu(t,n,gu),Jl=fu.nx*gu.ny-fu.ny*gu.nx,eu=fu.nx*gu.nx-fu.ny*-gu.ny,ru=Math.asin(Math.max(-1,Math.min(1,Jl))),Math.abs(ru)<1e-6)return $l=t.x,Ql=t.y,void(iu=su=0);tu=1,nu=!1,eu<0?ru<0?ru=Math.PI+ru:(ru=Math.PI-ru,tu=-1,nu=!0):ru>0&&(tu=-1,nu=!0),su=void 0!==t.radius?t.radius:r,au=ru/2,lu=Math.min(fu.len/2,gu.len/2),a?(ou=Math.abs(Math.cos(au)*su/Math.sin(au)))>lu?(ou=lu,iu=Math.abs(ou*Math.sin(au)/Math.cos(au))):iu=su:(ou=Math.min(lu,su),iu=Math.abs(ou*Math.sin(au)/Math.cos(au))),du=t.x+gu.nx*ou,hu=t.y+gu.ny*ou,$l=du-gu.ny*iu*tu,Ql=hu+gu.nx*iu*tu,uu=t.x+fu.nx*ou,cu=t.y+fu.ny*ou,pu=t};function mu(e,t){0===t.radius?e.lineTo(t.cx,t.cy):e.arc(t.cx,t.cy,t.radius,t.startAngle,t.endAngle,t.counterClockwise)}function bu(e,t,n,r){var a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4];return 0===r||0===t.radius?{cx:t.x,cy:t.y,radius:0,startX:t.x,startY:t.y,stopX:t.x,stopY:t.y,startAngle:void 0,endAngle:void 0,counterClockwise:void 0}:(yu(e,t,n,r,a),{cx:$l,cy:Ql,radius:iu,startX:uu,startY:cu,stopX:du,stopY:hu,startAngle:fu.ang+Math.PI/2*tu,endAngle:gu.ang-Math.PI/2*tu,counterClockwise:nu})}var xu={};function wu(e){var t=[];if(null!=e){for(var n=0;n0?Math.max(e-t,0):Math.min(e+t,0)},D=P(C,E),T=P(S,k),_=!1;"auto"===v?g=Math.abs(D)>Math.abs(T)?a:r:v===l||v===s?(g=r,_=!0):v!==i&&v!==o||(g=a,_=!0);var M,B=g===r,N=B?T:D,z=B?S:C,I=Bt(z),A=!1;(_&&(m||x)||!(v===s&&z<0||v===l&&z>0||v===i&&z>0||v===o&&z<0)||(N=(I*=-1)*Math.abs(N),A=!0),m)?M=(b<0?1+b:b)*N:M=(b<0?N:0)+b*I;var L=function(e){return Math.abs(e)=Math.abs(N)},O=L(M),R=L(Math.abs(N)-Math.abs(M));if((O||R)&&!A)if(B){var V=Math.abs(z)<=d/2,F=Math.abs(C)<=h/2;if(V){var j=(u.x1+u.x2)/2,q=u.y1,Y=u.y2;n.segpts=[j,q,j,Y]}else if(F){var X=(u.y1+u.y2)/2,W=u.x1,H=u.x2;n.segpts=[W,X,H,X]}else n.segpts=[u.x1,u.y2]}else{var K=Math.abs(z)<=c/2,G=Math.abs(S)<=p/2;if(K){var U=(u.y1+u.y2)/2,Z=u.x1,$=u.x2;n.segpts=[Z,U,$,U]}else if(G){var Q=(u.x1+u.x2)/2,J=u.y1,ee=u.y2;n.segpts=[Q,J,Q,ee]}else n.segpts=[u.x2,u.y1]}else if(B){var te=u.y1+M+(f?d/2*I:0),ne=u.x1,re=u.x2;n.segpts=[ne,te,re,te]}else{var ae=u.x1+M+(f?c/2*I:0),ie=u.y1,oe=u.y2;n.segpts=[ae,ie,ae,oe]}if(n.isRound){var se=e.pstyle("taxi-radius").value,le="arc-radius"===e.pstyle("radius-type").value[0];n.radii=new Array(n.segpts.length/2).fill(se),n.isArcRadius=new Array(n.segpts.length/2).fill(le)}},xu.tryToCorrectInvalidPoints=function(e,t){var n=e._private.rscratch;if("bezier"===n.edgeType){var r=t.srcPos,a=t.tgtPos,i=t.srcW,o=t.srcH,s=t.tgtW,l=t.tgtH,u=t.srcShape,c=t.tgtShape,d=t.srcCornerRadius,h=t.tgtCornerRadius,p=t.srcRs,f=t.tgtRs,g=!k(n.startX)||!k(n.startY),v=!k(n.arrowStartX)||!k(n.arrowStartY),y=!k(n.endX)||!k(n.endY),m=!k(n.arrowEndX)||!k(n.arrowEndY),b=3*(this.getArrowWidth(e.pstyle("width").pfValue,e.pstyle("arrow-scale").value)*this.arrowShapeWidth),x=Nt({x:n.ctrlpts[0],y:n.ctrlpts[1]},{x:n.startX,y:n.startY}),w=xh.poolIndex()){var p=d;d=h,h=p}var f=s.srcPos=d.position(),g=s.tgtPos=h.position(),v=s.srcW=d.outerWidth(),y=s.srcH=d.outerHeight(),m=s.tgtW=h.outerWidth(),b=s.tgtH=h.outerHeight(),x=s.srcShape=n.nodeShapes[t.getNodeShape(d)],w=s.tgtShape=n.nodeShapes[t.getNodeShape(h)],E=s.srcCornerRadius="auto"===d.pstyle("corner-radius").value?"auto":d.pstyle("corner-radius").pfValue,C=s.tgtCornerRadius="auto"===h.pstyle("corner-radius").value?"auto":h.pstyle("corner-radius").pfValue,S=s.tgtRs=h._private.rscratch,P=s.srcRs=d._private.rscratch;s.dirCounts={north:0,west:0,south:0,east:0,northwest:0,southwest:0,northeast:0,southeast:0};for(var D=0;D0){var H=u,K=zt(H,Tt(t)),G=zt(H,Tt(W)),U=K;if(G2)zt(H,{x:W[2],y:W[3]})0){var le=c,ue=zt(le,Tt(t)),ce=zt(le,Tt(se)),de=ue;if(ce2)zt(le,{x:se[2],y:se[3]})=u||m){c={cp:g,segment:y};break}}if(c)break}var b=c.cp,x=c.segment,w=(u-h)/x.length,E=x.t1-x.t0,k=s?x.t0+E*w:x.t1-E*w;k=Ot(0,k,1),t=Lt(b.p0,b.p1,b.p2,k),a=function(e,t,n,r){var a=Ot(0,r-.001,1),i=Ot(0,r+.001,1),o=Lt(e,t,n,a),s=Lt(e,t,n,i);return Du(o,s)}(b.p0,b.p1,b.p2,k);break;case"straight":case"segments":case"haystack":for(var C,S,P,D,T=0,_=r.allpts.length,M=0;M+3<_&&(s?(P={x:r.allpts[M],y:r.allpts[M+1]},D={x:r.allpts[M+2],y:r.allpts[M+3]}):(P={x:r.allpts[_-2-M],y:r.allpts[_-1-M]},D={x:r.allpts[_-4-M],y:r.allpts[_-3-M]}),S=T,!((T+=C=Nt(P,D))>=u));M+=2);var B=(u-S)/C;B=Ot(0,B,1),t=function(e,t,n,r){var a=t.x-e.x,i=t.y-e.y,o=Nt(e,t),s=a/o,l=i/o;return n=null==n?0:n,r=null!=r?r:n*o,{x:e.x+s*r,y:e.y+l*r}}(P,D,B),a=Du(P,D)}o("labelX",n,t.x),o("labelY",n,t.y),o("labelAutoAngle",n,a)}};u("source"),u("target"),this.applyLabelDimensions(e)}},Su.applyLabelDimensions=function(e){this.applyPrefixedLabelDimensions(e),e.isEdge()&&(this.applyPrefixedLabelDimensions(e,"source"),this.applyPrefixedLabelDimensions(e,"target"))},Su.applyPrefixedLabelDimensions=function(e,t){var n=e._private,r=this.getLabelText(e,t),a=this.calculateLabelDimensions(e,r),i=e.pstyle("line-height").pfValue,o=e.pstyle("text-wrap").strValue,s=rt(n.rscratch,"labelWrapCachedLines",t)||[],l="wrap"!==o?1:Math.max(s.length,1),u=a.height/l,c=u*i,d=a.width,h=a.height+(l-1)*(i-1)*u;at(n.rstyle,"labelWidth",t,d),at(n.rscratch,"labelWidth",t,d),at(n.rstyle,"labelHeight",t,h),at(n.rscratch,"labelHeight",t,h),at(n.rscratch,"labelLineHeight",t,c)},Su.getLabelText=function(e,t){var n=e._private,r=t?t+"-":"",a=e.pstyle(r+"label").strValue,i=e.pstyle("text-transform").value,o=function(e,r){return r?(at(n.rscratch,e,t,r),r):rt(n.rscratch,e,t)};if(!a)return"";"none"==i||("uppercase"==i?a=a.toUpperCase():"lowercase"==i&&(a=a.toLowerCase()));var s=e.pstyle("text-wrap").value;if("wrap"===s){var l=o("labelKey");if(null!=l&&o("labelWrapKey")===l)return o("labelWrapCachedText");for(var u=a.split("\n"),c=e.pstyle("text-max-width").pfValue,h="anywhere"===e.pstyle("text-overflow-wrap").value,p=[],f=/[\s\u200b]+|$/g,g=0;gc){var b,x="",w=0,E=d(v.matchAll(f));try{for(E.s();!(b=E.n()).done;){var k=b.value,C=k[0],S=v.substring(w,k.index);w=k.index+C.length;var P=0===x.length?S:x+S+C;this.calculateLabelDimensions(e,P).width<=c?x+=S+C:(x&&p.push(x),x=S+C)}}catch(B){E.e(B)}finally{E.f()}x.match(/^[\s\u200b]+$/)||p.push(x)}else p.push(v)}o("labelWrapCachedLines",p),a=o("labelWrapCachedText",p.join("\n")),o("labelWrapKey",l)}else if("ellipsis"===s){var D=e.pstyle("text-max-width").pfValue,T="",_=!1;if(this.calculateLabelDimensions(e,a).widthD)break;T+=a[M],M===a.length-1&&(_=!0)}return _||(T+="\u2026"),T}return a},Su.getLabelJustification=function(e){var t=e.pstyle("text-justification").strValue,n=e.pstyle("text-halign").strValue;if("auto"!==t)return t;if(!e.isNode())return"center";switch(n){case"left":return"right";case"right":return"left";default:return"center"}},Su.calculateLabelDimensions=function(e,t){var n=this,r=n.cy.window().document,a=Le(t,e._private.labelDimsKey),i=n.labelDimCache||(n.labelDimCache=[]),o=i[a];if(null!=o)return o;var s=e.pstyle("font-style").strValue,l=e.pstyle("font-size").pfValue,u=e.pstyle("font-family").strValue,c=e.pstyle("font-weight").strValue,d=this.labelCalcCanvas,h=this.labelCalcCanvasContext;if(!d){d=this.labelCalcCanvas=r.createElement("canvas"),h=this.labelCalcCanvasContext=d.getContext("2d");var p=d.style;p.position="absolute",p.left="-9999px",p.top="-9999px",p.zIndex="-1",p.visibility="hidden",p.pointerEvents="none"}h.font="".concat(s," ").concat(c," ").concat(l,"px ").concat(u);for(var f=0,g=0,v=t.split("\n"),y=0;y1&&void 0!==arguments[1])||arguments[1];if(t.merge(e),n)for(var r=0;r=e.desktopTapThreshold2}var D=a(t);v&&(e.hoverData.tapholdCancelled=!0);n=!0,r(g,["mousemove","vmousemove","tapdrag"],t,{x:c[0],y:c[1]});var T=function(){e.data.bgActivePosistion=void 0,e.hoverData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:c[0],y:c[1]}}),f[4]=1,e.hoverData.selecting=!0,e.redrawHint("select",!0),e.redraw()};if(3===e.hoverData.which){if(v){var _={originalEvent:t,type:"cxtdrag",position:{x:c[0],y:c[1]}};b?b.emit(_):o.emit(_),e.hoverData.cxtDragged=!0,e.hoverData.cxtOver&&g===e.hoverData.cxtOver||(e.hoverData.cxtOver&&e.hoverData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:c[0],y:c[1]}}),e.hoverData.cxtOver=g,g&&g.emit({originalEvent:t,type:"cxtdragover",position:{x:c[0],y:c[1]}}))}}else if(e.hoverData.dragging){if(n=!0,o.panningEnabled()&&o.userPanningEnabled()){var M;if(e.hoverData.justStartedPan){var B=e.hoverData.mdownPos;M={x:(c[0]-B[0])*s,y:(c[1]-B[1])*s},e.hoverData.justStartedPan=!1}else M={x:x[0]*s,y:x[1]*s};o.panBy(M),o.emit("dragpan"),e.hoverData.dragged=!0}c=e.projectIntoViewport(t.clientX,t.clientY)}else if(1!=f[4]||null!=b&&!b.pannable()){if(b&&b.pannable()&&b.active()&&b.unactivate(),b&&b.grabbed()||g==y||(y&&r(y,["mouseout","tapdragout"],t,{x:c[0],y:c[1]}),g&&r(g,["mouseover","tapdragover"],t,{x:c[0],y:c[1]}),e.hoverData.last=g),b)if(v){if(o.boxSelectionEnabled()&&D)b&&b.grabbed()&&(d(w),b.emit("freeon"),w.emit("free"),e.dragData.didDrag&&(b.emit("dragfreeon"),w.emit("dragfree"))),T();else if(b&&b.grabbed()&&e.nodeIsDraggable(b)){var N=!e.dragData.didDrag;N&&e.redrawHint("eles",!0),e.dragData.didDrag=!0,e.hoverData.draggingEles||u(w,{inDragLayer:!0});var z={x:0,y:0};if(k(x[0])&&k(x[1])&&(z.x+=x[0],z.y+=x[1],N)){var I=e.hoverData.dragDelta;I&&k(I[0])&&k(I[1])&&(z.x+=I[0],z.y+=I[1])}e.hoverData.draggingEles=!0,w.silentShift(z).emit("position drag"),e.redrawHint("drag",!0),e.redraw()}}else!function(){var t=e.hoverData.dragDelta=e.hoverData.dragDelta||[];0===t.length?(t.push(x[0]),t.push(x[1])):(t[0]+=x[0],t[1]+=x[1])}();n=!0}else if(v){if(e.hoverData.dragging||!o.boxSelectionEnabled()||!D&&o.panningEnabled()&&o.userPanningEnabled()){if(!e.hoverData.selecting&&o.panningEnabled()&&o.userPanningEnabled()){i(b,e.hoverData.downs)&&(e.hoverData.dragging=!0,e.hoverData.justStartedPan=!0,f[4]=0,e.data.bgActivePosistion=Tt(h),e.redrawHint("select",!0),e.redraw())}}else T();b&&b.pannable()&&b.active()&&b.unactivate()}return f[2]=c[0],f[3]=c[1],n?(t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),!1):void 0}}),!1),e.registerBinding(t,"mouseup",(function(t){if((1!==e.hoverData.which||1===t.which||!e.hoverData.capture)&&e.hoverData.capture){e.hoverData.capture=!1;var i=e.cy,o=e.projectIntoViewport(t.clientX,t.clientY),s=e.selection,l=e.findNearestElement(o[0],o[1],!0,!1),u=e.dragData.possibleDragElements,c=e.hoverData.down,h=a(t);if(e.data.bgActivePosistion&&(e.redrawHint("select",!0),e.redraw()),e.hoverData.tapholdCancelled=!0,e.data.bgActivePosistion=void 0,c&&c.unactivate(),3===e.hoverData.which){var p={originalEvent:t,type:"cxttapend",position:{x:o[0],y:o[1]}};if(c?c.emit(p):i.emit(p),!e.hoverData.cxtDragged){var f={originalEvent:t,type:"cxttap",position:{x:o[0],y:o[1]}};c?c.emit(f):i.emit(f)}e.hoverData.cxtDragged=!1,e.hoverData.which=null}else if(1===e.hoverData.which){if(r(l,["mouseup","tapend","vmouseup"],t,{x:o[0],y:o[1]}),e.dragData.didDrag||e.hoverData.dragged||e.hoverData.selecting||e.hoverData.isOverThresholdDrag||(r(c,["click","tap","vclick"],t,{x:o[0],y:o[1]}),x=!1,t.timeStamp-w<=i.multiClickDebounceTime()?(b&&clearTimeout(b),x=!0,w=null,r(c,["dblclick","dbltap","vdblclick"],t,{x:o[0],y:o[1]})):(b=setTimeout((function(){x||r(c,["oneclick","onetap","voneclick"],t,{x:o[0],y:o[1]})}),i.multiClickDebounceTime()),w=t.timeStamp)),null!=c||e.dragData.didDrag||e.hoverData.selecting||e.hoverData.dragged||a(t)||(i.$(n).unselect(["tapunselect"]),u.length>0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=u=i.collection()),l!=c||e.dragData.didDrag||e.hoverData.selecting||null!=l&&l._private.selectable&&(e.hoverData.dragging||("additive"===i.selectionType()||h?l.selected()?l.unselect(["tapunselect"]):l.select(["tapselect"]):h||(i.$(n).unmerge(l).unselect(["tapunselect"]),l.select(["tapselect"]))),e.redrawHint("eles",!0)),e.hoverData.selecting){var g=i.collection(e.getAllInBox(s[0],s[1],s[2],s[3]));e.redrawHint("select",!0),g.length>0&&e.redrawHint("eles",!0),i.emit({type:"boxend",originalEvent:t,position:{x:o[0],y:o[1]}});var v=function(e){return e.selectable()&&!e.selected()};"additive"===i.selectionType()||h||i.$(n).unmerge(g).unselect(),g.emit("box").stdFilter(v).select().emit("boxselect"),e.redraw()}if(e.hoverData.dragging&&(e.hoverData.dragging=!1,e.redrawHint("select",!0),e.redrawHint("eles",!0),e.redraw()),!s[4]){e.redrawHint("drag",!0),e.redrawHint("eles",!0);var y=c&&c.grabbed();d(u),y&&(c.emit("freeon"),u.emit("free"),e.dragData.didDrag&&(c.emit("dragfreeon"),u.emit("dragfree")))}}s[4]=0,e.hoverData.down=null,e.hoverData.cxtStarted=!1,e.hoverData.draggingEles=!1,e.hoverData.selecting=!1,e.hoverData.isOverThresholdDrag=!1,e.dragData.didDrag=!1,e.hoverData.dragged=!1,e.hoverData.dragDelta=[],e.hoverData.mdownPos=null,e.hoverData.mdownGPos=null,e.hoverData.which=null}}),!1);var C,S,P,D,T,_,M,B,N,z,I,A,L,O=function(t){if(!e.scrollingPage){var n=e.cy,r=n.zoom(),a=n.pan(),i=e.projectIntoViewport(t.clientX,t.clientY),o=[i[0]*r+a.x,i[1]*r+a.y];if(e.hoverData.draggingEles||e.hoverData.dragging||e.hoverData.cxtStarted||0!==e.selection[4])t.preventDefault();else if(n.panningEnabled()&&n.userPanningEnabled()&&n.zoomingEnabled()&&n.userZoomingEnabled()){var s;t.preventDefault(),e.data.wheelZooming=!0,clearTimeout(e.data.wheelTimeout),e.data.wheelTimeout=setTimeout((function(){e.data.wheelZooming=!1,e.redrawHint("eles",!0),e.redraw()}),150),s=null!=t.deltaY?t.deltaY/-250:null!=t.wheelDeltaY?t.wheelDeltaY/1e3:t.wheelDelta/1e3,s*=e.wheelSensitivity,1===t.deltaMode&&(s*=33);var l=n.zoom()*Math.pow(10,s);"gesturechange"===t.type&&(l=e.gestureStartZoom*t.scale),n.zoom({level:l,renderedPosition:{x:o[0],y:o[1]}}),n.emit("gesturechange"===t.type?"pinchzoom":"scrollzoom")}}};e.registerBinding(e.container,"wheel",O,!0),e.registerBinding(t,"scroll",(function(t){e.scrollingPage=!0,clearTimeout(e.scrollingPageTimeout),e.scrollingPageTimeout=setTimeout((function(){e.scrollingPage=!1}),250)}),!0),e.registerBinding(e.container,"gesturestart",(function(t){e.gestureStartZoom=e.cy.zoom(),e.hasTouchStarted||t.preventDefault()}),!0),e.registerBinding(e.container,"gesturechange",(function(t){e.hasTouchStarted||O(t)}),!0),e.registerBinding(e.container,"mouseout",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseout",position:{x:n[0],y:n[1]}})}),!1),e.registerBinding(e.container,"mouseover",(function(t){var n=e.projectIntoViewport(t.clientX,t.clientY);e.cy.emit({originalEvent:t,type:"mouseover",position:{x:n[0],y:n[1]}})}),!1);var R,V,F,j,q,Y,X,W=function(e,t,n,r){return Math.sqrt((n-e)*(n-e)+(r-t)*(r-t))},H=function(e,t,n,r){return(n-e)*(n-e)+(r-t)*(r-t)};if(e.registerBinding(e.container,"touchstart",R=function(t){if(e.hasTouchStarted=!0,m(t)){p(),e.touchData.capture=!0,e.data.bgActivePosistion=void 0;var n=e.cy,a=e.touchData.now,i=e.touchData.earlier;if(t.touches[0]){var o=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);a[0]=o[0],a[1]=o[1]}if(t.touches[1]){o=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);a[2]=o[0],a[3]=o[1]}if(t.touches[2]){o=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);a[4]=o[0],a[5]=o[1]}if(t.touches[1]){e.touchData.singleTouchMoved=!0,d(e.dragData.touchDragEles);var l=e.findContainerClientCoords();N=l[0],z=l[1],I=l[2],A=l[3],C=t.touches[0].clientX-N,S=t.touches[0].clientY-z,P=t.touches[1].clientX-N,D=t.touches[1].clientY-z,L=0<=C&&C<=I&&0<=P&&P<=I&&0<=S&&S<=A&&0<=D&&D<=A;var h=n.pan(),f=n.zoom();T=W(C,S,P,D),_=H(C,S,P,D),B=[((M=[(C+P)/2,(S+D)/2])[0]-h.x)/f,(M[1]-h.y)/f];if(_<4e4&&!t.touches[2]){var g=e.findNearestElement(a[0],a[1],!0,!0),v=e.findNearestElement(a[2],a[3],!0,!0);return g&&g.isNode()?(g.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}}),e.touchData.start=g):v&&v.isNode()?(v.activate().emit({originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}}),e.touchData.start=v):n.emit({originalEvent:t,type:"cxttapstart",position:{x:a[0],y:a[1]}}),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(t.touches[2])n.boxSelectionEnabled()&&t.preventDefault();else if(t.touches[1]);else if(t.touches[0]){var y=e.findNearestElements(a[0],a[1],!0,!0),b=y[0];if(null!=b&&(b.activate(),e.touchData.start=b,e.touchData.starts=y,e.nodeIsGrabbable(b))){var x=e.dragData.touchDragEles=n.collection(),w=null;e.redrawHint("eles",!0),e.redrawHint("drag",!0),b.selected()?(w=n.$((function(t){return t.selected()&&e.nodeIsGrabbable(t)})),u(w,{addToList:x})):c(b,{addToList:x}),s(b);var E=function(e){return{originalEvent:t,type:e,position:{x:a[0],y:a[1]}}};b.emit(E("grabon")),w?w.forEach((function(e){e.emit(E("grab"))})):b.emit(E("grab"))}r(b,["touchstart","tapstart","vmousedown"],t,{x:a[0],y:a[1]}),null==b&&(e.data.bgActivePosistion={x:o[0],y:o[1]},e.redrawHint("select",!0),e.redraw()),e.touchData.singleTouchMoved=!1,e.touchData.singleTouchStartTime=+new Date,clearTimeout(e.touchData.tapholdTimeout),e.touchData.tapholdTimeout=setTimeout((function(){!1!==e.touchData.singleTouchMoved||e.pinching||e.touchData.selecting||r(e.touchData.start,["taphold"],t,{x:a[0],y:a[1]})}),e.tapholdDuration)}if(t.touches.length>=1){for(var k=e.touchData.startPosition=[null,null,null,null,null,null],O=0;O=e.touchTapThreshold2}if(n&&e.touchData.cxt){t.preventDefault();var w=t.touches[0].clientX-N,E=t.touches[0].clientY-z,M=t.touches[1].clientX-N,I=t.touches[1].clientY-z,A=H(w,E,M,I);if(A/_>=2.25||A>=22500){e.touchData.cxt=!1,e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var O={originalEvent:t,type:"cxttapend",position:{x:s[0],y:s[1]}};e.touchData.start?(e.touchData.start.unactivate().emit(O),e.touchData.start=null):o.emit(O)}}if(n&&e.touchData.cxt){O={originalEvent:t,type:"cxtdrag",position:{x:s[0],y:s[1]}};e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.emit(O):o.emit(O),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var R=e.findNearestElement(s[0],s[1],!0,!0);e.touchData.cxtOver&&R===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.emit({originalEvent:t,type:"cxtdragout",position:{x:s[0],y:s[1]}}),e.touchData.cxtOver=R,R&&R.emit({originalEvent:t,type:"cxtdragover",position:{x:s[0],y:s[1]}}))}else if(n&&t.touches[2]&&o.boxSelectionEnabled())t.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting||o.emit({originalEvent:t,type:"boxstart",position:{x:s[0],y:s[1]}}),e.touchData.selecting=!0,e.touchData.didSelect=!0,a[4]=1,a&&0!==a.length&&void 0!==a[0]?(a[2]=(s[0]+s[2]+s[4])/3,a[3]=(s[1]+s[3]+s[5])/3):(a[0]=(s[0]+s[2]+s[4])/3,a[1]=(s[1]+s[3]+s[5])/3,a[2]=(s[0]+s[2]+s[4])/3+1,a[3]=(s[1]+s[3]+s[5])/3+1),e.redrawHint("select",!0),e.redraw();else if(n&&t.touches[1]&&!e.touchData.didSelect&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){if(t.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),ee=e.dragData.touchDragEles){e.redrawHint("drag",!0);for(var V=0;V0&&!e.hoverData.draggingEles&&!e.swipePanning&&null!=e.data.bgActivePosistion&&(e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.redraw())}},!1),e.registerBinding(t,"touchcancel",F=function(t){var n=e.touchData.start;e.touchData.capture=!1,n&&n.unactivate()}),e.registerBinding(t,"touchend",j=function(t){var a=e.touchData.start;if(e.touchData.capture){0===t.touches.length&&(e.touchData.capture=!1),t.preventDefault();var i=e.selection;e.swipePanning=!1,e.hoverData.draggingEles=!1;var o,s=e.cy,l=s.zoom(),u=e.touchData.now,c=e.touchData.earlier;if(t.touches[0]){var h=e.projectIntoViewport(t.touches[0].clientX,t.touches[0].clientY);u[0]=h[0],u[1]=h[1]}if(t.touches[1]){h=e.projectIntoViewport(t.touches[1].clientX,t.touches[1].clientY);u[2]=h[0],u[3]=h[1]}if(t.touches[2]){h=e.projectIntoViewport(t.touches[2].clientX,t.touches[2].clientY);u[4]=h[0],u[5]=h[1]}if(a&&a.unactivate(),e.touchData.cxt){if(o={originalEvent:t,type:"cxttapend",position:{x:u[0],y:u[1]}},a?a.emit(o):s.emit(o),!e.touchData.cxtDragged){var p={originalEvent:t,type:"cxttap",position:{x:u[0],y:u[1]}};a?a.emit(p):s.emit(p)}return e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!1,e.touchData.start=null,void e.redraw()}if(!t.touches[2]&&s.boxSelectionEnabled()&&e.touchData.selecting){e.touchData.selecting=!1;var f=s.collection(e.getAllInBox(i[0],i[1],i[2],i[3]));i[0]=void 0,i[1]=void 0,i[2]=void 0,i[3]=void 0,i[4]=0,e.redrawHint("select",!0),s.emit({type:"boxend",originalEvent:t,position:{x:u[0],y:u[1]}});f.emit("box").stdFilter((function(e){return e.selectable()&&!e.selected()})).select().emit("boxselect"),f.nonempty()&&e.redrawHint("eles",!0),e.redraw()}if(null!=a&&a.unactivate(),t.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(t.touches[1]);else if(t.touches[0]);else if(!t.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var g=e.dragData.touchDragEles;if(null!=a){var v=a._private.grabbed;d(g),e.redrawHint("drag",!0),e.redrawHint("eles",!0),v&&(a.emit("freeon"),g.emit("free"),e.dragData.didDrag&&(a.emit("dragfreeon"),g.emit("dragfree"))),r(a,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]}),a.unactivate(),e.touchData.start=null}else{var y=e.findNearestElement(u[0],u[1],!0,!0);r(y,["touchend","tapend","vmouseup","tapdragout"],t,{x:u[0],y:u[1]})}var m=e.touchData.startPosition[0]-u[0],b=m*m,x=e.touchData.startPosition[1]-u[1],w=(b+x*x)*l*l;e.touchData.singleTouchMoved||(a||s.$(":selected").unselect(["tapunselect"]),r(a,["tap","vclick"],t,{x:u[0],y:u[1]}),q=!1,t.timeStamp-X<=s.multiClickDebounceTime()?(Y&&clearTimeout(Y),q=!0,X=null,r(a,["dbltap","vdblclick"],t,{x:u[0],y:u[1]})):(Y=setTimeout((function(){q||r(a,["onetap","voneclick"],t,{x:u[0],y:u[1]})}),s.multiClickDebounceTime()),X=t.timeStamp)),null!=a&&!e.dragData.didDrag&&a._private.selectable&&w2){for(var p=[c[0],c[1]],f=Math.pow(p[0]-e,2)+Math.pow(p[1]-t,2),g=1;g0)return g[0]}return null},p=Object.keys(d),f=0;f0?u:Kt(a,i,e,t,n,r,o,s)},checkPoint:function(e,t,n,r,a,i,o,s){var l=2*(s="auto"===s?hn(r,a):s);if(Jt(e,t,this.points,i,o,r,a-l,[0,-1],n))return!0;if(Jt(e,t,this.points,i,o,r-l,a,[0,-1],n))return!0;var u=r/2+2*n,c=a/2+2*n;return!!Qt(e,t,[i-u,o-c,i-u,o,i+u,o,i+u,o-c])||(!!nn(e,t,l,l,i+r/2-s,o+a/2-s,n)||!!nn(e,t,l,l,i-r/2+s,o+a/2-s,n))}}},Au.registerNodeShapes=function(){var e=this.nodeShapes={},t=this;this.generateEllipse(),this.generatePolygon("triangle",un(3,0)),this.generateRoundPolygon("round-triangle",un(3,0)),this.generatePolygon("rectangle",un(4,0)),e.square=e.rectangle,this.generateRoundRectangle(),this.generateCutRectangle(),this.generateBarrel(),this.generateBottomRoundrectangle();var n=[0,1,1,0,0,-1,-1,0];this.generatePolygon("diamond",n),this.generateRoundPolygon("round-diamond",n),this.generatePolygon("pentagon",un(5,0)),this.generateRoundPolygon("round-pentagon",un(5,0)),this.generatePolygon("hexagon",un(6,0)),this.generateRoundPolygon("round-hexagon",un(6,0)),this.generatePolygon("heptagon",un(7,0)),this.generateRoundPolygon("round-heptagon",un(7,0)),this.generatePolygon("octagon",un(8,0)),this.generateRoundPolygon("round-octagon",un(8,0));var r=new Array(20),a=dn(5,0),i=dn(5,Math.PI/5),o=.5*(3-Math.sqrt(5));o*=1.57;for(var s=0;s=e.deqFastCost*g)break}else if(a){if(p>=e.deqCost*l||p>=e.deqAvgCost*s)break}else if(f>=e.deqNoDrawCost*Fu)break;var v=e.deq(t,d,c);if(!(v.length>0))break;for(var y=0;y0&&(e.onDeqd(t,u),!a&&e.shouldRedraw(t,u,d,c)&&r())}),a(t))}}},qu=function(){function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:Xe;a(this,e),this.idsByKey=new it,this.keyForId=new it,this.cachesByLvl=new it,this.lvls=[],this.getKey=t,this.doesEleInvalidateKey=n}return o(e,[{key:"getIdsFor",value:function(e){null==e&&Ke("Can not get id list for null key");var t=this.idsByKey,n=this.idsByKey.get(e);return n||(n=new st,t.set(e,n)),n}},{key:"addIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).add(t)}},{key:"deleteIdForKey",value:function(e,t){null!=e&&this.getIdsFor(e).delete(t)}},{key:"getNumberOfIdsForKey",value:function(e){return null==e?0:this.getIdsFor(e).size}},{key:"updateKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t),r=this.getKey(e);this.deleteIdForKey(n,t),this.addIdForKey(r,t),this.keyForId.set(t,r)}},{key:"deleteKeyMappingFor",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteIdForKey(n,t),this.keyForId.delete(t)}},{key:"keyHasChangedFor",value:function(e){var t=e.id();return this.keyForId.get(t)!==this.getKey(e)}},{key:"isInvalid",value:function(e){return this.keyHasChangedFor(e)||this.doesEleInvalidateKey(e)}},{key:"getCachesAt",value:function(e){var t=this.cachesByLvl,n=this.lvls,r=t.get(e);return r||(r=new it,t.set(e,r),n.push(e)),r}},{key:"getCache",value:function(e,t){return this.getCachesAt(t).get(e)}},{key:"get",value:function(e,t){var n=this.getKey(e),r=this.getCache(n,t);return null!=r&&this.updateKeyMappingFor(e),r}},{key:"getForCachedKey",value:function(e,t){var n=this.keyForId.get(e.id());return this.getCache(n,t)}},{key:"hasCache",value:function(e,t){return this.getCachesAt(t).has(e)}},{key:"has",value:function(e,t){var n=this.getKey(e);return this.hasCache(n,t)}},{key:"setCache",value:function(e,t,n){n.key=e,this.getCachesAt(t).set(e,n)}},{key:"set",value:function(e,t,n){var r=this.getKey(e);this.setCache(r,t,n),this.updateKeyMappingFor(e)}},{key:"deleteCache",value:function(e,t){this.getCachesAt(t).delete(e)}},{key:"delete",value:function(e,t){var n=this.getKey(e);this.deleteCache(n,t)}},{key:"invalidateKey",value:function(e){var t=this;this.lvls.forEach((function(n){return t.deleteCache(e,n)}))}},{key:"invalidate",value:function(e){var t=e.id(),n=this.keyForId.get(t);this.deleteKeyMappingFor(e);var r=this.doesEleInvalidateKey(e);return r&&this.invalidateKey(n),r||0===this.getNumberOfIdsForKey(n)}}]),e}(),Yu={dequeue:"dequeue",downscale:"downscale",highQuality:"highQuality"},Xu=et({getKey:null,doesEleInvalidateKey:Xe,drawElement:null,getBoundingBox:null,getRotationPoint:null,getRotationOffset:null,isVisible:Ye,allowEdgeTxrCaching:!0,allowParentTxrCaching:!0}),Wu=function(e,t){var n=this;n.renderer=e,n.onDequeues=[];var r=Xu(t);Y(n,r),n.lookup=new qu(r.getKey,r.doesEleInvalidateKey),n.setupDequeueing()},Hu=Wu.prototype;Hu.reasons=Yu,Hu.getTextureQueue=function(e){var t=this;return t.eleImgCaches=t.eleImgCaches||{},t.eleImgCaches[e]=t.eleImgCaches[e]||[]},Hu.getRetiredTextureQueue=function(e){var t=this.eleImgCaches.retired=this.eleImgCaches.retired||{};return t[e]=t[e]||[]},Hu.getElementQueue=function(){return this.eleCacheQueue=this.eleCacheQueue||new ht((function(e,t){return t.reqs-e.reqs}))},Hu.getElementKeyToQueue=function(){return this.eleKeyToCacheQueue=this.eleKeyToCacheQueue||{}},Hu.getElement=function(e,t,n,r,a){var i=this,o=this.renderer,s=o.cy.zoom(),l=this.lookup;if(!t||0===t.w||0===t.h||isNaN(t.w)||isNaN(t.h)||!e.visible()||e.removed())return null;if(!i.allowEdgeTxrCaching&&e.isEdge()||!i.allowParentTxrCaching&&e.isParent())return null;if(null==r&&(r=Math.ceil(Mt(s*n))),r<-4)r=-4;else if(s>=7.99||r>3)return null;var u=Math.pow(2,r),c=t.h*u,d=t.w*u,h=o.eleTextBiggerThanMin(e,u);if(!this.isVisible(e,h))return null;var p,f=l.get(e,r);if(f&&f.invalidated&&(f.invalidated=!1,f.texture.invalidatedWidth-=f.width),f)return f;if(p=c<=25?25:c<=50?50:50*Math.ceil(c/50),c>1024||d>1024)return null;var g=i.getTextureQueue(p),v=g[g.length-2],y=function(){return i.recycleTexture(p,d)||i.addTexture(p,d)};v||(v=g[g.length-1]),v||(v=y()),v.width-v.usedWidthr;D--)S=i.getElement(e,t,n,D,Yu.downscale);P()}else{var T;if(!x&&!w&&!E)for(var _=r-1;_>=-4;_--){var M=l.get(e,_);if(M){T=M;break}}if(b(T))return i.queueElement(e,r),T;v.context.translate(v.usedWidth,0),v.context.scale(u,u),this.drawElement(v.context,e,t,h,!1),v.context.scale(1/u,1/u),v.context.translate(-v.usedWidth,0)}return f={x:v.usedWidth,texture:v,level:r,scale:u,width:d,height:c,scaledLabelShown:h},v.usedWidth+=Math.ceil(d+8),v.eleCaches.push(f),l.set(e,r,f),i.checkTextureFullness(v),f},Hu.invalidateElements=function(e){for(var t=0;t=.2*e.width&&this.retireTexture(e)},Hu.checkTextureFullness=function(e){var t=this.getTextureQueue(e.height);e.usedWidth/e.width>.8&&e.fullnessChecks>=10?tt(t,e):e.fullnessChecks++},Hu.retireTexture=function(e){var t=e.height,n=this.getTextureQueue(t),r=this.lookup;tt(n,e),e.retired=!0;for(var a=e.eleCaches,i=0;i=t)return i.retired=!1,i.usedWidth=0,i.invalidatedWidth=0,i.fullnessChecks=0,nt(i.eleCaches),i.context.setTransform(1,0,0,1,0,0),i.context.clearRect(0,0,i.width,i.height),tt(r,i),n.push(i),i}},Hu.queueElement=function(e,t){var n=this.getElementQueue(),r=this.getElementKeyToQueue(),a=this.getKey(e),i=r[a];if(i)i.level=Math.max(i.level,t),i.eles.merge(e),i.reqs++,n.updateItem(i);else{var o={eles:e.spawn().merge(e),level:t,reqs:1,key:a};n.push(o),r[a]=o}},Hu.dequeue=function(e){for(var t=this,n=t.getElementQueue(),r=t.getElementKeyToQueue(),a=[],i=t.lookup,o=0;o<1&&n.size()>0;o++){var s=n.pop(),l=s.key,u=s.eles[0],c=i.hasCache(u,s.level);if(r[l]=null,!c){a.push(s);var d=t.getBoundingBox(u);t.getElement(u,d,e,s.level,Yu.dequeue)}}return a},Hu.removeFromQueue=function(e){var t=this.getElementQueue(),n=this.getElementKeyToQueue(),r=this.getKey(e),a=n[r];null!=a&&(1===a.eles.length?(a.reqs=qe,t.updateItem(a),t.pop(),n[r]=null):a.eles.unmerge(e))},Hu.onDequeue=function(e){this.onDequeues.push(e)},Hu.offDequeue=function(e){tt(this.onDequeues,e)},Hu.setupDequeueing=ju({deqRedrawThreshold:100,deqCost:.15,deqAvgCost:.1,deqNoDrawCost:.9,deqFastCost:.9,deq:function(e,t,n){return e.dequeue(t,n)},onDeqd:function(e,t){for(var n=0;n=3.99||n>2)return null;r.validateLayersElesOrdering(n,e);var o,s,l=r.layersByLevel,u=Math.pow(2,n),c=l[n]=l[n]||[];if(r.levelIsComplete(n,e))return c;!function(){var t=function(t){if(r.validateLayersElesOrdering(t,e),r.levelIsComplete(t,e))return s=l[t],!0},a=function(e){if(!s)for(var r=n+e;-4<=r&&r<=2&&!t(r);r+=e);};a(1),a(-1);for(var i=c.length-1;i>=0;i--){var o=c[i];o.invalid&&tt(c,o)}}();var d=function(t){var a=(t=t||{}).after;!function(){if(!o){o=Rt();for(var t=0;t32767||s>32767)return null;if(i*s>16e6)return null;var l=r.makeLayer(o,n);if(null!=a){var d=c.indexOf(a)+1;c.splice(d,0,l)}else(void 0===t.insert||t.insert)&&c.unshift(l);return l};if(r.skipping&&!i)return null;for(var h=null,p=e.length/1,f=!i,g=0;g=p||!Ht(h.bb,v.boundingBox()))&&!(h=d({insert:!0,after:h})))return null;s||f?r.queueLayer(h,v):r.drawEleInLayer(h,v,n,t),h.eles.push(v),m[n]=h}}return s||(f?null:c)},Gu.getEleLevelForLayerLevel=function(e,t){return e},Gu.drawEleInLayer=function(e,t,n,r){var a=this.renderer,i=e.context,o=t.boundingBox();0!==o.w&&0!==o.h&&t.visible()&&(n=this.getEleLevelForLayerLevel(n,r),a.setImgSmoothing(i,!1),a.drawCachedElement(i,t,null,null,n,true),a.setImgSmoothing(i,!0))},Gu.levelIsComplete=function(e,t){var n=this.layersByLevel[e];if(!n||0===n.length)return!1;for(var r=0,a=0;a0)return!1;if(i.invalid)return!1;r+=i.eles.length}return r===t.length},Gu.validateLayersElesOrdering=function(e,t){var n=this.layersByLevel[e];if(n)for(var r=0;r0){e=!0;break}}return e},Gu.invalidateElements=function(e){var t=this;0!==e.length&&(t.lastInvalidationTime=Te(),0!==e.length&&t.haveLayers()&&t.updateElementsInLayers(e,(function(e,n,r){t.invalidateLayer(e)})))},Gu.invalidateLayer=function(e){if(this.lastInvalidationTime=Te(),!e.invalid){var t=e.level,n=e.eles,r=this.layersByLevel[t];tt(r,e),e.elesQueue=[],e.invalid=!0,e.replacement&&(e.replacement.invalid=!0);for(var a=0;a3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],o=this,s=t._private.rscratch;if((!i||t.visible())&&!s.badLine&&null!=s.allpts&&!isNaN(s.allpts[0])){var l;n&&(l=n,e.translate(-l.x1,-l.y1));var u=i?t.pstyle("opacity").value:1,c=i?t.pstyle("line-opacity").value:1,d=t.pstyle("curve-style").value,h=t.pstyle("line-style").value,p=t.pstyle("width").pfValue,f=t.pstyle("line-cap").value,g=t.pstyle("line-outline-width").value,v=t.pstyle("line-outline-color").value,y=u*c,m=u*c,b=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;"straight-triangle"===d?(o.eleStrokeStyle(e,t,n),o.drawEdgeTrianglePath(t,e,s.allpts)):(e.lineWidth=p,e.lineCap=f,o.eleStrokeStyle(e,t,n),o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")},x=function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:m;o.drawArrowheads(e,t,n)};if(e.lineJoin="round","yes"===t.pstyle("ghost").value){var w=t.pstyle("ghost-offset-x").pfValue,E=t.pstyle("ghost-offset-y").pfValue,k=t.pstyle("ghost-opacity").value,C=y*k;e.translate(w,E),b(C),x(C),e.translate(-w,-E)}else!function(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:y;e.lineWidth=p+g,e.lineCap=f,g>0?(o.colorStrokeStyle(e,v[0],v[1],v[2],n),"straight-triangle"===d?o.drawEdgeTrianglePath(t,e,s.allpts):(o.drawEdgePath(t,e,s.allpts,h),e.lineCap="butt")):e.lineCap="butt"}();a&&o.drawEdgeUnderlay(e,t),b(),x(),a&&o.drawEdgeOverlay(e,t),o.drawElementText(e,t,null,r),n&&e.translate(l.x1,l.y1)}}},hc=function(e){if(!["overlay","underlay"].includes(e))throw new Error("Invalid state");return function(t,n){if(n.visible()){var r=n.pstyle("".concat(e,"-opacity")).value;if(0!==r){var a=this,i=a.usePaths(),o=n._private.rscratch,s=2*n.pstyle("".concat(e,"-padding")).pfValue,l=n.pstyle("".concat(e,"-color")).value;t.lineWidth=s,"self"!==o.edgeType||i?t.lineCap="round":t.lineCap="butt",a.colorStrokeStyle(t,l[0],l[1],l[2],r),a.drawEdgePath(n,t,o.allpts,"solid")}}}};dc.drawEdgeOverlay=hc("overlay"),dc.drawEdgeUnderlay=hc("underlay"),dc.drawEdgePath=function(e,t,n,r){var a,i=e._private.rscratch,o=t,s=!1,l=this.usePaths(),u=e.pstyle("line-dash-pattern").pfValue,c=e.pstyle("line-dash-offset").pfValue;if(l){var h=n.join("$");i.pathCacheKey&&i.pathCacheKey===h?(a=t=i.pathCache,s=!0):(a=t=new Path2D,i.pathCacheKey=h,i.pathCache=a)}if(o.setLineDash)switch(r){case"dotted":o.setLineDash([1,1]);break;case"dashed":o.setLineDash(u),o.lineDashOffset=c;break;case"solid":o.setLineDash([])}if(!s&&!i.badLine)switch(t.beginPath&&t.beginPath(),t.moveTo(n[0],n[1]),i.edgeType){case"bezier":case"self":case"compound":case"multibezier":for(var p=2;p+35&&void 0!==arguments[5]?arguments[5]:5,o=arguments.length>6?arguments[6]:void 0;e.beginPath(),e.moveTo(t+i,n),e.lineTo(t+r-i,n),e.quadraticCurveTo(t+r,n,t+r,n+i),e.lineTo(t+r,n+a-i),e.quadraticCurveTo(t+r,n+a,t+r-i,n+a),e.lineTo(t+i,n+a),e.quadraticCurveTo(t,n+a,t,n+a-i),e.lineTo(t,n+i),e.quadraticCurveTo(t,n,t+i,n),e.closePath(),o?e.stroke():e.fill()}fc.eleTextBiggerThanMin=function(e,t){if(!t){var n=e.cy().zoom(),r=this.getPixelRatio(),a=Math.ceil(Mt(n*r));t=Math.pow(2,a)}return!(e.pstyle("font-size").pfValue*t5&&void 0!==arguments[5])||arguments[5],o=this;if(null==r){if(i&&!o.eleTextBiggerThanMin(t))return}else if(!1===r)return;if(t.isNode()){var s=t.pstyle("label");if(!s||!s.value)return;var l=o.getLabelJustification(t);e.textAlign=l,e.textBaseline="bottom"}else{var u=t.element()._private.rscratch.badLine,c=t.pstyle("label"),d=t.pstyle("source-label"),h=t.pstyle("target-label");if(u||(!c||!c.value)&&(!d||!d.value)&&(!h||!h.value))return;e.textAlign="center",e.textBaseline="bottom"}var p,f=!n;n&&(p=n,e.translate(-p.x1,-p.y1)),null==a?(o.drawText(e,t,null,f,i),t.isEdge()&&(o.drawText(e,t,"source",f,i),o.drawText(e,t,"target",f,i))):o.drawText(e,t,a,f,i),n&&e.translate(p.x1,p.y1)},fc.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var n=0;n2&&void 0!==arguments[2])||arguments[2],r=t.pstyle("font-style").strValue,a=t.pstyle("font-size").pfValue+"px",i=t.pstyle("font-family").strValue,o=t.pstyle("font-weight").strValue,s=n?t.effectiveOpacity()*t.pstyle("text-opacity").value:1,l=t.pstyle("text-outline-opacity").value*s,u=t.pstyle("color").value,c=t.pstyle("text-outline-color").value;e.font=r+" "+o+" "+a+" "+i,e.lineJoin="round",this.colorFillStyle(e,u[0],u[1],u[2],s),this.colorStrokeStyle(e,c[0],c[1],c[2],l)},fc.getTextAngle=function(e,t){var n=e._private.rscratch,r=t?t+"-":"",a=e.pstyle(r+"text-rotation"),i=rt(n,"labelAngle",t);return"autorotate"===a.strValue?e.isEdge()?i:0:"none"===a.strValue?0:a.pfValue},fc.drawText=function(e,t,n){var r=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],a=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],i=t._private.rscratch,o=a?t.effectiveOpacity():1;if(!a||0!==o&&0!==t.pstyle("text-opacity").value){"main"===n&&(n=null);var s,l,u=rt(i,"labelX",n),c=rt(i,"labelY",n),d=this.getLabelText(t,n);if(null!=d&&""!==d&&!isNaN(u)&&!isNaN(c)){this.setupTextStyle(e,t,a);var h,p=n?n+"-":"",f=rt(i,"labelWidth",n),g=rt(i,"labelHeight",n),v=t.pstyle(p+"text-margin-x").pfValue,y=t.pstyle(p+"text-margin-y").pfValue,m=t.isEdge(),b=t.pstyle("text-halign").value,x=t.pstyle("text-valign").value;switch(m&&(b="center",x="center"),u+=v,c+=y,0!==(h=r?this.getTextAngle(t,n):0)&&(s=u,l=c,e.translate(s,l),e.rotate(h),u=0,c=0),x){case"top":break;case"center":c+=g/2;break;case"bottom":c+=g}var w=t.pstyle("text-background-opacity").value,E=t.pstyle("text-border-opacity").value,k=t.pstyle("text-border-width").pfValue,C=t.pstyle("text-background-padding").pfValue,S=0===t.pstyle("text-background-shape").strValue.indexOf("round");if(w>0||k>0&&E>0){var P=u-C;switch(b){case"left":P-=f;break;case"center":P-=f/2}var D=c-g-C,T=f+2*C,_=g+2*C;if(w>0){var M=e.fillStyle,B=t.pstyle("text-background-color").value;e.fillStyle="rgba("+B[0]+","+B[1]+","+B[2]+","+w*o+")",S?gc(e,P,D,T,_,2):e.fillRect(P,D,T,_),e.fillStyle=M}if(k>0&&E>0){var N=e.strokeStyle,z=e.lineWidth,I=t.pstyle("text-border-color").value,A=t.pstyle("text-border-style").value;if(e.strokeStyle="rgba("+I[0]+","+I[1]+","+I[2]+","+E*o+")",e.lineWidth=k,e.setLineDash)switch(A){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=k/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(S?gc(e,P,D,T,_,2,"stroke"):e.strokeRect(P,D,T,_),"double"===A){var L=k/2;S?gc(e,P+L,D+L,T-2*L,_-2*L,2,"stroke"):e.strokeRect(P+L,D+L,T-2*L,_-2*L)}e.setLineDash&&e.setLineDash([]),e.lineWidth=z,e.strokeStyle=N}}var O=2*t.pstyle("text-outline-width").pfValue;if(O>0&&(e.lineWidth=O),"wrap"===t.pstyle("text-wrap").value){var R=rt(i,"labelWrapCachedLines",n),V=rt(i,"labelLineHeight",n),F=f/2,j=this.getLabelJustification(t);switch("auto"===j||("left"===b?"left"===j?u+=-f:"center"===j&&(u+=-F):"center"===b?"left"===j?u+=-F:"right"===j&&(u+=F):"right"===b&&("center"===j?u+=F:"right"===j&&(u+=f))),x){case"top":case"center":case"bottom":c-=(R.length-1)*V}for(var q=0;q0&&e.strokeText(R[q],u,c),e.fillText(R[q],u,c),c+=V}else O>0&&e.strokeText(d,u,c),e.fillText(d,u,c);0!==h&&(e.rotate(-h),e.translate(-s,-l))}}};var vc={drawNode:function(e,t,n){var r,a,i=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],o=!(arguments.length>4&&void 0!==arguments[4])||arguments[4],s=!(arguments.length>5&&void 0!==arguments[5])||arguments[5],l=this,u=t._private,c=u.rscratch,d=t.position();if(k(d.x)&&k(d.y)&&(!s||t.visible())){var h,p,f=s?t.effectiveOpacity():1,g=l.usePaths(),v=!1,y=t.padding();r=t.width()+2*y,a=t.height()+2*y,n&&(p=n,e.translate(-p.x1,-p.y1));for(var m=t.pstyle("background-image").value,b=new Array(m.length),x=new Array(m.length),w=0,E=0;E0&&void 0!==arguments[0]?arguments[0]:T;l.eleFillStyle(e,t,n)},X=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:L;l.colorStrokeStyle(e,_[0],_[1],_[2],t)},W=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:F;l.colorStrokeStyle(e,R[0],R[1],R[2],t)},H=function(e,t,n,r){var a,i=l.nodePathCache=l.nodePathCache||[],o=Oe("polygon"===n?n+","+r.join(","):n,""+t,""+e,""+q),s=i[o],u=!1;return null!=s?(a=s,u=!0,c.pathCache=a):(a=new Path2D,i[o]=c.pathCache=a),{path:a,cacheHit:u}},K=t.pstyle("shape").strValue,G=t.pstyle("shape-polygon-points").pfValue;if(g){e.translate(d.x,d.y);var U=H(r,a,K,G);h=U.path,v=U.cacheHit}var Z=function(){if(!v){var n=d;g&&(n={x:0,y:0}),l.nodeShapes[l.getNodeShape(t)].draw(h||e,n.x,n.y,r,a,q,c)}g?e.fill(h):e.fill()},$=function(){for(var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:f,r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],a=u.backgrounding,i=0,o=0;o0&&void 0!==arguments[0]&&arguments[0],i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:f;l.hasPie(t)&&(l.drawPie(e,t,i),n&&(g||l.nodeShapes[l.getNodeShape(t)].draw(e,d.x,d.y,r,a,q,c)))},J=function(){var t=(P>0?P:-P)*(arguments.length>0&&void 0!==arguments[0]?arguments[0]:f),n=P>0?0:255;0!==P&&(l.colorFillStyle(e,n,n,n,t),g?e.fill(h):e.fill())},ee=function(){if(D>0){if(e.lineWidth=D,e.lineCap=N,e.lineJoin=B,e.setLineDash)switch(M){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash(I),e.lineDashOffset=A;break;case"solid":case"double":e.setLineDash([])}if("center"!==z){if(e.save(),e.lineWidth*=2,"inside"===z)g?e.clip(h):e.clip();else{var t=new Path2D;t.rect(-r/2-D,-a/2-D,r+2*D,a+2*D),t.addPath(h),e.clip(t,"evenodd")}g?e.stroke(h):e.stroke(),e.restore()}else g?e.stroke(h):e.stroke();if("double"===M){e.lineWidth=D/3;var n=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",g?e.stroke(h):e.stroke(),e.globalCompositeOperation=n}e.setLineDash&&e.setLineDash([])}},te=function(){if(O>0){if(e.lineWidth=O,e.lineCap="butt",e.setLineDash)switch(V){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var n=d;g&&(n={x:0,y:0});var i=l.getNodeShape(t),o=D;"inside"===z&&(o=0),"outside"===z&&(o*=2);var s,u=(r+o+(O+j))/r,c=(a+o+(O+j))/a,h=r*u,p=a*c,f=l.nodeShapes[i].points;if(g)s=H(h,p,i,f).path;if("ellipse"===i)l.drawEllipsePath(s||e,n.x,n.y,h,p);else if(["round-diamond","round-heptagon","round-hexagon","round-octagon","round-pentagon","round-polygon","round-triangle","round-tag"].includes(i)){var v=0,y=0,m=0;"round-diamond"===i?v=1.4*(o+j+O):"round-heptagon"===i?(v=1.075*(o+j+O),m=-(o/2+j+O)/35):"round-hexagon"===i?v=1.12*(o+j+O):"round-pentagon"===i?(v=1.13*(o+j+O),m=-(o/2+j+O)/15):"round-tag"===i?(v=1.12*(o+j+O),y=.07*(o/2+O+j)):"round-triangle"===i&&(v=(o+j+O)*(Math.PI/2),m=-(o+j/2+O)/Math.PI),0!==v&&(h=r*(u=(r+v)/r),["round-hexagon","round-tag"].includes(i)||(p=a*(c=(a+v)/a)));for(var b=h/2,x=p/2,w=(q="auto"===q?pn(h,p):q)+(o+O+j)/2,E=new Array(f.length/2),k=new Array(f.length/2),C=0;C0){if(r=r||n.position(),null==a||null==i){var d=n.padding();a=n.width()+2*d,i=n.height()+2*d}this.colorFillStyle(t,l[0],l[1],l[2],s),this.nodeShapes[u].draw(t,r.x,r.y,a+2*o,i+2*o,c),t.fill()}}}};vc.drawNodeOverlay=yc("overlay"),vc.drawNodeUnderlay=yc("underlay"),vc.hasPie=function(e){return(e=e[0])._private.hasPie},vc.drawPie=function(e,t,n,r){t=t[0],r=r||t.position();var a=t.cy().style(),i=t.pstyle("pie-size"),o=r.x,s=r.y,l=t.width(),u=t.height(),c=Math.min(l,u)/2,d=0;this.usePaths()&&(o=0,s=0),"%"===i.units?c*=i.pfValue:void 0!==i.pfValue&&(c=i.pfValue/2);for(var h=1;h<=a.pieBackgroundN;h++){var p=t.pstyle("pie-"+h+"-background-size").value,f=t.pstyle("pie-"+h+"-background-color").value,g=t.pstyle("pie-"+h+"-background-opacity").value*n,v=p/100;v+d>1&&(v=1-d);var y=1.5*Math.PI+2*Math.PI*d,m=y+2*Math.PI*v;0===p||d>=1||d+v>1||(e.beginPath(),e.moveTo(o,s),e.arc(o,s,c,y,m),e.closePath(),this.colorFillStyle(e,f[0],f[1],f[2],g),e.fill(),d+=v)}};var mc={};mc.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=this.cy.window(),n=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(t.devicePixelRatio||1)/n},mc.paintCache=function(e){for(var t,n=this.paintCaches=this.paintCaches||[],r=!0,a=0;ao.minMbLowQualFrames&&(o.motionBlurPxRatio=o.mbPxRBlurry)),o.clearingMotionBlur&&(o.motionBlurPxRatio=1),o.textureDrawLastFrame&&!d&&(c[o.NODE]=!0,c[o.SELECT_BOX]=!0);var m=l.style(),b=l.zoom(),x=void 0!==a?a:b,w=l.pan(),E={x:w.x,y:w.y},k={zoom:b,pan:{x:w.x,y:w.y}},C=o.prevViewport;void 0===C||k.zoom!==C.zoom||k.pan.x!==C.pan.x||k.pan.y!==C.pan.y||g&&!f||(o.motionBlurPxRatio=1),i&&(E=i),x*=s,E.x*=s,E.y*=s;var S=o.getCachedZSortedEles();function P(e,t,n,r,a){var i=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",o.colorFillStyle(e,255,255,255,o.motionBlurTransparency),e.fillRect(t,n,r,a),e.globalCompositeOperation=i}function D(e,r){var s,l,c,d;o.clearingMotionBlur||e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]&&e!==u.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]?(s=E,l=x,c=o.canvasWidth,d=o.canvasHeight):(s={x:w.x*p,y:w.y*p},l=b*p,c=o.canvasWidth*p,d=o.canvasHeight*p),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?P(e,0,0,c,d):t||void 0!==r&&!r||e.clearRect(0,0,c,d),n||(e.translate(s.x,s.y),e.scale(l,l)),i&&e.translate(i.x,i.y),a&&e.scale(a,a)}if(d||(o.textureDrawLastFrame=!1),d){if(o.textureDrawLastFrame=!0,!o.textureCache){o.textureCache={},o.textureCache.bb=l.mutableElements().boundingBox(),o.textureCache.texture=o.data.bufferCanvases[o.TEXTURE_BUFFER];var T=o.data.bufferContexts[o.TEXTURE_BUFFER];T.setTransform(1,0,0,1,0,0),T.clearRect(0,0,o.canvasWidth*o.textureMult,o.canvasHeight*o.textureMult),o.render({forcedContext:T,drawOnlyNodeLayer:!0,forcedPxRatio:s*o.textureMult}),(k=o.textureCache.viewport={zoom:l.zoom(),pan:l.pan(),width:o.canvasWidth,height:o.canvasHeight}).mpan={x:(0-k.pan.x)/k.zoom,y:(0-k.pan.y)/k.zoom}}c[o.DRAG]=!1,c[o.NODE]=!1;var _=u.contexts[o.NODE],M=o.textureCache.texture;k=o.textureCache.viewport;_.setTransform(1,0,0,1,0,0),h?P(_,0,0,k.width,k.height):_.clearRect(0,0,k.width,k.height);var B=m.core("outside-texture-bg-color").value,N=m.core("outside-texture-bg-opacity").value;o.colorFillStyle(_,B[0],B[1],B[2],N),_.fillRect(0,0,k.width,k.height);b=l.zoom();D(_,!1),_.clearRect(k.mpan.x,k.mpan.y,k.width/k.zoom/s,k.height/k.zoom/s),_.drawImage(M,k.mpan.x,k.mpan.y,k.width/k.zoom/s,k.height/k.zoom/s)}else o.textureOnViewport&&!t&&(o.textureCache=null);var z=l.extent(),I=o.pinching||o.hoverData.dragging||o.swipePanning||o.data.wheelZooming||o.hoverData.draggingEles||o.cy.animated(),A=o.hideEdgesOnViewport&&I,L=[];if(L[o.NODE]=!c[o.NODE]&&h&&!o.clearedForMotionBlur[o.NODE]||o.clearingMotionBlur,L[o.NODE]&&(o.clearedForMotionBlur[o.NODE]=!0),L[o.DRAG]=!c[o.DRAG]&&h&&!o.clearedForMotionBlur[o.DRAG]||o.clearingMotionBlur,L[o.DRAG]&&(o.clearedForMotionBlur[o.DRAG]=!0),c[o.NODE]||n||r||L[o.NODE]){var O=h&&!L[o.NODE]&&1!==p;D(_=t||(O?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_NODE]:u.contexts[o.NODE]),h&&!O?"motionBlur":void 0),A?o.drawCachedNodes(_,S.nondrag,s,z):o.drawLayeredElements(_,S.nondrag,s,z),o.debug&&o.drawDebugPoints(_,S.nondrag),n||h||(c[o.NODE]=!1)}if(!r&&(c[o.DRAG]||n||L[o.DRAG])){O=h&&!L[o.DRAG]&&1!==p;D(_=t||(O?o.data.bufferContexts[o.MOTIONBLUR_BUFFER_DRAG]:u.contexts[o.DRAG]),h&&!O?"motionBlur":void 0),A?o.drawCachedNodes(_,S.drag,s,z):o.drawCachedElements(_,S.drag,s,z),o.debug&&o.drawDebugPoints(_,S.drag),n||h||(c[o.DRAG]=!1)}if(o.showFps||!r&&c[o.SELECT_BOX]&&!n){if(D(_=t||u.contexts[o.SELECT_BOX]),1==o.selection[4]&&(o.hoverData.selecting||o.touchData.selecting)){b=o.cy.zoom();var R=m.core("selection-box-border-width").value/b;_.lineWidth=R,_.fillStyle="rgba("+m.core("selection-box-color").value[0]+","+m.core("selection-box-color").value[1]+","+m.core("selection-box-color").value[2]+","+m.core("selection-box-opacity").value+")",_.fillRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]),R>0&&(_.strokeStyle="rgba("+m.core("selection-box-border-color").value[0]+","+m.core("selection-box-border-color").value[1]+","+m.core("selection-box-border-color").value[2]+","+m.core("selection-box-opacity").value+")",_.strokeRect(o.selection[0],o.selection[1],o.selection[2]-o.selection[0],o.selection[3]-o.selection[1]))}if(u.bgActivePosistion&&!o.hoverData.selecting){b=o.cy.zoom();var V=u.bgActivePosistion;_.fillStyle="rgba("+m.core("active-bg-color").value[0]+","+m.core("active-bg-color").value[1]+","+m.core("active-bg-color").value[2]+","+m.core("active-bg-opacity").value+")",_.beginPath(),_.arc(V.x,V.y,m.core("active-bg-size").pfValue/b,0,2*Math.PI),_.fill()}var F=o.lastRedrawTime;if(o.showFps&&F){F=Math.round(F);var j=Math.round(1e3/F);_.setTransform(1,0,0,1,0,0),_.fillStyle="rgba(255, 0, 0, 0.75)",_.strokeStyle="rgba(255, 0, 0, 0.75)",_.lineWidth=1,_.fillText("1 frame = "+F+" ms = "+j+" fps",0,20);_.strokeRect(0,30,250,20),_.fillRect(0,30,250*Math.min(j/60,1),20)}n||(c[o.SELECT_BOX]=!1)}if(h&&1!==p){var q=u.contexts[o.NODE],Y=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_NODE],X=u.contexts[o.DRAG],W=o.data.bufferCanvases[o.MOTIONBLUR_BUFFER_DRAG],H=function(e,t,n){e.setTransform(1,0,0,1,0,0),n||!y?e.clearRect(0,0,o.canvasWidth,o.canvasHeight):P(e,0,0,o.canvasWidth,o.canvasHeight);var r=p;e.drawImage(t,0,0,o.canvasWidth*r,o.canvasHeight*r,0,0,o.canvasWidth,o.canvasHeight)};(c[o.NODE]||L[o.NODE])&&(H(q,Y,L[o.NODE]),c[o.NODE]=!1),(c[o.DRAG]||L[o.DRAG])&&(H(X,W,L[o.DRAG]),c[o.DRAG]=!1)}o.prevViewport=k,o.clearingMotionBlur&&(o.clearingMotionBlur=!1,o.motionBlurCleared=!0,o.motionBlur=!0),h&&(o.motionBlurTimeout=setTimeout((function(){o.motionBlurTimeout=null,o.clearedForMotionBlur[o.NODE]=!1,o.clearedForMotionBlur[o.DRAG]=!1,o.motionBlur=!1,o.clearingMotionBlur=!d,o.mbFrames=0,c[o.NODE]=!0,c[o.DRAG]=!0,o.redraw()}),100)),t||l.emit("render")};for(var bc={drawPolygonPath:function(e,t,n,r,a,i){var o=r/2,s=a/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*i[0],n+s*i[1]);for(var l=1;l0&&i>0){h.clearRect(0,0,a,i),h.globalCompositeOperation="source-over";var p=this.getCachedZSortedEles();if(e.full)h.translate(-n.x1*l,-n.y1*l),h.scale(l,l),this.drawElements(h,p),h.scale(1/l,1/l),h.translate(n.x1*l,n.y1*l);else{var f=t.pan(),g={x:f.x*l,y:f.y*l};l*=t.zoom(),h.translate(g.x,g.y),h.scale(l,l),this.drawElements(h,p),h.scale(1/l,1/l),h.translate(-g.x,-g.y)}e.bg&&(h.globalCompositeOperation="destination-over",h.fillStyle=e.bg,h.rect(0,0,a,i),h.fill())}return d},Pc.png=function(e){return Tc(e,this.bufferCanvasImage(e),"image/png")},Pc.jpg=function(e){return Tc(e,this.bufferCanvasImage(e),"image/jpeg")};var _c={nodeShapeImpl:function(e,t,n,r,a,i,o,s){switch(e){case"ellipse":return this.drawEllipsePath(t,n,r,a,i);case"polygon":return this.drawPolygonPath(t,n,r,a,i,o);case"round-polygon":return this.drawRoundPolygonPath(t,n,r,a,i,o,s);case"roundrectangle":case"round-rectangle":return this.drawRoundRectanglePath(t,n,r,a,i,s);case"cutrectangle":case"cut-rectangle":return this.drawCutRectanglePath(t,n,r,a,i,o,s);case"bottomroundrectangle":case"bottom-round-rectangle":return this.drawBottomRoundRectanglePath(t,n,r,a,i,s);case"barrel":return this.drawBarrelPath(t,n,r,a,i)}}},Mc=Nc,Bc=Nc.prototype;function Nc(e){var t=this,n=t.cy.window().document;t.data={canvases:new Array(Bc.CANVAS_LAYERS),contexts:new Array(Bc.CANVAS_LAYERS),canvasNeedsRedraw:new Array(Bc.CANVAS_LAYERS),bufferCanvases:new Array(Bc.BUFFER_COUNT),bufferContexts:new Array(Bc.CANVAS_LAYERS)};var r="-webkit-tap-highlight-color",a="rgba(0,0,0,0)";t.data.canvasContainer=n.createElement("div");var i=t.data.canvasContainer.style;t.data.canvasContainer.style[r]=a,i.position="relative",i.zIndex="0",i.overflow="hidden";var o=e.cy.container();o.appendChild(t.data.canvasContainer),o.style[r]=a;var s={"-webkit-user-select":"none","-moz-user-select":"-moz-none","user-select":"none","-webkit-tap-highlight-color":"rgba(0,0,0,0)","outline-style":"none"};p&&p.userAgent.match(/msie|trident|edge/i)&&(s["-ms-touch-action"]="none",s["touch-action"]="none");for(var l=0;l{s.d(e,{A:()=>i});var n=s(72453),r=s(74886);const i=(t,e)=>n.A.lang.round(r.A.parse(t)[e])},79972:(t,e,s)=>{s.d(e,{A:()=>i,P:()=>u});var n=s(45567),r=s(20007),i=(0,n.K2)(((t,e)=>{let s;"sandbox"===e&&(s=(0,r.Ltv)("#i"+t));return("sandbox"===e?(0,r.Ltv)(s.nodes()[0].contentDocument.body):(0,r.Ltv)("body")).select(`[id="${t}"]`)}),"getDiagramElement"),u=(0,n.K2)(((t,e,s,r)=>{t.attr("class",s);const{width:i,height:u,x:c,y:l}=a(t,e);(0,n.a$)(t,u,i,r);const h=o(c,l,i,u,e);t.attr("viewBox",h),n.Rm.debug(`viewBox configured: ${h} with padding: ${e}`)}),"setupViewPortForSVG"),a=(0,n.K2)(((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}}),"calculateDimensionsWithPadding"),o=(0,n.K2)(((t,e,s,n,r)=>`${t-r} ${e-r} ${s} ${n}`),"createViewBox")},71689:(t,e,s)=>{s.d(e,{diagram:()=>Dt});var n,r,i=s(79972),u=s(79515),a=s(79740),o=(s(6396),s(5081)),c=(s(34483),s(52294),s(62392),s(86825),s(85039)),l=s(45567),h=s(20007),d=s(75937),p=s(25582),A=0,g=(0,l.D7)(),f=new Map,y=[],k=new Map,b=[],E=new Map,m=new Map,D=0,x=!0,C=[],T=(0,l.K2)((t=>l.Y2.sanitizeText(t,g)),"sanitizeText"),S=(0,l.K2)((function(t){for(const e of f.values())if(e.id===t)return e.domId;return t}),"lookUpDomId"),F=(0,l.K2)((function(t,e,s,n,r,i,a={},c){if(!t||0===t.trim().length)return;let h,d=f.get(t);if(void 0===d&&(d={id:t,labelType:"text",domId:"flowchart-"+t+"-"+A,styles:[],classes:[]},f.set(t,d)),A++,void 0!==e?(g=(0,l.D7)(),h=T(e.text.trim()),d.labelType=e.type,h.startsWith('"')&&h.endsWith('"')&&(h=h.substring(1,h.length-1)),d.text=h):void 0===d.text&&(d.text=t),void 0!==s&&(d.type=s),null!=n&&n.forEach((function(t){d.styles.push(t)})),null!=r&&r.forEach((function(t){d.classes.push(t)})),void 0!==i&&(d.dir=i),void 0===d.props?d.props=a:void 0!==a&&Object.assign(d.props,a),void 0!==c){let e;e=c.includes("\n")?c+"\n":"{\n"+c+"\n}";const s=(0,u.H)(e,{schema:u.r});if(s.shape){if(s.shape!==s.shape.toLowerCase()||s.shape.includes("_"))throw new Error(`No such shape: ${s.shape}. Shape names should be lowercase.`);if(!(0,o.aP)(s.shape))throw new Error(`No such shape: ${s.shape}.`);d.type=s?.shape}s?.label&&(d.text=s?.label),s?.icon&&(d.icon=s?.icon,s.label?.trim()||d.text!==t||(d.text="")),s?.form&&(d.form=s?.form),s?.pos&&(d.pos=s?.pos),s?.img&&(d.img=s?.img,s.label?.trim()||d.text!==t||(d.text="")),s?.constraint&&(d.constraint=s.constraint),s.w&&(d.assetWidth=Number(s.w)),s.h&&(d.assetHeight=Number(s.h))}}),"addVertex"),_=(0,l.K2)((function(t,e,s){const n={start:t,end:e,type:void 0,text:"",labelType:"text"};l.Rm.info("abc78 Got edge...",n);const r=s.text;if(void 0!==r&&(n.text=T(r.text.trim()),n.text.startsWith('"')&&n.text.endsWith('"')&&(n.text=n.text.substring(1,n.text.length-1)),n.labelType=r.type),void 0!==s&&(n.type=s.type,n.stroke=s.stroke,n.length=s.length>10?10:s.length),!(y.length<(g.maxEdges??500)))throw new Error(`Edge limit exceeded. ${y.length} edges found, but the limit is ${g.maxEdges}.\n\nInitialize mermaid with maxEdges set to a higher number to allow more edges.\nYou cannot set this config via configuration inside the diagram as it is a secure config.\nYou have to call mermaid.initialize.`);l.Rm.info("Pushing edge..."),y.push(n)}),"addSingleLink"),B=(0,l.K2)((function(t,e,s){l.Rm.info("addLink",t,e,s);for(const n of t)for(const t of e)_(n,t,s)}),"addLink"),v=(0,l.K2)((function(t,e){t.forEach((function(t){"default"===t?y.defaultInterpolate=e:y[t].interpolate=e}))}),"updateLinkInterpolate"),w=(0,l.K2)((function(t,e){t.forEach((function(t){if("number"==typeof t&&t>=y.length)throw new Error(`The index ${t} for linkStyle is out of bounds. Valid indices for linkStyle are between 0 and ${y.length-1}. (Help: Ensure that the index is within the range of existing edges.)`);"default"===t?y.defaultStyle=e:(y[t].style=e,(y[t]?.style?.length??0)>0&&!y[t]?.style?.some((t=>t?.startsWith("fill")))&&y[t]?.style?.push("fill:none"))}))}),"updateLink"),$=(0,l.K2)((function(t,e){t.split(",").forEach((function(t){let s=k.get(t);void 0===s&&(s={id:t,styles:[],textStyles:[]},k.set(t,s)),null!=e&&e.forEach((function(t){if(/color/.exec(t)){const e=t.replace("fill","bgFill");s.textStyles.push(e)}s.styles.push(t)}))}))}),"addClass"),L=(0,l.K2)((function(t){/.*/.exec(n)&&(n="LR"),/.*v/.exec(n)&&(n="TB"),"TD"===n&&(n="TB")}),"setDirection"),R=(0,l.K2)((function(t,e){for(const s of t.split(",")){const t=f.get(s);t&&t.classes.push(e);const n=E.get(s);n&&n.classes.push(e)}}),"setClass"),I=(0,l.K2)((function(t,e){if(void 0!==e){e=T(e);for(const s of t.split(","))m.set("gen-1"===r?S(s):s,e)}}),"setTooltip"),K=(0,l.K2)((function(t,e,s){const n=S(t);if("loose"!==(0,l.D7)().securityLevel)return;if(void 0===e)return;let r=[];if("string"==typeof s){r=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,h.Ltv)(this).classed("hover",!1)}))}),"setupToolTips");C.push(Y);var j=(0,l.K2)((function(t="gen-1"){f=new Map,k=new Map,y=[],C=[Y],b=[],E=new Map,D=0,m=new Map,x=!0,r=t,g=(0,l.D7)(),(0,l.IU)()}),"clear"),X=(0,l.K2)((t=>{r=t||"gen-2"}),"setGen"),z=(0,l.K2)((function(){return"fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;"}),"defaultStyle"),H=(0,l.K2)((function(t,e,s){let n=t.text.trim(),i=s.text;function u(t){const e={boolean:{},number:{},string:{}},s=[];let n;return{nodeList:t.filter((function(t){const r=typeof t;return t.stmt&&"dir"===t.stmt?(n=t.value,!1):""!==t.trim()&&(r in e?!e[r].hasOwnProperty(t)&&(e[r][t]=!0):!s.includes(t)&&s.push(t))})),dir:n}}t===s&&/\s/.exec(s.text)&&(n=void 0),(0,l.K2)(u,"uniq");const{nodeList:a,dir:o}=u(e.flat());if("gen-1"===r)for(let r=0;r2e3)return{result:!1,count:0};if(Z[Q]=e,b[e].id===t)return{result:!0,count:0};let n=0,r=1;for(;n=0){const s=J(t,e);if(s.result)return{result:!0,count:r+s.count};r+=s.count}n+=1}return{result:!1,count:r}}),"indexNodes2"),tt=(0,l.K2)((function(t){return Z[t]}),"getDepthFirstPos"),et=(0,l.K2)((function(){Q=-1,b.length>0&&J("none",b.length-1)}),"indexNodes"),st=(0,l.K2)((function(){return b}),"getSubGraphs"),nt=(0,l.K2)((()=>!!x&&(x=!1,!0)),"firstGraph"),rt=(0,l.K2)((t=>{let e=t.trim(),s="arrow_open";switch(e[0]){case"<":s="arrow_point",e=e.slice(1);break;case"x":s="arrow_cross",e=e.slice(1);break;case"o":s="arrow_circle",e=e.slice(1)}let n="normal";return e.includes("=")&&(n="thick"),e.includes(".")&&(n="dotted"),{type:s,stroke:n}}),"destructStartLink"),it=(0,l.K2)(((t,e)=>{const s=e.length;let n=0;for(let r=0;r{const e=t.trim();let s=e.slice(0,-1),n="arrow_open";switch(e.slice(-1)){case"x":n="arrow_cross",e.startsWith("x")&&(n="double_"+n,s=s.slice(1));break;case">":n="arrow_point",e.startsWith("<")&&(n="double_"+n,s=s.slice(1));break;case"o":n="arrow_circle",e.startsWith("o")&&(n="double_"+n,s=s.slice(1))}let r="normal",i=s.length-1;s.startsWith("=")&&(r="thick"),s.startsWith("~")&&(r="invisible");const u=it(".",s);return u&&(r="dotted",i=u),{type:n,stroke:r,length:i}}),"destructEndLink"),at=(0,l.K2)(((t,e)=>{const s=ut(t);let n;if(e){if(n=rt(e),n.stroke!==s.stroke)return{type:"INVALID",stroke:"INVALID"};if("arrow_open"===n.type)n.type=s.type;else{if(n.type!==s.type)return{type:"INVALID",stroke:"INVALID"};n.type="double_"+n.type}return"double_arrow"===n.type&&(n.type="double_arrow_point"),n.length=s.length,n}return s}),"destructLink"),ot=(0,l.K2)(((t,e)=>{for(const s of t)if(s.nodes.includes(e))return!0;return!1}),"exists"),ct=(0,l.K2)(((t,e)=>{const s=[];return t.nodes.forEach(((n,r)=>{ot(e,n)||s.push(t.nodes[r])})),{nodes:s}}),"makeUniq"),lt={firstGraph:nt},ht=(0,l.K2)((t=>{if(t.img)return"imageSquare";if(t.icon)return"circle"===t.form?"iconCircle":"square"===t.form?"iconSquare":"rounded"===t.form?"iconRounded":"icon";switch(t.type){case"square":case void 0:return"squareRect";case"round":return"roundedRect";case"ellipse":return"ellipse";default:return t.type}}),"getTypeFromVertex"),dt=(0,l.K2)(((t,e)=>t.find((t=>t.id===e))),"findNode"),pt=(0,l.K2)((t=>{let e="none",s="arrow_point";switch(t){case"arrow_point":case"arrow_circle":case"arrow_cross":s=t;break;case"double_arrow_point":case"double_arrow_circle":case"double_arrow_cross":e=t.replace("double_",""),s=e}return{arrowTypeStart:e,arrowTypeEnd:s}}),"destructEdgeType"),At=(0,l.K2)(((t,e,s,n,r,i)=>{const u=s.get(t.id),a=n.get(t.id)??!1,o=dt(e,t.id);if(o)o.cssStyles=t.styles,o.cssCompiledStyles=gt(t.classes),o.cssClasses=t.classes.join(" ");else{const s={id:t.id,label:t.text,labelStyle:"",parentId:u,padding:r.flowchart?.padding||8,cssStyles:t.styles,cssCompiledStyles:gt(["default","node",...t.classes]),cssClasses:"default "+t.classes.join(" "),dir:t.dir,domId:t.domId,look:i,link:t.link,linkTarget:t.linkTarget,tooltip:P(t.id),icon:t.icon,pos:t.pos,img:t.img,assetWidth:t.assetWidth,assetHeight:t.assetHeight,constraint:t.constraint};a?e.push({...s,isGroup:!0,shape:"rect"}):e.push({...s,isGroup:!1,shape:ht(t)})}}),"addNodeFromVertex");function gt(t){let e=[];for(const s of t){const t=k.get(s);t?.styles&&(e=[...e,...t.styles??[]].map((t=>t.trim()))),t?.textStyles&&(e=[...e,...t.textStyles??[]].map((t=>t.trim())))}return e}(0,l.K2)(gt,"getCompiledStyles");var ft=(0,l.K2)((()=>{const t=(0,l.D7)(),e=[],s=[],n=st(),r=new Map,i=new Map;for(let a=n.length-1;a>=0;a--){const t=n[a];t.nodes.length>0&&i.set(t.id,!0);for(const e of t.nodes)r.set(e,t.id)}for(let a=n.length-1;a>=0;a--){const s=n[a];e.push({id:s.id,label:s.title,labelStyle:"",parentId:r.get(s.id),padding:8,cssCompiledStyles:gt(s.classes),cssClasses:s.classes.join(" "),shape:"rect",dir:s.dir,isGroup:!0,look:t.look})}U().forEach((s=>{At(s,e,r,i,t,t.look||"classic")}));const u=G();return u.forEach(((e,n)=>{const{arrowTypeStart:r,arrowTypeEnd:i}=pt(e.type),a=[...u.defaultStyle??[]];e.style&&a.push(...e.style);const o={id:(0,c.rY)(e.start,e.end,{counter:n,prefix:"L"}),start:e.start,end:e.end,type:e.type??"normal",label:e.text,labelpos:"c",thickness:e.stroke,minlen:e.length,classes:"invisible"===e?.stroke?"":"edge-thickness-normal edge-pattern-solid flowchart-link",arrowTypeStart:"invisible"===e?.stroke?"none":r,arrowTypeEnd:"invisible"===e?.stroke?"none":i,arrowheadStyle:"fill: #333",labelStyle:a,style:a,pattern:e.stroke,look:t.look};s.push(o)})),{nodes:e,edges:s,other:{},config:t}}),"getData"),yt={defaultConfig:(0,l.K2)((()=>l.ME.flowchart),"defaultConfig"),setAccTitle:l.SV,getAccTitle:l.iN,getAccDescription:l.m7,getData:ft,setAccDescription:l.EI,addVertex:F,lookUpDomId:S,addLink:B,updateLinkInterpolate:v,updateLink:w,addClass:$,setDirection:L,setClass:R,setTooltip:I,getTooltip:P,setClickEvent:O,setLink:N,bindFunctions:M,getDirection:V,getVertices:U,getEdges:G,getClasses:W,clear:j,setGen:X,defaultStyle:z,addSubGraph:H,getDepthFirstPos:tt,indexNodes:et,getSubGraphs:st,destructLink:at,lex:lt,exists:ot,makeUniq:ct,setDiagramTitle:l.ke,getDiagramTitle:l.ab},kt={getClasses:(0,l.K2)((function(t,e){return e.db.getClasses()}),"getClasses"),draw:(0,l.K2)((async function(t,e,s,n){l.Rm.info("REF0:"),l.Rm.info("Drawing state diagram (v2)",e);const{securityLevel:r,flowchart:u,layout:o}=(0,l.D7)();let d;"sandbox"===r&&(d=(0,h.Ltv)("#i"+e));const p="sandbox"===r?d.nodes()[0].contentDocument:document;l.Rm.debug("Before getData: ");const A=n.db.getData();l.Rm.debug("Data: ",A);const g=(0,i.A)(e,r),f=V();A.type=n.type,A.layoutAlgorithm=(0,a.q7)(o),"dagre"===A.layoutAlgorithm&&"elk"===o&&l.Rm.warn("flowchart-elk was moved to an external package in Mermaid v11. Please refer [release notes](https://github.com/mermaid-js/mermaid/releases/tag/v11.0.0) for more details. This diagram will be rendered using `dagre` layout as a fallback."),A.direction=f,A.nodeSpacing=u?.nodeSpacing||50,A.rankSpacing=u?.rankSpacing||50,A.markers=["point","circle","cross"],A.diagramId=e,l.Rm.debug("REF1:",A),await(0,a.XX)(A,g);const y=A.config.flowchart?.diagramPadding??8;c._K.insertTitle(g,"flowchartTitleText",u?.titleTopMargin||0,n.db.getDiagramTitle()),(0,i.P)(g,y,"flowchart",u?.useMaxWidth||!1);for(const i of A.nodes){const t=(0,h.Ltv)(`#${e} [id="${i.id}"]`);if(!t||!i.link)continue;const s=p.createElementNS("http://www.w3.org/2000/svg","a");s.setAttributeNS("http://www.w3.org/2000/svg","class",i.cssClasses),s.setAttributeNS("http://www.w3.org/2000/svg","rel","noopener"),"sandbox"===r?s.setAttributeNS("http://www.w3.org/2000/svg","target","_top"):i.linkTarget&&s.setAttributeNS("http://www.w3.org/2000/svg","target",i.linkTarget);const n=t.insert((function(){return s}),":first-child"),u=t.select(".label-container");u&&n.append((function(){return u.node()}));const a=t.select(".label");a&&n.append((function(){return a.node()}))}}),"draw")},bt=function(){var t=(0,l.K2)((function(t,e,s,n){for(s=s||{},n=t.length;n--;s[t[n]]=e);return s}),"o"),e=[1,4],s=[1,3],n=[1,5],r=[1,8,9,10,11,27,34,36,38,44,60,83,84,85,86,87,88,101,104,105,108,110,113,114,115,120,121,122,123],i=[2,2],u=[1,13],a=[1,14],o=[1,15],c=[1,16],h=[1,23],d=[1,25],p=[1,26],A=[1,27],g=[1,49],f=[1,48],y=[1,29],k=[1,30],b=[1,31],E=[1,32],m=[1,33],D=[1,44],x=[1,46],C=[1,42],T=[1,47],S=[1,43],F=[1,50],_=[1,45],B=[1,51],v=[1,52],w=[1,34],$=[1,35],L=[1,36],R=[1,37],I=[1,57],K=[1,8,9,10,11,27,32,34,36,38,44,60,83,84,85,86,87,88,101,104,105,108,110,113,114,115,120,121,122,123],N=[1,61],P=[1,60],O=[1,62],M=[8,9,11,75,77],V=[1,77],U=[1,90],G=[1,95],W=[1,94],Y=[1,91],j=[1,87],X=[1,93],z=[1,89],H=[1,96],q=[1,92],Q=[1,97],Z=[1,88],J=[8,9,10,11,40,75,77],tt=[8,9,10,11,40,46,75,77],et=[8,9,10,11,29,40,44,46,48,50,52,54,56,58,60,63,65,67,68,70,75,77,88,101,104,105,108,110,113,114,115],st=[8,9,11,44,60,75,77,88,101,104,105,108,110,113,114,115],nt=[44,60,88,101,104,105,108,110,113,114,115],rt=[1,123],it=[1,122],ut=[1,130],at=[1,144],ot=[1,145],ct=[1,146],lt=[1,147],ht=[1,132],dt=[1,134],pt=[1,138],At=[1,139],gt=[1,140],ft=[1,141],yt=[1,142],kt=[1,143],bt=[1,148],Et=[1,149],mt=[1,128],Dt=[1,129],xt=[1,136],Ct=[1,131],Tt=[1,135],St=[1,133],Ft=[8,9,10,11,27,32,34,36,38,44,60,83,84,85,86,87,88,101,104,105,108,110,113,114,115,120,121,122,123],_t=[1,151],Bt=[1,153],vt=[8,9,11],wt=[8,9,10,11,14,44,60,88,104,105,108,110,113,114,115],$t=[1,173],Lt=[1,169],Rt=[1,170],It=[1,174],Kt=[1,171],Nt=[1,172],Pt=[77,115,118],Ot=[8,9,10,11,12,14,27,29,32,44,60,75,83,84,85,86,87,88,89,104,108,110,113,114,115],Mt=[10,105],Vt=[31,49,51,53,55,57,62,64,66,67,69,71,115,116,117],Ut=[1,242],Gt=[1,240],Wt=[1,244],Yt=[1,238],jt=[1,239],Xt=[1,241],zt=[1,243],Ht=[1,245],qt=[1,263],Qt=[8,9,11,105],Zt=[8,9,10,11,60,83,104,105,108,109,110,111],Jt={trace:(0,l.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,graphConfig:4,document:5,line:6,statement:7,SEMI:8,NEWLINE:9,SPACE:10,EOF:11,GRAPH:12,NODIR:13,DIR:14,FirstStmtSeparator:15,ending:16,endToken:17,spaceList:18,spaceListNewline:19,vertexStatement:20,separator:21,styleStatement:22,linkStyleStatement:23,classDefStatement:24,classStatement:25,clickStatement:26,subgraph:27,textNoTags:28,SQS:29,text:30,SQE:31,end:32,direction:33,acc_title:34,acc_title_value:35,acc_descr:36,acc_descr_value:37,acc_descr_multiline_value:38,shapeData:39,SHAPE_DATA:40,link:41,node:42,styledVertex:43,AMP:44,vertex:45,STYLE_SEPARATOR:46,idString:47,DOUBLECIRCLESTART:48,DOUBLECIRCLEEND:49,PS:50,PE:51,"(-":52,"-)":53,STADIUMSTART:54,STADIUMEND:55,SUBROUTINESTART:56,SUBROUTINEEND:57,VERTEX_WITH_PROPS_START:58,"NODE_STRING[field]":59,COLON:60,"NODE_STRING[value]":61,PIPE:62,CYLINDERSTART:63,CYLINDEREND:64,DIAMOND_START:65,DIAMOND_STOP:66,TAGEND:67,TRAPSTART:68,TRAPEND:69,INVTRAPSTART:70,INVTRAPEND:71,linkStatement:72,arrowText:73,TESTSTR:74,START_LINK:75,edgeText:76,LINK:77,edgeTextToken:78,STR:79,MD_STR:80,textToken:81,keywords:82,STYLE:83,LINKSTYLE:84,CLASSDEF:85,CLASS:86,CLICK:87,DOWN:88,UP:89,textNoTagsToken:90,stylesOpt:91,"idString[vertex]":92,"idString[class]":93,CALLBACKNAME:94,CALLBACKARGS:95,HREF:96,LINK_TARGET:97,"STR[link]":98,"STR[tooltip]":99,alphaNum:100,DEFAULT:101,numList:102,INTERPOLATE:103,NUM:104,COMMA:105,style:106,styleComponent:107,NODE_STRING:108,UNIT:109,BRKT:110,PCT:111,idStringToken:112,MINUS:113,MULT:114,UNICODE_TEXT:115,TEXT:116,TAGSTART:117,EDGE_TEXT:118,alphaNumToken:119,direction_tb:120,direction_bt:121,direction_rl:122,direction_lr:123,$accept:0,$end:1},terminals_:{2:"error",8:"SEMI",9:"NEWLINE",10:"SPACE",11:"EOF",12:"GRAPH",13:"NODIR",14:"DIR",27:"subgraph",29:"SQS",31:"SQE",32:"end",34:"acc_title",35:"acc_title_value",36:"acc_descr",37:"acc_descr_value",38:"acc_descr_multiline_value",40:"SHAPE_DATA",44:"AMP",46:"STYLE_SEPARATOR",48:"DOUBLECIRCLESTART",49:"DOUBLECIRCLEEND",50:"PS",51:"PE",52:"(-",53:"-)",54:"STADIUMSTART",55:"STADIUMEND",56:"SUBROUTINESTART",57:"SUBROUTINEEND",58:"VERTEX_WITH_PROPS_START",59:"NODE_STRING[field]",60:"COLON",61:"NODE_STRING[value]",62:"PIPE",63:"CYLINDERSTART",64:"CYLINDEREND",65:"DIAMOND_START",66:"DIAMOND_STOP",67:"TAGEND",68:"TRAPSTART",69:"TRAPEND",70:"INVTRAPSTART",71:"INVTRAPEND",74:"TESTSTR",75:"START_LINK",77:"LINK",79:"STR",80:"MD_STR",83:"STYLE",84:"LINKSTYLE",85:"CLASSDEF",86:"CLASS",87:"CLICK",88:"DOWN",89:"UP",92:"idString[vertex]",93:"idString[class]",94:"CALLBACKNAME",95:"CALLBACKARGS",96:"HREF",97:"LINK_TARGET",98:"STR[link]",99:"STR[tooltip]",101:"DEFAULT",103:"INTERPOLATE",104:"NUM",105:"COMMA",108:"NODE_STRING",109:"UNIT",110:"BRKT",111:"PCT",113:"MINUS",114:"MULT",115:"UNICODE_TEXT",116:"TEXT",117:"TAGSTART",118:"EDGE_TEXT",120:"direction_tb",121:"direction_bt",122:"direction_rl",123:"direction_lr"},productions_:[0,[3,2],[5,0],[5,2],[6,1],[6,1],[6,1],[6,1],[6,1],[4,2],[4,2],[4,2],[4,3],[16,2],[16,1],[17,1],[17,1],[17,1],[15,1],[15,1],[15,2],[19,2],[19,2],[19,1],[19,1],[18,2],[18,1],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,9],[7,6],[7,4],[7,1],[7,2],[7,2],[7,1],[21,1],[21,1],[21,1],[39,2],[39,1],[20,4],[20,3],[20,4],[20,2],[20,2],[20,1],[42,1],[42,6],[42,5],[43,1],[43,3],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,8],[45,4],[45,4],[45,4],[45,6],[45,4],[45,4],[45,4],[45,4],[45,4],[45,1],[41,2],[41,3],[41,3],[41,1],[41,3],[76,1],[76,2],[76,1],[76,1],[72,1],[73,3],[30,1],[30,2],[30,1],[30,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[82,1],[28,1],[28,2],[28,1],[28,1],[24,5],[25,5],[26,2],[26,4],[26,3],[26,5],[26,3],[26,5],[26,5],[26,7],[26,2],[26,4],[26,2],[26,4],[26,4],[26,6],[22,5],[23,5],[23,5],[23,9],[23,9],[23,7],[23,7],[102,1],[102,3],[91,1],[91,3],[106,1],[106,2],[107,1],[107,1],[107,1],[107,1],[107,1],[107,1],[107,1],[107,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[112,1],[81,1],[81,1],[81,1],[81,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[90,1],[78,1],[78,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[119,1],[47,1],[47,2],[100,1],[100,2],[33,1],[33,1],[33,1],[33,1]],performAction:(0,l.K2)((function(t,e,s,n,r,i,u){var a=i.length-1;switch(r){case 2:case 28:case 29:case 30:case 31:case 32:this.$=[];break;case 3:(!Array.isArray(i[a])||i[a].length>0)&&i[a-1].push(i[a]),this.$=i[a-1];break;case 4:case 181:case 44:case 54:case 76:case 179:this.$=i[a];break;case 11:n.setDirection("TB"),this.$="TB";break;case 12:n.setDirection(i[a-1]),this.$=i[a-1];break;case 27:this.$=i[a-1].nodes;break;case 33:this.$=n.addSubGraph(i[a-6],i[a-1],i[a-4]);break;case 34:this.$=n.addSubGraph(i[a-3],i[a-1],i[a-3]);break;case 35:this.$=n.addSubGraph(void 0,i[a-1],void 0);break;case 37:this.$=i[a].trim(),n.setAccTitle(this.$);break;case 38:case 39:this.$=i[a].trim(),n.setAccDescription(this.$);break;case 43:case 131:this.$=i[a-1]+i[a];break;case 45:n.addVertex(i[a-1][0],void 0,void 0,void 0,void 0,void 0,void 0,i[a]),n.addLink(i[a-3].stmt,i[a-1],i[a-2]),this.$={stmt:i[a-1],nodes:i[a-1].concat(i[a-3].nodes)};break;case 46:n.addLink(i[a-2].stmt,i[a],i[a-1]),this.$={stmt:i[a],nodes:i[a].concat(i[a-2].nodes)};break;case 47:n.addLink(i[a-3].stmt,i[a-1],i[a-2]),this.$={stmt:i[a-1],nodes:i[a-1].concat(i[a-3].nodes)};break;case 48:this.$={stmt:i[a-1],nodes:i[a-1]};break;case 49:n.addVertex(i[a-1][0],void 0,void 0,void 0,void 0,void 0,void 0,i[a]),this.$={stmt:i[a-1],nodes:i[a-1],shapeData:i[a]};break;case 50:this.$={stmt:i[a],nodes:i[a]};break;case 51:case 126:case 128:this.$=[i[a]];break;case 52:n.addVertex(i[a-5][0],void 0,void 0,void 0,void 0,void 0,void 0,i[a-4]),this.$=i[a-5].concat(i[a]);break;case 53:this.$=i[a-4].concat(i[a]);break;case 55:this.$=i[a-2],n.setClass(i[a-2],i[a]);break;case 56:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"square");break;case 57:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"doublecircle");break;case 58:this.$=i[a-5],n.addVertex(i[a-5],i[a-2],"circle");break;case 59:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"ellipse");break;case 60:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"stadium");break;case 61:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"subroutine");break;case 62:this.$=i[a-7],n.addVertex(i[a-7],i[a-1],"rect",void 0,void 0,void 0,Object.fromEntries([[i[a-5],i[a-3]]]));break;case 63:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"cylinder");break;case 64:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"round");break;case 65:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"diamond");break;case 66:this.$=i[a-5],n.addVertex(i[a-5],i[a-2],"hexagon");break;case 67:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"odd");break;case 68:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"trapezoid");break;case 69:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"inv_trapezoid");break;case 70:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"lean_right");break;case 71:this.$=i[a-3],n.addVertex(i[a-3],i[a-1],"lean_left");break;case 72:this.$=i[a],n.addVertex(i[a]);break;case 73:i[a-1].text=i[a],this.$=i[a-1];break;case 74:case 75:i[a-2].text=i[a-1],this.$=i[a-2];break;case 77:var o=n.destructLink(i[a],i[a-2]);this.$={type:o.type,stroke:o.stroke,length:o.length,text:i[a-1]};break;case 78:case 84:case 99:case 101:this.$={text:i[a],type:"text"};break;case 79:case 85:case 100:this.$={text:i[a-1].text+""+i[a],type:i[a-1].type};break;case 80:case 86:this.$={text:i[a],type:"string"};break;case 81:case 87:case 102:this.$={text:i[a],type:"markdown"};break;case 82:o=n.destructLink(i[a]);this.$={type:o.type,stroke:o.stroke,length:o.length};break;case 83:this.$=i[a-1];break;case 103:this.$=i[a-4],n.addClass(i[a-2],i[a]);break;case 104:this.$=i[a-4],n.setClass(i[a-2],i[a]);break;case 105:case 113:this.$=i[a-1],n.setClickEvent(i[a-1],i[a]);break;case 106:case 114:this.$=i[a-3],n.setClickEvent(i[a-3],i[a-2]),n.setTooltip(i[a-3],i[a]);break;case 107:this.$=i[a-2],n.setClickEvent(i[a-2],i[a-1],i[a]);break;case 108:this.$=i[a-4],n.setClickEvent(i[a-4],i[a-3],i[a-2]),n.setTooltip(i[a-4],i[a]);break;case 109:this.$=i[a-2],n.setLink(i[a-2],i[a]);break;case 110:this.$=i[a-4],n.setLink(i[a-4],i[a-2]),n.setTooltip(i[a-4],i[a]);break;case 111:this.$=i[a-4],n.setLink(i[a-4],i[a-2],i[a]);break;case 112:this.$=i[a-6],n.setLink(i[a-6],i[a-4],i[a]),n.setTooltip(i[a-6],i[a-2]);break;case 115:this.$=i[a-1],n.setLink(i[a-1],i[a]);break;case 116:this.$=i[a-3],n.setLink(i[a-3],i[a-2]),n.setTooltip(i[a-3],i[a]);break;case 117:this.$=i[a-3],n.setLink(i[a-3],i[a-2],i[a]);break;case 118:this.$=i[a-5],n.setLink(i[a-5],i[a-4],i[a]),n.setTooltip(i[a-5],i[a-2]);break;case 119:this.$=i[a-4],n.addVertex(i[a-2],void 0,void 0,i[a]);break;case 120:this.$=i[a-4],n.updateLink([i[a-2]],i[a]);break;case 121:this.$=i[a-4],n.updateLink(i[a-2],i[a]);break;case 122:this.$=i[a-8],n.updateLinkInterpolate([i[a-6]],i[a-2]),n.updateLink([i[a-6]],i[a]);break;case 123:this.$=i[a-8],n.updateLinkInterpolate(i[a-6],i[a-2]),n.updateLink(i[a-6],i[a]);break;case 124:this.$=i[a-6],n.updateLinkInterpolate([i[a-4]],i[a]);break;case 125:this.$=i[a-6],n.updateLinkInterpolate(i[a-4],i[a]);break;case 127:case 129:i[a-2].push(i[a]),this.$=i[a-2];break;case 180:case 182:this.$=i[a-1]+""+i[a];break;case 183:this.$={stmt:"dir",value:"TB"};break;case 184:this.$={stmt:"dir",value:"BT"};break;case 185:this.$={stmt:"dir",value:"RL"};break;case 186:this.$={stmt:"dir",value:"LR"}}}),"anonymous"),table:[{3:1,4:2,9:e,10:s,12:n},{1:[3]},t(r,i,{5:6}),{4:7,9:e,10:s,12:n},{4:8,9:e,10:s,12:n},{13:[1,9],14:[1,10]},{1:[2,1],6:11,7:12,8:u,9:a,10:o,11:c,20:17,22:18,23:19,24:20,25:21,26:22,27:h,33:24,34:d,36:p,38:A,42:28,43:38,44:g,45:39,47:40,60:f,83:y,84:k,85:b,86:E,87:m,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v,120:w,121:$,122:L,123:R},t(r,[2,9]),t(r,[2,10]),t(r,[2,11]),{8:[1,54],9:[1,55],10:I,15:53,18:56},t(K,[2,3]),t(K,[2,4]),t(K,[2,5]),t(K,[2,6]),t(K,[2,7]),t(K,[2,8]),{8:N,9:P,11:O,21:58,41:59,72:63,75:[1,64],77:[1,65]},{8:N,9:P,11:O,21:66},{8:N,9:P,11:O,21:67},{8:N,9:P,11:O,21:68},{8:N,9:P,11:O,21:69},{8:N,9:P,11:O,21:70},{8:N,9:P,10:[1,71],11:O,21:72},t(K,[2,36]),{35:[1,73]},{37:[1,74]},t(K,[2,39]),t(M,[2,50],{18:75,39:76,10:I,40:V}),{10:[1,78]},{10:[1,79]},{10:[1,80]},{10:[1,81]},{14:U,44:G,60:W,79:[1,85],88:Y,94:[1,82],96:[1,83],100:84,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z,119:86},t(K,[2,183]),t(K,[2,184]),t(K,[2,185]),t(K,[2,186]),t(J,[2,51]),t(J,[2,54],{46:[1,98]}),t(tt,[2,72],{112:111,29:[1,99],44:g,48:[1,100],50:[1,101],52:[1,102],54:[1,103],56:[1,104],58:[1,105],60:f,63:[1,106],65:[1,107],67:[1,108],68:[1,109],70:[1,110],88:D,101:x,104:C,105:T,108:S,110:F,113:_,114:B,115:v}),t(et,[2,179]),t(et,[2,140]),t(et,[2,141]),t(et,[2,142]),t(et,[2,143]),t(et,[2,144]),t(et,[2,145]),t(et,[2,146]),t(et,[2,147]),t(et,[2,148]),t(et,[2,149]),t(et,[2,150]),t(r,[2,12]),t(r,[2,18]),t(r,[2,19]),{9:[1,112]},t(st,[2,26],{18:113,10:I}),t(K,[2,27]),{42:114,43:38,44:g,45:39,47:40,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},t(K,[2,40]),t(K,[2,41]),t(K,[2,42]),t(nt,[2,76],{73:115,62:[1,117],74:[1,116]}),{76:118,78:119,79:[1,120],80:[1,121],115:rt,118:it},t([44,60,62,74,88,101,104,105,108,110,113,114,115],[2,82]),t(K,[2,28]),t(K,[2,29]),t(K,[2,30]),t(K,[2,31]),t(K,[2,32]),{10:ut,12:at,14:ot,27:ct,28:124,32:lt,44:ht,60:dt,75:pt,79:[1,126],80:[1,127],82:137,83:At,84:gt,85:ft,86:yt,87:kt,88:bt,89:Et,90:125,104:mt,108:Dt,110:xt,113:Ct,114:Tt,115:St},t(Ft,i,{5:150}),t(K,[2,37]),t(K,[2,38]),t(M,[2,48],{44:_t}),t(M,[2,49],{18:152,10:I,40:Bt}),t(J,[2,44]),{44:g,47:154,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},{101:[1,155],102:156,104:[1,157]},{44:g,47:158,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},{44:g,47:159,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},t(vt,[2,105],{10:[1,160],95:[1,161]}),{79:[1,162]},t(vt,[2,113],{119:164,10:[1,163],14:U,44:G,60:W,88:Y,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z}),t(vt,[2,115],{10:[1,165]}),t(wt,[2,181]),t(wt,[2,168]),t(wt,[2,169]),t(wt,[2,170]),t(wt,[2,171]),t(wt,[2,172]),t(wt,[2,173]),t(wt,[2,174]),t(wt,[2,175]),t(wt,[2,176]),t(wt,[2,177]),t(wt,[2,178]),{44:g,47:166,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},{30:167,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:175,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:177,50:[1,176],67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:178,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:179,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:180,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{108:[1,181]},{30:182,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:183,65:[1,184],67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:185,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:186,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{30:187,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},t(et,[2,180]),t(r,[2,20]),t(st,[2,25]),t(M,[2,46],{39:188,18:189,10:I,40:V}),t(nt,[2,73],{10:[1,190]}),{10:[1,191]},{30:192,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{77:[1,193],78:194,115:rt,118:it},t(Pt,[2,78]),t(Pt,[2,80]),t(Pt,[2,81]),t(Pt,[2,166]),t(Pt,[2,167]),{8:N,9:P,10:ut,11:O,12:at,14:ot,21:196,27:ct,29:[1,195],32:lt,44:ht,60:dt,75:pt,82:137,83:At,84:gt,85:ft,86:yt,87:kt,88:bt,89:Et,90:197,104:mt,108:Dt,110:xt,113:Ct,114:Tt,115:St},t(Ot,[2,99]),t(Ot,[2,101]),t(Ot,[2,102]),t(Ot,[2,155]),t(Ot,[2,156]),t(Ot,[2,157]),t(Ot,[2,158]),t(Ot,[2,159]),t(Ot,[2,160]),t(Ot,[2,161]),t(Ot,[2,162]),t(Ot,[2,163]),t(Ot,[2,164]),t(Ot,[2,165]),t(Ot,[2,88]),t(Ot,[2,89]),t(Ot,[2,90]),t(Ot,[2,91]),t(Ot,[2,92]),t(Ot,[2,93]),t(Ot,[2,94]),t(Ot,[2,95]),t(Ot,[2,96]),t(Ot,[2,97]),t(Ot,[2,98]),{6:11,7:12,8:u,9:a,10:o,11:c,20:17,22:18,23:19,24:20,25:21,26:22,27:h,32:[1,198],33:24,34:d,36:p,38:A,42:28,43:38,44:g,45:39,47:40,60:f,83:y,84:k,85:b,86:E,87:m,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v,120:w,121:$,122:L,123:R},{10:I,18:199},{44:[1,200]},t(J,[2,43]),{10:[1,201],44:g,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:111,113:_,114:B,115:v},{10:[1,202]},{10:[1,203],105:[1,204]},t(Mt,[2,126]),{10:[1,205],44:g,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:111,113:_,114:B,115:v},{10:[1,206],44:g,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:111,113:_,114:B,115:v},{79:[1,207]},t(vt,[2,107],{10:[1,208]}),t(vt,[2,109],{10:[1,209]}),{79:[1,210]},t(wt,[2,182]),{79:[1,211],97:[1,212]},t(J,[2,55],{112:111,44:g,60:f,88:D,101:x,104:C,105:T,108:S,110:F,113:_,114:B,115:v}),{31:[1,213],67:$t,81:214,115:It,116:Kt,117:Nt},t(Vt,[2,84]),t(Vt,[2,86]),t(Vt,[2,87]),t(Vt,[2,151]),t(Vt,[2,152]),t(Vt,[2,153]),t(Vt,[2,154]),{49:[1,215],67:$t,81:214,115:It,116:Kt,117:Nt},{30:216,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{51:[1,217],67:$t,81:214,115:It,116:Kt,117:Nt},{53:[1,218],67:$t,81:214,115:It,116:Kt,117:Nt},{55:[1,219],67:$t,81:214,115:It,116:Kt,117:Nt},{57:[1,220],67:$t,81:214,115:It,116:Kt,117:Nt},{60:[1,221]},{64:[1,222],67:$t,81:214,115:It,116:Kt,117:Nt},{66:[1,223],67:$t,81:214,115:It,116:Kt,117:Nt},{30:224,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},{31:[1,225],67:$t,81:214,115:It,116:Kt,117:Nt},{67:$t,69:[1,226],71:[1,227],81:214,115:It,116:Kt,117:Nt},{67:$t,69:[1,229],71:[1,228],81:214,115:It,116:Kt,117:Nt},t(M,[2,45],{18:152,10:I,40:Bt}),t(M,[2,47],{44:_t}),t(nt,[2,75]),t(nt,[2,74]),{62:[1,230],67:$t,81:214,115:It,116:Kt,117:Nt},t(nt,[2,77]),t(Pt,[2,79]),{30:231,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},t(Ft,i,{5:232}),t(Ot,[2,100]),t(K,[2,35]),{43:233,44:g,45:39,47:40,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},{10:I,18:234},{10:Ut,60:Gt,83:Wt,91:235,104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},{10:Ut,60:Gt,83:Wt,91:246,103:[1,247],104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},{10:Ut,60:Gt,83:Wt,91:248,103:[1,249],104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},{104:[1,250]},{10:Ut,60:Gt,83:Wt,91:251,104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},{44:g,47:252,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},t(vt,[2,106]),{79:[1,253]},{79:[1,254],97:[1,255]},t(vt,[2,114]),t(vt,[2,116],{10:[1,256]}),t(vt,[2,117]),t(tt,[2,56]),t(Vt,[2,85]),t(tt,[2,57]),{51:[1,257],67:$t,81:214,115:It,116:Kt,117:Nt},t(tt,[2,64]),t(tt,[2,59]),t(tt,[2,60]),t(tt,[2,61]),{108:[1,258]},t(tt,[2,63]),t(tt,[2,65]),{66:[1,259],67:$t,81:214,115:It,116:Kt,117:Nt},t(tt,[2,67]),t(tt,[2,68]),t(tt,[2,70]),t(tt,[2,69]),t(tt,[2,71]),t([10,44,60,88,101,104,105,108,110,113,114,115],[2,83]),{31:[1,260],67:$t,81:214,115:It,116:Kt,117:Nt},{6:11,7:12,8:u,9:a,10:o,11:c,20:17,22:18,23:19,24:20,25:21,26:22,27:h,32:[1,261],33:24,34:d,36:p,38:A,42:28,43:38,44:g,45:39,47:40,60:f,83:y,84:k,85:b,86:E,87:m,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v,120:w,121:$,122:L,123:R},t(J,[2,53]),{43:262,44:g,45:39,47:40,60:f,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v},t(vt,[2,119],{105:qt}),t(Qt,[2,128],{107:264,10:Ut,60:Gt,83:Wt,104:Yt,108:jt,109:Xt,110:zt,111:Ht}),t(Zt,[2,130]),t(Zt,[2,132]),t(Zt,[2,133]),t(Zt,[2,134]),t(Zt,[2,135]),t(Zt,[2,136]),t(Zt,[2,137]),t(Zt,[2,138]),t(Zt,[2,139]),t(vt,[2,120],{105:qt}),{10:[1,265]},t(vt,[2,121],{105:qt}),{10:[1,266]},t(Mt,[2,127]),t(vt,[2,103],{105:qt}),t(vt,[2,104],{112:111,44:g,60:f,88:D,101:x,104:C,105:T,108:S,110:F,113:_,114:B,115:v}),t(vt,[2,108]),t(vt,[2,110],{10:[1,267]}),t(vt,[2,111]),{97:[1,268]},{51:[1,269]},{62:[1,270]},{66:[1,271]},{8:N,9:P,11:O,21:272},t(K,[2,34]),t(J,[2,52]),{10:Ut,60:Gt,83:Wt,104:Yt,106:273,107:237,108:jt,109:Xt,110:zt,111:Ht},t(Zt,[2,131]),{14:U,44:G,60:W,88:Y,100:274,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z,119:86},{14:U,44:G,60:W,88:Y,100:275,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z,119:86},{97:[1,276]},t(vt,[2,118]),t(tt,[2,58]),{30:277,67:$t,79:Lt,80:Rt,81:168,115:It,116:Kt,117:Nt},t(tt,[2,66]),t(Ft,i,{5:278}),t(Qt,[2,129],{107:264,10:Ut,60:Gt,83:Wt,104:Yt,108:jt,109:Xt,110:zt,111:Ht}),t(vt,[2,124],{119:164,10:[1,279],14:U,44:G,60:W,88:Y,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z}),t(vt,[2,125],{119:164,10:[1,280],14:U,44:G,60:W,88:Y,104:j,105:X,108:z,110:H,113:q,114:Q,115:Z}),t(vt,[2,112]),{31:[1,281],67:$t,81:214,115:It,116:Kt,117:Nt},{6:11,7:12,8:u,9:a,10:o,11:c,20:17,22:18,23:19,24:20,25:21,26:22,27:h,32:[1,282],33:24,34:d,36:p,38:A,42:28,43:38,44:g,45:39,47:40,60:f,83:y,84:k,85:b,86:E,87:m,88:D,101:x,104:C,105:T,108:S,110:F,112:41,113:_,114:B,115:v,120:w,121:$,122:L,123:R},{10:Ut,60:Gt,83:Wt,91:283,104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},{10:Ut,60:Gt,83:Wt,91:284,104:Yt,106:236,107:237,108:jt,109:Xt,110:zt,111:Ht},t(tt,[2,62]),t(K,[2,33]),t(vt,[2,122],{105:qt}),t(vt,[2,123],{105:qt})],defaultActions:{},parseError:(0,l.K2)((function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)}),"parseError"),parse:(0,l.K2)((function(t){var e=this,s=[0],n=[],r=[null],i=[],u=this.table,a="",o=0,c=0,h=0,d=i.slice.call(arguments,1),p=Object.create(this.lexer),A={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(A.yy[g]=this.yy[g]);p.setInput(t,A.yy),A.yy.lexer=p,A.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;i.push(f);var y=p.options&&p.options.ranges;function k(){var t;return"number"!=typeof(t=n.pop()||p.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,l.K2)((function(t){s.length=s.length-2*t,r.length=r.length-t,i.length=i.length-t}),"popStack"),(0,l.K2)(k,"lex");for(var b,E,m,D,x,C,T,S,F,_={};;){if(m=s[s.length-1],this.defaultActions[m]?D=this.defaultActions[m]:(null==b&&(b=k()),D=u[m]&&u[m][b]),void 0===D||!D.length||!D[0]){var B="";for(C in F=[],u[m])this.terminals_[C]&&C>2&&F.push("'"+this.terminals_[C]+"'");B=p.showPosition?"Parse error on line "+(o+1)+":\n"+p.showPosition()+"\nExpecting "+F.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(o+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(B,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:f,expected:F})}if(D[0]instanceof Array&&D.length>1)throw new Error("Parse Error: multiple actions possible at state: "+m+", token: "+b);switch(D[0]){case 1:s.push(b),r.push(p.yytext),i.push(p.yylloc),s.push(D[1]),b=null,E?(b=E,E=null):(c=p.yyleng,a=p.yytext,o=p.yylineno,f=p.yylloc,h>0&&h--);break;case 2:if(T=this.productions_[D[1]][1],_.$=r[r.length-T],_._$={first_line:i[i.length-(T||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(T||1)].first_column,last_column:i[i.length-1].last_column},y&&(_._$.range=[i[i.length-(T||1)].range[0],i[i.length-1].range[1]]),void 0!==(x=this.performAction.apply(_,[a,c,o,A.yy,D[1],r,i].concat(d))))return x;T&&(s=s.slice(0,-1*T*2),r=r.slice(0,-1*T),i=i.slice(0,-1*T)),s.push(this.productions_[D[1]][0]),r.push(_.$),i.push(_._$),S=u[s[s.length-2]][s[s.length-1]],s.push(S);break;case 3:return!0}}return!0}),"parse")},te=function(){return{EOF:1,parseError:(0,l.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,l.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,l.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,l.K2)((function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===n.length?this.yylloc.first_column:0)+n[n.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,l.K2)((function(){return this._more=!0,this}),"more"),reject:(0,l.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,l.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,l.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,l.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,l.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,l.K2)((function(t,e){var s,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var i in r)this[i]=r[i];return!1}return!1}),"test_match"),next:(0,l.K2)((function(){if(this.done)return this.EOF;var t,e,s,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),i=0;ie[0].length)){if(e=s,n=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,r[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,l.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,l.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,l.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,l.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,l.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,l.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,l.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{},performAction:(0,l.K2)((function(t,e,s,n){switch(s){case 0:return this.begin("acc_title"),34;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),36;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:case 12:case 14:case 17:case 20:case 23:case 33:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return this.pushState("shapeData"),e.yytext="",40;case 8:return this.pushState("shapeDataStr"),40;case 9:return this.popState(),40;case 10:const s=/\n\s*/g;return e.yytext=e.yytext.replace(s,"
"),40;case 11:return 40;case 13:this.begin("callbackname");break;case 15:this.popState(),this.begin("callbackargs");break;case 16:return 94;case 18:return 95;case 19:return"MD_STR";case 21:this.begin("md_string");break;case 22:return"STR";case 24:this.pushState("string");break;case 25:return 83;case 26:return 101;case 27:return 84;case 28:return 103;case 29:return 85;case 30:return 86;case 31:return 96;case 32:this.begin("click");break;case 34:return 87;case 35:case 36:case 37:return t.lex.firstGraph()&&this.begin("dir"),12;case 38:return 27;case 39:return 32;case 40:case 41:case 42:case 43:return 97;case 44:return this.popState(),13;case 45:case 46:case 47:case 48:case 49:case 50:case 51:case 52:case 53:case 54:return this.popState(),14;case 55:return 120;case 56:return 121;case 57:return 122;case 58:return 123;case 59:return 104;case 60:case 101:return 110;case 61:return 46;case 62:return 60;case 63:case 102:return 44;case 64:return 8;case 65:return 105;case 66:case 100:return 114;case 67:case 70:case 73:return this.popState(),77;case 68:return this.pushState("edgeText"),75;case 69:case 72:case 75:return 118;case 71:return this.pushState("thickEdgeText"),75;case 74:return this.pushState("dottedEdgeText"),75;case 76:return 77;case 77:return this.popState(),53;case 78:case 114:return"TEXT";case 79:return this.pushState("ellipseText"),52;case 80:return this.popState(),55;case 81:return this.pushState("text"),54;case 82:return this.popState(),57;case 83:return this.pushState("text"),56;case 84:return 58;case 85:return this.pushState("text"),67;case 86:return this.popState(),64;case 87:return this.pushState("text"),63;case 88:return this.popState(),49;case 89:return this.pushState("text"),48;case 90:return this.popState(),69;case 91:return this.popState(),71;case 92:return 116;case 93:return this.pushState("trapText"),68;case 94:return this.pushState("trapText"),70;case 95:return 117;case 96:return 67;case 97:return 89;case 98:return"SEP";case 99:return 88;case 103:return 108;case 104:return 113;case 105:return 115;case 106:return this.popState(),62;case 107:return this.pushState("text"),62;case 108:return this.popState(),51;case 109:return this.pushState("text"),50;case 110:return this.popState(),31;case 111:return this.pushState("text"),29;case 112:return this.popState(),66;case 113:return this.pushState("text"),65;case 115:return"QUOTE";case 116:return 9;case 117:return 10;case 118:return 11}}),"anonymous"),rules:[/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:@\{)/,/^(?:["])/,/^(?:["])/,/^(?:[^\"]+)/,/^(?:[^}^"]+)/,/^(?:\})/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["][`])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:["])/,/^(?:style\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\b)/,/^(?:class\b)/,/^(?:href[\s])/,/^(?:click[\s]+)/,/^(?:[\s\n])/,/^(?:[^\s\n]*)/,/^(?:flowchart-elk\b)/,/^(?:graph\b)/,/^(?:flowchart\b)/,/^(?:subgraph\b)/,/^(?:end\b\s*)/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:(\r?\n)*\s*\n)/,/^(?:\s*LR\b)/,/^(?:\s*RL\b)/,/^(?:\s*TB\b)/,/^(?:\s*BT\b)/,/^(?:\s*TD\b)/,/^(?:\s*BR\b)/,/^(?:\s*<)/,/^(?:\s*>)/,/^(?:\s*\^)/,/^(?:\s*v\b)/,/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:[0-9]+)/,/^(?:#)/,/^(?::::)/,/^(?::)/,/^(?:&)/,/^(?:;)/,/^(?:,)/,/^(?:\*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:[^-]|-(?!-)+)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:[^=]|=(?!))/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:[^\.]|\.(?!))/,/^(?:\s*~~[\~]+\s*)/,/^(?:[-/\)][\)])/,/^(?:[^\(\)\[\]\{\}]|!\)+)/,/^(?:\(-)/,/^(?:\]\))/,/^(?:\(\[)/,/^(?:\]\])/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:>)/,/^(?:\)\])/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\(\(\()/,/^(?:[\\(?=\])][\]])/,/^(?:\/(?=\])\])/,/^(?:\/(?!\])|\\(?!\])|[^\\\[\]\(\)\{\}\/]+)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:<)/,/^(?:>)/,/^(?:\^)/,/^(?:\\\|)/,/^(?:v\b)/,/^(?:\*)/,/^(?:#)/,/^(?:&)/,/^(?:([A-Za-z0-9!"\#$%&'*+\.`?\\_\/]|-(?=[^\>\-\.])|(?!))+)/,/^(?:-)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\|)/,/^(?:\|)/,/^(?:\))/,/^(?:\()/,/^(?:\])/,/^(?:\[)/,/^(?:(\}))/,/^(?:\{)/,/^(?:[^\[\]\(\)\{\}\|\"]+)/,/^(?:")/,/^(?:(\r?\n)+)/,/^(?:\s)/,/^(?:$)/],conditions:{shapeDataEndBracket:{rules:[21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},shapeDataStr:{rules:[9,10,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},shapeData:{rules:[8,11,12,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},callbackargs:{rules:[17,18,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},callbackname:{rules:[14,15,16,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},href:{rules:[21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},click:{rules:[21,24,33,34,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},dottedEdgeText:{rules:[21,24,73,75,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},thickEdgeText:{rules:[21,24,70,72,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},edgeText:{rules:[21,24,67,69,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},trapText:{rules:[21,24,76,79,81,83,87,89,90,91,92,93,94,107,109,111,113],inclusive:!1},ellipseText:{rules:[21,24,76,77,78,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},text:{rules:[21,24,76,79,80,81,82,83,86,87,88,89,93,94,106,107,108,109,110,111,112,113,114],inclusive:!1},vertex:{rules:[21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},dir:{rules:[21,24,44,45,46,47,48,49,50,51,52,53,54,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},acc_descr_multiline:{rules:[5,6,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},acc_descr:{rules:[3,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},acc_title:{rules:[1,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},md_string:{rules:[19,20,21,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},string:{rules:[21,22,23,24,76,79,81,83,87,89,93,94,107,109,111,113],inclusive:!1},INITIAL:{rules:[0,2,4,7,13,21,24,25,26,27,28,29,30,31,32,35,36,37,38,39,40,41,42,43,55,56,57,58,59,60,61,62,63,64,65,66,67,68,70,71,73,74,76,79,81,83,84,85,87,89,93,94,95,96,97,98,99,100,101,102,103,104,105,107,109,111,113,115,116,117,118],inclusive:!0}}}}();function ee(){this.yy={}}return Jt.lexer=te,(0,l.K2)(ee,"Parser"),ee.prototype=Jt,Jt.Parser=ee,new ee}();bt.parser=bt;var Et=bt,mt=(0,l.K2)(((t,e)=>{const s=d.A,n=s(t,"r"),r=s(t,"g"),i=s(t,"b");return p.A(n,r,i,e)}),"fade"),Dt={parser:Et,db:yt,renderer:kt,styles:(0,l.K2)((t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n .cluster-label text {\n fill: ${t.titleColor};\n }\n .cluster-label span {\n color: ${t.titleColor};\n }\n .cluster-label span p {\n background-color: transparent;\n }\n\n .label text,span {\n fill: ${t.nodeTextColor||t.textColor};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n .rough-node .label text , .node .label text, .image-shape .label, .icon-shape .label {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .katex path {\n fill: #000;\n stroke: #000;\n stroke-width: 1px;\n }\n\n .rough-node .label,.node .label, .image-shape .label, .icon-shape .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n\n .root .anchor path {\n fill: ${t.lineColor} !important;\n stroke-width: 0;\n stroke: ${t.lineColor};\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${mt(t.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .cluster rect {\n fill: ${t.clusterBkg};\n stroke: ${t.clusterBorder};\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n .cluster span {\n color: ${t.titleColor};\n }\n /* .cluster div {\n color: ${t.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n\n rect.text {\n fill: none;\n stroke-width: 0;\n }\n\n .icon-shape, .image-shape {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n padding: 2px;\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n`),"getStyles"),init:(0,l.K2)((t=>{t.flowchart||(t.flowchart={}),t.layout&&(0,l.XV)({layout:t.layout}),t.flowchart.arrowMarkerAbsolute=t.arrowMarkerAbsolute,(0,l.XV)({flowchart:{arrowMarkerAbsolute:t.arrowMarkerAbsolute}}),yt.clear(),yt.setGen("gen-2")}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1711.0c8f9a6a.js b/pr-preview/pr-976/assets/js/1711.0c8f9a6a.js new file mode 100644 index 0000000000..507c277538 --- /dev/null +++ b/pr-preview/pr-976/assets/js/1711.0c8f9a6a.js @@ -0,0 +1 @@ +(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1711],{97375:function(t){t.exports=function(){"use strict";return function(t,e){var n=e.prototype,i=n.format;n.format=function(t){var e=this,n=this.$locale();if(!this.isValid())return i.bind(this)(t);var s=this.$utils(),r=(t||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(t){switch(t){case"Q":return Math.ceil((e.$M+1)/3);case"Do":return n.ordinal(e.$D);case"gggg":return e.weekYear();case"GGGG":return e.isoWeekYear();case"wo":return n.ordinal(e.week(),"W");case"w":case"ww":return s.s(e.week(),"w"===t?1:2,"0");case"W":case"WW":return s.s(e.isoWeek(),"W"===t?1:2,"0");case"k":case"kk":return s.s(String(0===e.$H?24:e.$H),"k"===t?1:2,"0");case"X":return Math.floor(e.$d.getTime()/1e3);case"x":return e.$d.getTime();case"z":return"["+e.offsetName()+"]";case"zzz":return"["+e.offsetName("long")+"]";default:return t}}));return i.bind(this)(r)}}}()},90445:function(t){t.exports=function(){"use strict";var t={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},e=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\d/,i=/\d\d/,s=/\d\d?/,r=/\d*[^-_:/,()\s\d]+/,a={},o=function(t){return(t=+t)+(t>68?1900:2e3)},c=function(t){return function(e){this[t]=+e}},l=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],d=function(t){var e=a[t];return e&&(e.indexOf?e:e.s.concat(e.f))},u=function(t,e){var n,i=a.meridiem;if(i){for(var s=1;s<=24;s+=1)if(t.indexOf(i(s,0,e))>-1){n=s>12;break}}else n=t===(e?"pm":"PM");return n},h={A:[r,function(t){this.afternoon=u(t,!1)}],a:[r,function(t){this.afternoon=u(t,!0)}],Q:[n,function(t){this.month=3*(t-1)+1}],S:[n,function(t){this.milliseconds=100*+t}],SS:[i,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[s,c("seconds")],ss:[s,c("seconds")],m:[s,c("minutes")],mm:[s,c("minutes")],H:[s,c("hours")],h:[s,c("hours")],HH:[s,c("hours")],hh:[s,c("hours")],D:[s,c("day")],DD:[i,c("day")],Do:[r,function(t){var e=a.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var i=1;i<=31;i+=1)e(i).replace(/\[|\]/g,"")===t&&(this.day=i)}],w:[s,c("week")],ww:[i,c("week")],M:[s,c("month")],MM:[i,c("month")],MMM:[r,function(t){var e=d("months"),n=(d("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[r,function(t){var e=d("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,c("year")],YY:[i,function(t){this.year=o(t)}],YYYY:[/\d{4}/,c("year")],Z:l,ZZ:l};function f(n){var i,s;i=n,s=a&&a.formats;for(var r=(n=i.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,i){var r=i&&i.toUpperCase();return n||s[i]||t[i]||s[r].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),o=r.length,c=0;c-1)return new Date(("X"===e?1e3:1)*t);var s=f(e)(t),r=s.year,a=s.month,o=s.day,c=s.hours,l=s.minutes,d=s.seconds,u=s.milliseconds,h=s.zone,y=s.week,k=new Date,m=o||(r||a?1:k.getDate()),p=r||k.getFullYear(),g=0;r&&!a||(g=a>0?a-1:k.getMonth());var b,T=c||0,v=l||0,x=d||0,w=u||0;return h?new Date(Date.UTC(p,g,m,T,v,x,w+60*h.offset*1e3)):n?new Date(Date.UTC(p,g,m,T,v,x,w)):(b=new Date(p,g,m,T,v,x,w),y&&(b=i(b).week(y).toDate()),b)}catch(t){return new Date("")}}(e,o,i,n),this.init(),u&&!0!==u&&(this.$L=this.locale(u).$L),d&&e!=this.format(o)&&(this.$d=new Date("")),a={}}else if(o instanceof Array)for(var h=o.length,y=1;y<=h;y+=1){r[1]=o[y-1];var k=n.apply(this,r);if(k.isValid()){this.$d=k.$d,this.$L=k.$L,this.init();break}y===h&&(this.$d=new Date(""))}else s.call(this,t)}}}()},68313:function(t){t.exports=function(){"use strict";var t="day";return function(e,n,i){var s=function(e){return e.add(4-e.isoWeekday(),t)},r=n.prototype;r.isoWeekYear=function(){return s(this).year()},r.isoWeek=function(e){if(!this.$utils().u(e))return this.add(7*(e-this.isoWeek()),t);var n,r,a,o=s(this),c=(n=this.isoWeekYear(),a=4-(r=(this.$u?i.utc:i)().year(n).startOf("year")).isoWeekday(),r.isoWeekday()>4&&(a+=7),r.add(a,t));return o.diff(c,"week")+1},r.isoWeekday=function(t){return this.$utils().u(t)?this.day()||7:this.day(this.day()%7?t:t-7)};var a=r.startOf;r.startOf=function(t,e){var n=this.$utils(),i=!!n.u(e)||e;return"isoweek"===n.p(t)?i?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):a.bind(this)(t,e)}}}()},81711:(t,e,n)=>{"use strict";n.d(e,{diagram:()=>Yt});var i=n(85039),s=n(45567),r=n(16750),a=n(74353),o=n(68313),c=n(90445),l=n(97375),d=n(20007),u=function(){var t=(0,s.K2)((function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n}),"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],n=[1,26],i=[1,27],r=[1,28],a=[1,29],o=[1,30],c=[1,31],l=[1,32],d=[1,33],u=[1,34],h=[1,9],f=[1,10],y=[1,11],k=[1,12],m=[1,13],p=[1,14],g=[1,15],b=[1,16],T=[1,19],v=[1,20],x=[1,21],w=[1,22],_=[1,23],D=[1,25],$=[1,35],C={trace:(0,s.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:(0,s.K2)((function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setWeekday("monday");break;case 9:i.setWeekday("tuesday");break;case 10:i.setWeekday("wednesday");break;case 11:i.setWeekday("thursday");break;case 12:i.setWeekday("friday");break;case 13:i.setWeekday("saturday");break;case 14:i.setWeekday("sunday");break;case 15:i.setWeekend("friday");break;case 16:i.setWeekend("saturday");break;case 17:i.setDateFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 18:i.enableInclusiveEndDates(),this.$=r[o].substr(18);break;case 19:i.TopAxis(),this.$=r[o].substr(8);break;case 20:i.setAxisFormat(r[o].substr(11)),this.$=r[o].substr(11);break;case 21:i.setTickInterval(r[o].substr(13)),this.$=r[o].substr(13);break;case 22:i.setExcludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 23:i.setIncludes(r[o].substr(9)),this.$=r[o].substr(9);break;case 24:i.setTodayMarker(r[o].substr(12)),this.$=r[o].substr(12);break;case 27:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 28:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 29:case 30:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 31:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 33:i.addTask(r[o-1],r[o]),this.$="task";break;case 34:this.$=r[o-1],i.setClickEvent(r[o-1],r[o],null);break;case 35:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],r[o]);break;case 36:this.$=r[o-2],i.setClickEvent(r[o-2],r[o-1],null),i.setLink(r[o-2],r[o]);break;case 37:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-2],r[o-1]),i.setLink(r[o-3],r[o]);break;case 38:this.$=r[o-2],i.setClickEvent(r[o-2],r[o],null),i.setLink(r[o-2],r[o-1]);break;case 39:this.$=r[o-3],i.setClickEvent(r[o-3],r[o-1],r[o]),i.setLink(r[o-3],r[o-2]);break;case 40:this.$=r[o-1],i.setLink(r[o-1],r[o]);break;case 41:case 47:this.$=r[o-1]+" "+r[o];break;case 42:case 43:case 45:this.$=r[o-2]+" "+r[o-1]+" "+r[o];break;case 44:case 46:this.$=r[o-3]+" "+r[o-2]+" "+r[o-1]+" "+r[o]}}),"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:i,14:r,15:a,16:o,17:c,18:l,19:18,20:d,21:u,22:h,23:f,24:y,25:k,26:m,27:p,28:g,29:b,30:T,31:v,33:x,35:w,36:_,37:24,38:D,40:$},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:n,13:i,14:r,15:a,16:o,17:c,18:l,19:18,20:d,21:u,22:h,23:f,24:y,25:k,26:m,27:p,28:g,29:b,30:T,31:v,33:x,35:w,36:_,37:24,38:D,40:$},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:(0,s.K2)((function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)}),"parseError"),parse:(0,s.K2)((function(t){var e=this,n=[0],i=[],r=[null],a=[],o=this.table,c="",l=0,d=0,u=0,h=a.slice.call(arguments,1),f=Object.create(this.lexer),y={yy:{}};for(var k in this.yy)Object.prototype.hasOwnProperty.call(this.yy,k)&&(y.yy[k]=this.yy[k]);f.setInput(t,y.yy),y.yy.lexer=f,y.yy.parser=this,void 0===f.yylloc&&(f.yylloc={});var m=f.yylloc;a.push(m);var p=f.options&&f.options.ranges;function g(){var t;return"number"!=typeof(t=i.pop()||f.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)((function(t){n.length=n.length-2*t,r.length=r.length-t,a.length=a.length-t}),"popStack"),(0,s.K2)(g,"lex");for(var b,T,v,x,w,_,D,$,C,S={};;){if(v=n[n.length-1],this.defaultActions[v]?x=this.defaultActions[v]:(null==b&&(b=g()),x=o[v]&&o[v][b]),void 0===x||!x.length||!x[0]){var K="";for(_ in C=[],o[v])this.terminals_[_]&&_>2&&C.push("'"+this.terminals_[_]+"'");K=f.showPosition?"Parse error on line "+(l+1)+":\n"+f.showPosition()+"\nExpecting "+C.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(K,{text:f.match,token:this.terminals_[b]||b,line:f.yylineno,loc:m,expected:C})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+b);switch(x[0]){case 1:n.push(b),r.push(f.yytext),a.push(f.yylloc),n.push(x[1]),b=null,T?(b=T,T=null):(d=f.yyleng,c=f.yytext,l=f.yylineno,m=f.yylloc,u>0&&u--);break;case 2:if(D=this.productions_[x[1]][1],S.$=r[r.length-D],S._$={first_line:a[a.length-(D||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(D||1)].first_column,last_column:a[a.length-1].last_column},p&&(S._$.range=[a[a.length-(D||1)].range[0],a[a.length-1].range[1]]),void 0!==(w=this.performAction.apply(S,[c,d,l,y.yy,x[1],r,a].concat(h))))return w;D&&(n=n.slice(0,-1*D*2),r=r.slice(0,-1*D),a=a.slice(0,-1*D)),n.push(this.productions_[x[1]][0]),r.push(S.$),a.push(S._$),$=o[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0}),"parse")},S=function(){return{EOF:1,parseError:(0,s.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,s.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,s.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,s.K2)((function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,s.K2)((function(){return this._more=!0,this}),"more"),reject:(0,s.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,s.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,s.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,s.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,s.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,s.K2)((function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1}),"test_match"),next:(0,s.K2)((function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,s.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,s.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,s.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,s.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,s.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,s.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,s.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,s.K2)((function(t,e,n,i){switch(n){case 0:return this.begin("open_directive"),"open_directive";case 1:return this.begin("acc_title"),31;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),33;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 15:case 18:case 21:case 24:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:case 9:case 10:case 12:case 13:break;case 11:return 10;case 14:this.begin("href");break;case 16:return 43;case 17:this.begin("callbackname");break;case 19:this.popState(),this.begin("callbackargs");break;case 20:return 41;case 22:return 42;case 23:this.begin("click");break;case 25:return 40;case 26:return 4;case 27:return 22;case 28:return 23;case 29:return 24;case 30:return 25;case 31:return 26;case 32:return 28;case 33:return 27;case 34:return 29;case 35:return 12;case 36:return 13;case 37:return 14;case 38:return 15;case 39:return 16;case 40:return 17;case 41:return 18;case 42:return 20;case 43:return 21;case 44:return"date";case 45:return 30;case 46:return"accDescription";case 47:return 36;case 48:return 38;case 49:return 39;case 50:return":";case 51:return 6;case 52:return"INVALID"}}),"anonymous"),rules:[/^(?:%%\{)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:%%(?!\{)*[^\n]*)/i,/^(?:[^\}]%%*[^\n]*)/i,/^(?:%%*[^\n]*[\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:%[^\n]*)/i,/^(?:href[\s]+["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:call[\s]+)/i,/^(?:\([\s]*\))/i,/^(?:\()/i,/^(?:[^(]*)/i,/^(?:\))/i,/^(?:[^)]*)/i,/^(?:click[\s]+)/i,/^(?:[\s\n])/i,/^(?:[^\s\n]*)/i,/^(?:gantt\b)/i,/^(?:dateFormat\s[^#\n;]+)/i,/^(?:inclusiveEndDates\b)/i,/^(?:topAxis\b)/i,/^(?:axisFormat\s[^#\n;]+)/i,/^(?:tickInterval\s[^#\n;]+)/i,/^(?:includes\s[^#\n;]+)/i,/^(?:excludes\s[^#\n;]+)/i,/^(?:todayMarker\s[^\n;]+)/i,/^(?:weekday\s+monday\b)/i,/^(?:weekday\s+tuesday\b)/i,/^(?:weekday\s+wednesday\b)/i,/^(?:weekday\s+thursday\b)/i,/^(?:weekday\s+friday\b)/i,/^(?:weekday\s+saturday\b)/i,/^(?:weekday\s+sunday\b)/i,/^(?:weekend\s+friday\b)/i,/^(?:weekend\s+saturday\b)/i,/^(?:\d\d\d\d-\d\d-\d\d\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accDescription\s[^#\n;]+)/i,/^(?:section\s[^\n]+)/i,/^(?:[^:\n]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},callbackargs:{rules:[21,22],inclusive:!1},callbackname:{rules:[18,19,20],inclusive:!1},href:{rules:[15,16],inclusive:!1},click:{rules:[24,25],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,17,23,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52],inclusive:!0}}}}();function K(){this.yy={}}return C.lexer=S,(0,s.K2)(K,"Parser"),K.prototype=C,C.Parser=K,new K}();u.parser=u;var h=u;a.extend(o),a.extend(c),a.extend(l);var f,y,k={friday:5,saturday:6},m="",p="",g=void 0,b="",T=[],v=[],x=new Map,w=[],_=[],D="",$="",C=["active","done","crit","milestone"],S=[],K=!1,E=!1,M="sunday",A="saturday",L=0,Y=(0,s.K2)((function(){w=[],_=[],D="",S=[],ht=0,f=void 0,y=void 0,mt=[],m="",p="",$="",g=void 0,b="",T=[],v=[],K=!1,E=!1,L=0,x=new Map,(0,s.IU)(),M="sunday",A="saturday"}),"clear"),I=(0,s.K2)((function(t){p=t}),"setAxisFormat"),W=(0,s.K2)((function(){return p}),"getAxisFormat"),F=(0,s.K2)((function(t){g=t}),"setTickInterval"),O=(0,s.K2)((function(){return g}),"getTickInterval"),P=(0,s.K2)((function(t){b=t}),"setTodayMarker"),B=(0,s.K2)((function(){return b}),"getTodayMarker"),z=(0,s.K2)((function(t){m=t}),"setDateFormat"),N=(0,s.K2)((function(){K=!0}),"enableInclusiveEndDates"),G=(0,s.K2)((function(){return K}),"endDatesAreInclusive"),H=(0,s.K2)((function(){E=!0}),"enableTopAxis"),R=(0,s.K2)((function(){return E}),"topAxisEnabled"),j=(0,s.K2)((function(t){$=t}),"setDisplayMode"),U=(0,s.K2)((function(){return $}),"getDisplayMode"),V=(0,s.K2)((function(){return m}),"getDateFormat"),Z=(0,s.K2)((function(t){T=t.toLowerCase().split(/[\s,]+/)}),"setIncludes"),X=(0,s.K2)((function(){return T}),"getIncludes"),q=(0,s.K2)((function(t){v=t.toLowerCase().split(/[\s,]+/)}),"setExcludes"),Q=(0,s.K2)((function(){return v}),"getExcludes"),J=(0,s.K2)((function(){return x}),"getLinks"),tt=(0,s.K2)((function(t){D=t,w.push(t)}),"addSection"),et=(0,s.K2)((function(){return w}),"getSections"),nt=(0,s.K2)((function(){let t=vt();let e=0;for(;!t&&e<10;)t=vt(),e++;return _=mt}),"getTasks"),it=(0,s.K2)((function(t,e,n,i){return!i.includes(t.format(e.trim()))&&(!(!n.includes("weekends")||t.isoWeekday()!==k[A]&&t.isoWeekday()!==k[A]+1)||(!!n.includes(t.format("dddd").toLowerCase())||n.includes(t.format(e.trim()))))}),"isInvalidDate"),st=(0,s.K2)((function(t){M=t}),"setWeekday"),rt=(0,s.K2)((function(){return M}),"getWeekday"),at=(0,s.K2)((function(t){A=t}),"setWeekend"),ot=(0,s.K2)((function(t,e,n,i){if(!n.length||t.manualEndTime)return;let s,r;s=t.startTime instanceof Date?a(t.startTime):a(t.startTime,e,!0),s=s.add(1,"d"),r=t.endTime instanceof Date?a(t.endTime):a(t.endTime,e,!0);const[o,c]=ct(s,r,e,n,i);t.endTime=o.toDate(),t.renderEndTime=c}),"checkTaskDates"),ct=(0,s.K2)((function(t,e,n,i,s){let r=!1,a=null;for(;t<=e;)r||(a=e.toDate()),r=it(t,n,i,s),r&&(e=e.add(1,"d")),t=t.add(1,"d");return[e,a]}),"fixTaskDates"),lt=(0,s.K2)((function(t,e,n){n=n.trim();const i=/^after\s+(?[\d\w- ]+)/.exec(n);if(null!==i){let t=null;for(const n of i.groups.ids.split(" ")){let e=bt(n);void 0!==e&&(!t||e.endTime>t.endTime)&&(t=e)}if(t)return t.endTime;const e=new Date;return e.setHours(0,0,0,0),e}let r=a(n,e.trim(),!0);if(r.isValid())return r.toDate();{s.Rm.debug("Invalid date:"+n),s.Rm.debug("With date format:"+e.trim());const t=new Date(n);if(void 0===t||isNaN(t.getTime())||t.getFullYear()<-1e4||t.getFullYear()>1e4)throw new Error("Invalid date:"+n);return t}}),"getStartDate"),dt=(0,s.K2)((function(t){const e=/^(\d+(?:\.\d+)?)([Mdhmswy]|ms)$/.exec(t.trim());return null!==e?[Number.parseFloat(e[1]),e[2]]:[NaN,"ms"]}),"parseDuration"),ut=(0,s.K2)((function(t,e,n,i=!1){n=n.trim();const s=/^until\s+(?[\d\w- ]+)/.exec(n);if(null!==s){let t=null;for(const n of s.groups.ids.split(" ")){let e=bt(n);void 0!==e&&(!t||e.startTime{window.open(n,"_self")})),x.set(t,n))})),wt(t,"clickable")}),"setLink"),wt=(0,s.K2)((function(t,e){t.split(",").forEach((function(t){let n=bt(t);void 0!==n&&n.classes.push(e)}))}),"setClass"),_t=(0,s.K2)((function(t,e,n){if("loose"!==(0,s.D7)().securityLevel)return;if(void 0===e)return;let r=[];if("string"==typeof n){r=n.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t{i._K.runFunc(e,...r)}))}),"setClickFun"),Dt=(0,s.K2)((function(t,e){S.push((function(){const n=document.querySelector(`[id="${t}"]`);null!==n&&n.addEventListener("click",(function(){e()}))}),(function(){const n=document.querySelector(`[id="${t}-text"]`);null!==n&&n.addEventListener("click",(function(){e()}))}))}),"pushFun"),$t=(0,s.K2)((function(t,e,n){t.split(",").forEach((function(t){_t(t,e,n)})),wt(t,"clickable")}),"setClickEvent"),Ct=(0,s.K2)((function(t){S.forEach((function(e){e(t)}))}),"bindFunctions"),St={getConfig:(0,s.K2)((()=>(0,s.D7)().gantt),"getConfig"),clear:Y,setDateFormat:z,getDateFormat:V,enableInclusiveEndDates:N,endDatesAreInclusive:G,enableTopAxis:H,topAxisEnabled:R,setAxisFormat:I,getAxisFormat:W,setTickInterval:F,getTickInterval:O,setTodayMarker:P,getTodayMarker:B,setAccTitle:s.SV,getAccTitle:s.iN,setDiagramTitle:s.ke,getDiagramTitle:s.ab,setDisplayMode:j,getDisplayMode:U,setAccDescription:s.EI,getAccDescription:s.m7,addSection:tt,getSections:et,getTasks:nt,addTask:gt,findTaskById:bt,addTaskOrg:Tt,setIncludes:Z,getIncludes:X,setExcludes:q,getExcludes:Q,setClickEvent:$t,setLink:xt,getLinks:J,bindFunctions:Ct,parseDuration:dt,isInvalidDate:it,setWeekday:st,getWeekday:rt,setWeekend:at};function Kt(t,e,n){let i=!0;for(;i;)i=!1,n.forEach((function(n){const s=new RegExp("^\\s*"+n+"\\s*$");t[0].match(s)&&(e[n]=!0,t.shift(1),i=!0)}))}(0,s.K2)(Kt,"getTaskTags");var Et,Mt=(0,s.K2)((function(){s.Rm.debug("Something is calling, setConf, remove the call")}),"setConf"),At={monday:d.ABi,tuesday:d.PGu,wednesday:d.GuW,thursday:d.Mol,friday:d.TUC,saturday:d.rGn,sunday:d.YPH},Lt=(0,s.K2)(((t,e)=>{let n=[...t].map((()=>-1/0)),i=[...t].sort(((t,e)=>t.startTime-e.startTime||t.order-e.order)),s=0;for(const r of i)for(let t=0;t=n[t]){n[t]=r.endTime,r.order=t+e,t>s&&(s=t);break}return s}),"getMaxIntersections"),Yt={parser:h,db:St,renderer:{setConf:Mt,draw:(0,s.K2)((function(t,e,n,i){const r=(0,s.D7)().gantt,o=(0,s.D7)().securityLevel;let c;"sandbox"===o&&(c=(0,d.Ltv)("#i"+e));const l="sandbox"===o?(0,d.Ltv)(c.nodes()[0].contentDocument.body):(0,d.Ltv)("body"),u="sandbox"===o?c.nodes()[0].contentDocument:document,h=u.getElementById(e);void 0===(Et=h.parentElement.offsetWidth)&&(Et=1200),void 0!==r.useWidth&&(Et=r.useWidth);const f=i.db.getTasks();let y=[];for(const s of f)y.push(s.type);y=$(y);const k={};let m=2*r.topPadding;if("compact"===i.db.getDisplayMode()||"compact"===r.displayMode){const t={};for(const n of f)void 0===t[n.section]?t[n.section]=[n]:t[n.section].push(n);let e=0;for(const n of Object.keys(t)){const i=Lt(t[n],e)+1;e+=i,m+=i*(r.barHeight+r.barGap),k[n]=i}}else{m+=f.length*(r.barHeight+r.barGap);for(const t of y)k[t]=f.filter((e=>e.type===t)).length}h.setAttribute("viewBox","0 0 "+Et+" "+m);const p=l.select(`[id="${e}"]`),g=(0,d.w7C)().domain([(0,d.jkA)(f,(function(t){return t.startTime})),(0,d.T9B)(f,(function(t){return t.endTime}))]).rangeRound([0,Et-r.leftPadding-r.rightPadding]);function b(t,e){const n=t.startTime,i=e.startTime;let s=0;return n>i?s=1:nt.order)))].map((e=>t.find((t=>t.order===e))));p.append("g").selectAll("rect").data(h).enter().append("rect").attr("x",0).attr("y",(function(t,e){return t.order*n+a-2})).attr("width",(function(){return u-r.rightPadding/2})).attr("height",n).attr("class",(function(t){for(const[e,n]of y.entries())if(t.type===n)return"section section"+e%r.numberSectionStyles;return"section section0"}));const f=p.append("g").selectAll("rect").data(t).enter(),k=i.db.getLinks();f.append("rect").attr("id",(function(t){return t.id})).attr("rx",3).attr("ry",3).attr("x",(function(t){return t.milestone?g(t.startTime)+o+.5*(g(t.endTime)-g(t.startTime))-.5*c:g(t.startTime)+o})).attr("y",(function(t,e){return t.order*n+a})).attr("width",(function(t){return t.milestone?c:g(t.renderEndTime||t.endTime)-g(t.startTime)})).attr("height",c).attr("transform-origin",(function(t,e){return e=t.order,(g(t.startTime)+o+.5*(g(t.endTime)-g(t.startTime))).toString()+"px "+(e*n+a+.5*c).toString()+"px"})).attr("class",(function(t){let e="";t.classes.length>0&&(e=t.classes.join(" "));let n=0;for(const[s,a]of y.entries())t.type===a&&(n=s%r.numberSectionStyles);let i="";return t.active?t.crit?i+=" activeCrit":i=" active":t.done?i=t.crit?" doneCrit":" done":t.crit&&(i+=" crit"),0===i.length&&(i=" task"),t.milestone&&(i=" milestone "+i),i+=n,i+=" "+e,"task"+i})),f.append("text").attr("id",(function(t){return t.id+"-text"})).text((function(t){return t.task})).attr("font-size",r.fontSize).attr("x",(function(t){let e=g(t.startTime),n=g(t.renderEndTime||t.endTime);t.milestone&&(e+=.5*(g(t.endTime)-g(t.startTime))-.5*c),t.milestone&&(n=e+c);const i=this.getBBox().width;return i>n-e?n+i+1.5*r.leftPadding>u?e+o-5:n+o+5:(n-e)/2+e+o})).attr("y",(function(t,e){return t.order*n+r.barHeight/2+(r.fontSize/2-2)+a})).attr("text-height",c).attr("class",(function(t){const e=g(t.startTime);let n=g(t.endTime);t.milestone&&(n=e+c);const i=this.getBBox().width;let s="";t.classes.length>0&&(s=t.classes.join(" "));let a=0;for(const[c,l]of y.entries())t.type===l&&(a=c%r.numberSectionStyles);let o="";return t.active&&(o=t.crit?"activeCritText"+a:"activeText"+a),t.done?o=t.crit?o+" doneCritText"+a:o+" doneText"+a:t.crit&&(o=o+" critText"+a),t.milestone&&(o+=" milestoneText"),i>n-e?n+i+1.5*r.leftPadding>u?s+" taskTextOutsideLeft taskTextOutside"+a+" "+o:s+" taskTextOutsideRight taskTextOutside"+a+" "+o+" width-"+i:s+" taskText taskText"+a+" "+o+" width-"+i}));if("sandbox"===(0,s.D7)().securityLevel){let t;t=(0,d.Ltv)("#i"+e);const n=t.nodes()[0].contentDocument;f.filter((function(t){return k.has(t.id)})).each((function(t){var e=n.querySelector("#"+t.id),i=n.querySelector("#"+t.id+"-text");const s=e.parentNode;var r=n.createElement("a");r.setAttribute("xlink:href",k.get(t.id)),r.setAttribute("target","_top"),s.appendChild(r),r.appendChild(e),r.appendChild(i)}))}}function x(t,e,n,o,c,l,d,u){if(0===d.length&&0===u.length)return;let h,f;for(const{startTime:i,endTime:s}of l)(void 0===h||if)&&(f=s);if(!h||!f)return;if(a(f).diff(a(h),"year")>5)return void s.Rm.warn("The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.");const y=i.db.getDateFormat(),k=[];let m=null,b=a(h);for(;b.valueOf()<=f;)i.db.isInvalidDate(b,y,d,u)?m?m.end=b:m={start:b,end:b}:m&&(k.push(m),m=null),b=b.add(1,"d");p.append("g").selectAll("rect").data(k).enter().append("rect").attr("id",(function(t){return"exclude-"+t.start.format("YYYY-MM-DD")})).attr("x",(function(t){return g(t.start)+n})).attr("y",r.gridLineStartPadding).attr("width",(function(t){const e=t.end.add(1,"day");return g(e)-g(t.start)})).attr("height",c-e-r.gridLineStartPadding).attr("transform-origin",(function(e,i){return(g(e.start)+n+.5*(g(e.end)-g(e.start))).toString()+"px "+(i*t+.5*c).toString()+"px"})).attr("class","exclude-range")}function w(t,e,n,s){let a=(0,d.l78)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,d.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));const o=/^([1-9]\d*)(millisecond|second|minute|hour|day|week|month)$/.exec(i.db.getTickInterval()||r.tickInterval);if(null!==o){const t=o[1],e=o[2],n=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":a.ticks(d.t6C.every(t));break;case"second":a.ticks(d.ucG.every(t));break;case"minute":a.ticks(d.wXd.every(t));break;case"hour":a.ticks(d.Agd.every(t));break;case"day":a.ticks(d.UAC.every(t));break;case"week":a.ticks(At[n].every(t));break;case"month":a.ticks(d.Ui6.every(t))}}if(p.append("g").attr("class","grid").attr("transform","translate("+t+", "+(s-50)+")").call(a).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10).attr("dy","1em"),i.db.topAxisEnabled()||r.topAxis){let n=(0,d.tlR)(g).tickSize(-s+e+r.gridLineStartPadding).tickFormat((0,d.DCK)(i.db.getAxisFormat()||r.axisFormat||"%Y-%m-%d"));if(null!==o){const t=o[1],e=o[2],s=i.db.getWeekday()||r.weekday;switch(e){case"millisecond":n.ticks(d.t6C.every(t));break;case"second":n.ticks(d.ucG.every(t));break;case"minute":n.ticks(d.wXd.every(t));break;case"hour":n.ticks(d.Agd.every(t));break;case"day":n.ticks(d.UAC.every(t));break;case"week":n.ticks(At[s].every(t));break;case"month":n.ticks(d.Ui6.every(t))}}p.append("g").attr("class","grid").attr("transform","translate("+t+", "+e+")").call(n).selectAll("text").style("text-anchor","middle").attr("fill","#000").attr("stroke","none").attr("font-size",10)}}function _(t,e){let n=0;const i=Object.keys(k).map((t=>[t,k[t]]));p.append("g").selectAll("text").data(i).enter().append((function(t){const e=t[0].split(s.Y2.lineBreakRegex),n=-(e.length-1)/2,i=u.createElementNS("http://www.w3.org/2000/svg","text");i.setAttribute("dy",n+"em");for(const[s,r]of e.entries()){const t=u.createElementNS("http://www.w3.org/2000/svg","tspan");t.setAttribute("alignment-baseline","central"),t.setAttribute("x","10"),s>0&&t.setAttribute("dy","1em"),t.textContent=r,i.appendChild(t)}return i})).attr("x",10).attr("y",(function(s,r){if(!(r>0))return s[1]*t/2+e;for(let a=0;a`\n .mermaid-main-font {\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .exclude-range {\n fill: ${t.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${t.sectionBkgColor};\n }\n\n .section2 {\n fill: ${t.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${t.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${t.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${t.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n }\n\n .grid .tick text {\n font-family: ${t.fontFamily};\n fill: ${t.textColor};\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${t.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideRight {\n fill: ${t.taskTextDarkColor};\n text-anchor: start;\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideLeft {\n fill: ${t.taskTextDarkColor};\n text-anchor: end;\n }\n\n\n /* Special case clickable */\n\n .task.clickable {\n cursor: pointer;\n }\n\n .taskText.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${t.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${t.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${t.taskBkgColor};\n stroke: ${t.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${t.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${t.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${t.activeTaskBkgColor};\n stroke: ${t.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${t.doneTaskBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${t.critBorderColor};\n fill: ${t.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${t.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.titleColor||t.textColor};\n font-family: var(--mermaid-font-family, "trebuchet ms", verdana, arial, sans-serif);\n }\n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/173fd1a8.8751a104.js b/pr-preview/pr-976/assets/js/173fd1a8.8751a104.js new file mode 100644 index 0000000000..ec5c56f0c0 --- /dev/null +++ b/pr-preview/pr-976/assets/js/173fd1a8.8751a104.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1514],{71144:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-0.7/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/0.7/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/basics/features.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.7/basics/security-benefits"},"next":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"../architecture",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/17896441.7a01a35f.js b/pr-preview/pr-976/assets/js/17896441.7a01a35f.js new file mode 100644 index 0000000000..fd03ea9e57 --- /dev/null +++ b/pr-preview/pr-976/assets/js/17896441.7a01a35f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8401],{7084:(s,c,t)=>{t.d(c,{A:()=>o});var a=t(94763),e=t(87119),n=t(76487);const o={...a.A,Tabs:e.A,TabItem:n.A}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1ab97833.9e49478d.js b/pr-preview/pr-976/assets/js/1ab97833.9e49478d.js new file mode 100644 index 0000000000..76a71e73a1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/1ab97833.9e49478d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[985],{29083:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-1.0/components/overview.md","sourceDirName":"components","slug":"/components/overview","permalink":"/contrast/pr-preview/pr-976/1.0/components/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/components/overview.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/1.0/troubleshooting"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/1.0/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},l=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(45426).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},45426:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1c9b88ee.ba0039db.js b/pr-preview/pr-976/assets/js/1c9b88ee.ba0039db.js new file mode 100644 index 0000000000..8c9f69066f --- /dev/null +++ b/pr-preview/pr-976/assets/js/1c9b88ee.ba0039db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1560],{62538:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-0.6/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/getting-started/install.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup"}}');var r=n(74848),a=n(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>o,x:()=>i});var s=n(96540);const r={},a=s.createContext(r);function o(t){const e=s.useContext(a);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),s.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1e7c9753.02e56af3.js b/pr-preview/pr-976/assets/js/1e7c9753.02e56af3.js new file mode 100644 index 0000000000..c35bc82a4c --- /dev/null +++ b/pr-preview/pr-976/assets/js/1e7c9753.02e56af3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3391],{99028:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-1.1/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/basics/features.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/basics/security-benefits"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/getting-started/install"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/1ea8f7a3.d2d50582.js b/pr-preview/pr-976/assets/js/1ea8f7a3.d2d50582.js new file mode 100644 index 0000000000..600092eed7 --- /dev/null +++ b/pr-preview/pr-976/assets/js/1ea8f7a3.d2d50582.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4555],{48376:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"0.6","label":"0.6","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.6","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"What is Contrast?","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/0.6/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/"},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/0.6/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/getting-started/"},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/examples/"},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/0.6/deployment","docId":"deployment","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/0.6/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/0.6/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/0.6/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/components/"},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/0.6/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/0.6/architecture/certificates","docId":"architecture/certificates","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/architecture/"},{"type":"link","label":"Known limitations","href":"/contrast/pr-preview/pr-976/0.6/known-limitations","docId":"known-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/0.6/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.6/about/"}]},"docs":{"about/index":{"id":"about/index","title":"About","description":"","sidebar":"docs"},"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/index":{"id":"architecture/index","title":"Architecture","description":"","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/index":{"id":"components/index","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service Mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"examples/index":{"id":"examples/index","title":"Examples","description":"","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"known-limitations":{"id":"known-limitations","title":"Known Limitations","description":"As Contrast is currently in an early development stage, it\'s built on several projects that are also under active development.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/20382dd7.20e8921f.js b/pr-preview/pr-976/assets/js/20382dd7.20e8921f.js new file mode 100644 index 0000000000..71a6cc08c4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/20382dd7.20e8921f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3357],{33961:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"architecture/attestation/runtime-policies","title":"runtime-policies","description":"","source":"@site/versioned_docs/version-0.5/architecture/attestation/runtime-policies.md","sourceDirName":"architecture/attestation","slug":"/architecture/attestation/runtime-policies","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/attestation/runtime-policies.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Pod VM","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm"},"next":{"title":"Manifest","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest"}}');var i=n(74848),s=n(28453);const o={},c=void 0,a={},u=[];function p(t){return(0,i.jsx)(i.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,i.jsx)(e,{...t,children:(0,i.jsx)(p,{...t})}):p()}},28453:(t,e,n)=>{n.d(e,{R:()=>o,x:()=>c});var r=n(96540);const i={},s=r.createContext(i);function o(t){const e=r.useContext(s);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function c(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:o(t.components),r.createElement(s.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/207bb774.442bb435.js b/pr-preview/pr-976/assets/js/207bb774.442bb435.js new file mode 100644 index 0000000000..4b674ca6d5 --- /dev/null +++ b/pr-preview/pr-976/assets/js/207bb774.442bb435.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[430],{67766:(e,t,n)=>{n.d(t,{A:()=>k});var r=n(96540),o=n(34164),s=n(85246),c=n(57880),i=n(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const o=n.select(t),s=n.pluralForms.indexOf(o);return r[Math.min(s,r.length-1)]}(n,t,e)}}var p=n(77056),h=n(32032),f=n(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function b(e){let{href:t,children:n}=e;return(0,g.jsx)(c.A,{href:t,className:(0,o.A)("card padding--lg",x.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:r,description:s}=e;return(0,g.jsxs)(b,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,o.A)("text--truncate",x.cardTitle),title:r,children:[n," ",r]}),s&&(0,g.jsx)("p",{className:(0,o.A)("text--truncate",x.cardDescription),title:s,children:s})]})}function v(e){let{item:t}=e;const n=(0,s.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,h.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function w(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,s.cC)(t.docId??void 0);return(0,g.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function y(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(w,{item:t});case"category":return(0,g.jsx)(v,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function A(e){let{className:t}=e;const n=(0,s.$S)();return(0,g.jsx)(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(A,{...e});const r=(0,s.d1)(t);return(0,g.jsx)("section",{className:(0,o.A)("row",n),children:r.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(y,{item:e})},t)))})}},50880:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"about/index","title":"About","description":"","source":"@site/versioned_docs/version-0.6/about/index.md","sourceDirName":"about","slug":"/about/","permalink":"/contrast/pr-preview/pr-976/0.6/about/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/about/index.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Known limitations","permalink":"/contrast/pr-preview/pr-976/0.6/known-limitations"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/0.6/about/telemetry"}}');var o=n(74848),s=n(28453),c=n(67766);const i={},a="About",l={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"about",children:"About"})}),"\n","\n",(0,o.jsx)(c.A,{})]})}function m(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(96540);const o={},s=r.createContext(o);function c(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/20e0cfa9.1b701e80.js b/pr-preview/pr-976/assets/js/20e0cfa9.1b701e80.js new file mode 100644 index 0000000000..6978ea07e9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/20e0cfa9.1b701e80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8403],{69107:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-0.7/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/basics/confidential-containers.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Contrast","permalink":"/contrast/pr-preview/pr-976/0.7/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.7/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2130.a7c31b12.js b/pr-preview/pr-976/assets/js/2130.a7c31b12.js new file mode 100644 index 0000000000..edb87e73cd --- /dev/null +++ b/pr-preview/pr-976/assets/js/2130.a7c31b12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2130],{22130:(e,t,r)=>{r.d(t,{default:()=>Ja});class a{constructor(e,t,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=e,this.start=t,this.end=r}static range(e,t){return t?e&&e.loc&&t.loc&&e.loc.lexer===t.loc.lexer?new a(e.loc.lexer,e.loc.start,t.loc.end):null:e&&e.loc}}class n{constructor(e,t){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=e,this.loc=t}range(e,t){return new n(t,a.range(this,e))}}class i{constructor(e,t){this.name=void 0,this.position=void 0,this.length=void 0,this.rawMessage=void 0;var r,a,n="KaTeX parse error: "+e,o=t&&t.loc;if(o&&o.start<=o.end){var s=o.lexer.input;r=o.start,a=o.end,r===s.length?n+=" at end of input: ":n+=" at position "+(r+1)+": ";var l=s.slice(r,a).replace(/[^]/g,"$&\u0332");n+=(r>15?"\u2026"+s.slice(r-15,r):s.slice(0,r))+l+(a+15":">","<":"<",'"':""","'":"'"},l=/[&><"']/g;var h=function e(t){return"ordgroup"===t.type||"color"===t.type?1===t.body.length?e(t.body[0]):t:"font"===t.type?e(t.body):t},m={contains:function(e,t){return-1!==e.indexOf(t)},deflt:function(e,t){return void 0===e?t:e},escape:function(e){return String(e).replace(l,(e=>s[e]))},hyphenate:function(e){return e.replace(o,"-$1").toLowerCase()},getBaseElem:h,isCharacterBox:function(e){var t=h(e);return"mathord"===t.type||"textord"===t.type||"atom"===t.type},protocolFromUrl:function(e){var t=/^[\x00-\x20]*([^\\/#?]*?)(:|�*58|�*3a|&colon)/i.exec(e);return t?":"!==t[2]?null:/^[a-zA-Z][a-zA-Z0-9+\-.]*$/.test(t[1])?t[1].toLowerCase():null:"_relative"}},c={displayMode:{type:"boolean",description:"Render math in display mode, which puts the math in display style (so \\int and \\sum are large, for example), and centers the math on the page on its own line.",cli:"-d, --display-mode"},output:{type:{enum:["htmlAndMathml","html","mathml"]},description:"Determines the markup language of the output.",cli:"-F, --format "},leqno:{type:"boolean",description:"Render display math in leqno style (left-justified tags)."},fleqn:{type:"boolean",description:"Render display math flush left."},throwOnError:{type:"boolean",default:!0,cli:"-t, --no-throw-on-error",cliDescription:"Render errors (in the color given by --error-color) instead of throwing a ParseError exception when encountering an error."},errorColor:{type:"string",default:"#cc0000",cli:"-c, --error-color ",cliDescription:"A color string given in the format 'rgb' or 'rrggbb' (no #). This option determines the color of errors rendered by the -t option.",cliProcessor:e=>"#"+e},macros:{type:"object",cli:"-m, --macro ",cliDescription:"Define custom macro of the form '\\foo:expansion' (use multiple -m arguments for multiple macros).",cliDefault:[],cliProcessor:(e,t)=>(t.push(e),t)},minRuleThickness:{type:"number",description:"Specifies a minimum thickness, in ems, for fraction lines, `\\sqrt` top lines, `{array}` vertical lines, `\\hline`, `\\hdashline`, `\\underline`, `\\overline`, and the borders of `\\fbox`, `\\boxed`, and `\\fcolorbox`.",processor:e=>Math.max(0,e),cli:"--min-rule-thickness ",cliProcessor:parseFloat},colorIsTextColor:{type:"boolean",description:"Makes \\color behave like LaTeX's 2-argument \\textcolor, instead of LaTeX's one-argument \\color mode change.",cli:"-b, --color-is-text-color"},strict:{type:[{enum:["warn","ignore","error"]},"boolean","function"],description:"Turn on strict / LaTeX faithfulness mode, which throws an error if the input uses features that are not supported by LaTeX.",cli:"-S, --strict",cliDefault:!1},trust:{type:["boolean","function"],description:"Trust the input, enabling all HTML features such as \\url.",cli:"-T, --trust"},maxSize:{type:"number",default:1/0,description:"If non-zero, all user-specified sizes, e.g. in \\rule{500em}{500em}, will be capped to maxSize ems. Otherwise, elements and spaces can be arbitrarily large",processor:e=>Math.max(0,e),cli:"-s, --max-size ",cliProcessor:parseInt},maxExpand:{type:"number",default:1e3,description:"Limit the number of macro expansions to the specified number, to prevent e.g. infinite macro loops. If set to Infinity, the macro expander will try to fully expand as in LaTeX.",processor:e=>Math.max(0,e),cli:"-e, --max-expand ",cliProcessor:e=>"Infinity"===e?1/0:parseInt(e)},globalGroup:{type:"boolean",cli:!1}};function p(e){if(e.default)return e.default;var t=e.type,r=Array.isArray(t)?t[0]:t;if("string"!=typeof r)return r.enum[0];switch(r){case"boolean":return!1;case"string":return"";case"number":return 0;case"object":return{}}}class u{constructor(e){for(var t in this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,e=e||{},c)if(c.hasOwnProperty(t)){var r=c[t];this[t]=void 0!==e[t]?r.processor?r.processor(e[t]):e[t]:p(r)}}reportNonstrict(e,t,r){var a=this.strict;if("function"==typeof a&&(a=a(e,t,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new i("LaTeX-incompatible input and strict mode is set to 'error': "+t+" ["+e+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]")}}useStrictBehavior(e,t,r){var a=this.strict;if("function"==typeof a)try{a=a(e,t,r)}catch(n){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+t+" ["+e+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+t+" ["+e+"]"),!1)))}isTrusted(e){if(e.url&&!e.protocol){var t=m.protocolFromUrl(e.url);if(null==t)return!1;e.protocol=t}var r="function"==typeof this.trust?this.trust(e):this.trust;return Boolean(r)}}class d{constructor(e,t,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=e,this.size=t,this.cramped=r}sup(){return g[f[this.id]]}sub(){return g[v[this.id]]}fracNum(){return g[b[this.id]]}fracDen(){return g[y[this.id]]}cramp(){return g[x[this.id]]}text(){return g[w[this.id]]}isTight(){return this.size>=2}}var g=[new d(0,0,!1),new d(1,0,!0),new d(2,1,!1),new d(3,1,!0),new d(4,2,!1),new d(5,2,!0),new d(6,3,!1),new d(7,3,!0)],f=[4,5,4,5,6,7,6,7],v=[5,5,5,5,7,7,7,7],b=[2,3,4,5,6,7,6,7],y=[3,3,5,5,7,7,7,7],x=[1,1,3,3,5,5,7,7],w=[0,1,2,3,2,3,2,3],k={DISPLAY:g[0],TEXT:g[2],SCRIPT:g[4],SCRIPTSCRIPT:g[6]},S=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"armenian",blocks:[[1328,1423]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var M=[];function z(e){for(var t=0;t=M[t]&&e<=M[t+1])return!0;return!1}S.forEach((e=>e.blocks.forEach((e=>M.push(...e)))));var A=80,T={doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"};class B{constructor(e){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=e,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}hasClass(e){return m.contains(this.classes,e)}toNode(){for(var e=document.createDocumentFragment(),t=0;te.toText())).join("")}}var C={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8773:[.027,.638,0,0,.894],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.123,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,.778],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.673,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.903,0,0,.278],8943:[-.19,.313,0,0,1.172],8945:[-.1,.823,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.745,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.745,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},N={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},q={"\xc5":"A","\xd0":"D","\xde":"o","\xe5":"a","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function I(e,t,r){if(!C[t])throw new Error("Font metrics not found for font: "+t+".");var a=e.charCodeAt(0),n=C[t][a];if(!n&&e[0]in q&&(a=q[e[0]].charCodeAt(0),n=C[t][a]),n||"text"!==r||z(a)&&(n=C[t][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}var R={};var H=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],O=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],E=function(e,t){return t.size<2?e:H[e-1][t.size-1]};class L{constructor(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||L.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=O[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}extend(e){var t={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return new L(t)}havingStyle(e){return this.style===e?this:this.extend({style:e,size:E(this.textSize,e)})}havingCrampedStyle(){return this.havingStyle(this.style.cramp())}havingSize(e){return this.size===e&&this.textSize===e?this:this.extend({style:this.style.text(),size:e,textSize:e,sizeMultiplier:O[e-1]})}havingBaseStyle(e){e=e||this.style.text();var t=E(L.BASESIZE,e);return this.size===t&&this.textSize===L.BASESIZE&&this.style===e?this:this.extend({style:e,size:t})}havingBaseSizing(){var e;switch(this.style.id){case 4:case 5:e=3;break;case 6:case 7:e=1;break;default:e=6}return this.extend({style:this.style.text(),size:e})}withColor(e){return this.extend({color:e})}withPhantom(){return this.extend({phantom:!0})}withFont(e){return this.extend({font:e})}withTextFontFamily(e){return this.extend({fontFamily:e,font:""})}withTextFontWeight(e){return this.extend({fontWeight:e,font:""})}withTextFontShape(e){return this.extend({fontShape:e,font:""})}sizingClasses(e){return e.size!==this.size?["sizing","reset-size"+e.size,"size"+this.size]:[]}baseSizingClasses(){return this.size!==L.BASESIZE?["sizing","reset-size"+this.size,"size"+L.BASESIZE]:[]}fontMetrics(){return this._fontMetrics||(this._fontMetrics=function(e){var t;if(!R[t=e>=5?0:e>=3?1:2]){var r=R[t]={cssEmPerMu:N.quad[t]/18};for(var a in N)N.hasOwnProperty(a)&&(r[a]=N[a][t])}return R[t]}(this.size)),this._fontMetrics}getColor(){return this.phantom?"transparent":this.color}}L.BASESIZE=6;var D={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},V={ex:!0,em:!0,mu:!0},P=function(e){return"string"!=typeof e&&(e=e.unit),e in D||e in V||"ex"===e},F=function(e,t){var r;if(e.unit in D)r=D[e.unit]/t.fontMetrics().ptPerEm/t.sizeMultiplier;else if("mu"===e.unit)r=t.fontMetrics().cssEmPerMu;else{var a;if(a=t.style.isTight()?t.havingStyle(t.style.text()):t,"ex"===e.unit)r=a.fontMetrics().xHeight;else{if("em"!==e.unit)throw new i("Invalid unit: '"+e.unit+"'");r=a.fontMetrics().quad}a!==t&&(r*=a.sizeMultiplier/t.sizeMultiplier)}return Math.min(e.number*r,t.maxSize)},G=function(e){return+e.toFixed(4)+"em"},U=function(e){return e.filter((e=>e)).join(" ")},Y=function(e,t,r){if(this.classes=e||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},t){t.style.isTight()&&this.classes.push("mtight");var a=t.getColor();a&&(this.style.color=a)}},X=function(e){var t=document.createElement(e);for(var r in t.className=U(this.classes),this.style)this.style.hasOwnProperty(r)&&(t.style[r]=this.style[r]);for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&t.setAttribute(a,this.attributes[a]);for(var n=0;n"};class _{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,e,r,a),this.children=t||[]}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"span")}toMarkup(){return W.call(this,"span")}}class j{constructor(e,t,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,Y.call(this,t,a),this.children=r||[],this.setAttribute("href",e)}setAttribute(e,t){this.attributes[e]=t}hasClass(e){return m.contains(this.classes,e)}toNode(){return X.call(this,"a")}toMarkup(){return W.call(this,"a")}}class ${constructor(e,t,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=t,this.src=e,this.classes=["mord"],this.style=r}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createElement("img");for(var t in e.src=this.src,e.alt=this.alt,e.className="mord",this.style)this.style.hasOwnProperty(t)&&(e.style[t]=this.style[t]);return e}toMarkup(){var e=''+m.escape(this.alt)+'=n[0]&&e<=n[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=Z[this.text])}hasClass(e){return m.contains(this.classes,e)}toNode(){var e=document.createTextNode(this.text),t=null;for(var r in this.italic>0&&((t=document.createElement("span")).style.marginRight=G(this.italic)),this.classes.length>0&&((t=t||document.createElement("span")).className=U(this.classes)),this.style)this.style.hasOwnProperty(r)&&((t=t||document.createElement("span")).style[r]=this.style[r]);return t?(t.appendChild(e),t):e}toMarkup(){var e=!1,t="0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=m.hyphenate(a)+":"+this.style[a]+";");r&&(e=!0,t+=' style="'+m.escape(r)+'"');var n=m.escape(this.text);return e?(t+=">",t+=n,t+=""):n}}class J{constructor(e,t){this.children=void 0,this.attributes=void 0,this.children=e||[],this.attributes=t||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);for(var r=0;r':''}}class ee{constructor(e){this.attributes=void 0,this.attributes=e||{}}toNode(){var e=document.createElementNS("http://www.w3.org/2000/svg","line");for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);return e}toMarkup(){var e="","\\gt",!0),ie(oe,le,be,"\u2208","\\in",!0),ie(oe,le,be,"\ue020","\\@not"),ie(oe,le,be,"\u2282","\\subset",!0),ie(oe,le,be,"\u2283","\\supset",!0),ie(oe,le,be,"\u2286","\\subseteq",!0),ie(oe,le,be,"\u2287","\\supseteq",!0),ie(oe,he,be,"\u2288","\\nsubseteq",!0),ie(oe,he,be,"\u2289","\\nsupseteq",!0),ie(oe,le,be,"\u22a8","\\models"),ie(oe,le,be,"\u2190","\\leftarrow",!0),ie(oe,le,be,"\u2264","\\le"),ie(oe,le,be,"\u2264","\\leq",!0),ie(oe,le,be,"<","\\lt",!0),ie(oe,le,be,"\u2192","\\rightarrow",!0),ie(oe,le,be,"\u2192","\\to"),ie(oe,he,be,"\u2271","\\ngeq",!0),ie(oe,he,be,"\u2270","\\nleq",!0),ie(oe,le,ye,"\xa0","\\ "),ie(oe,le,ye,"\xa0","\\space"),ie(oe,le,ye,"\xa0","\\nobreakspace"),ie(se,le,ye,"\xa0","\\ "),ie(se,le,ye,"\xa0"," "),ie(se,le,ye,"\xa0","\\space"),ie(se,le,ye,"\xa0","\\nobreakspace"),ie(oe,le,ye,null,"\\nobreak"),ie(oe,le,ye,null,"\\allowbreak"),ie(oe,le,ve,",",","),ie(oe,le,ve,";",";"),ie(oe,he,ce,"\u22bc","\\barwedge",!0),ie(oe,he,ce,"\u22bb","\\veebar",!0),ie(oe,le,ce,"\u2299","\\odot",!0),ie(oe,le,ce,"\u2295","\\oplus",!0),ie(oe,le,ce,"\u2297","\\otimes",!0),ie(oe,le,xe,"\u2202","\\partial",!0),ie(oe,le,ce,"\u2298","\\oslash",!0),ie(oe,he,ce,"\u229a","\\circledcirc",!0),ie(oe,he,ce,"\u22a1","\\boxdot",!0),ie(oe,le,ce,"\u25b3","\\bigtriangleup"),ie(oe,le,ce,"\u25bd","\\bigtriangledown"),ie(oe,le,ce,"\u2020","\\dagger"),ie(oe,le,ce,"\u22c4","\\diamond"),ie(oe,le,ce,"\u22c6","\\star"),ie(oe,le,ce,"\u25c3","\\triangleleft"),ie(oe,le,ce,"\u25b9","\\triangleright"),ie(oe,le,fe,"{","\\{"),ie(se,le,xe,"{","\\{"),ie(se,le,xe,"{","\\textbraceleft"),ie(oe,le,pe,"}","\\}"),ie(se,le,xe,"}","\\}"),ie(se,le,xe,"}","\\textbraceright"),ie(oe,le,fe,"{","\\lbrace"),ie(oe,le,pe,"}","\\rbrace"),ie(oe,le,fe,"[","\\lbrack",!0),ie(se,le,xe,"[","\\lbrack",!0),ie(oe,le,pe,"]","\\rbrack",!0),ie(se,le,xe,"]","\\rbrack",!0),ie(oe,le,fe,"(","\\lparen",!0),ie(oe,le,pe,")","\\rparen",!0),ie(se,le,xe,"<","\\textless",!0),ie(se,le,xe,">","\\textgreater",!0),ie(oe,le,fe,"\u230a","\\lfloor",!0),ie(oe,le,pe,"\u230b","\\rfloor",!0),ie(oe,le,fe,"\u2308","\\lceil",!0),ie(oe,le,pe,"\u2309","\\rceil",!0),ie(oe,le,xe,"\\","\\backslash"),ie(oe,le,xe,"\u2223","|"),ie(oe,le,xe,"\u2223","\\vert"),ie(se,le,xe,"|","\\textbar",!0),ie(oe,le,xe,"\u2225","\\|"),ie(oe,le,xe,"\u2225","\\Vert"),ie(se,le,xe,"\u2225","\\textbardbl"),ie(se,le,xe,"~","\\textasciitilde"),ie(se,le,xe,"\\","\\textbackslash"),ie(se,le,xe,"^","\\textasciicircum"),ie(oe,le,be,"\u2191","\\uparrow",!0),ie(oe,le,be,"\u21d1","\\Uparrow",!0),ie(oe,le,be,"\u2193","\\downarrow",!0),ie(oe,le,be,"\u21d3","\\Downarrow",!0),ie(oe,le,be,"\u2195","\\updownarrow",!0),ie(oe,le,be,"\u21d5","\\Updownarrow",!0),ie(oe,le,ge,"\u2210","\\coprod"),ie(oe,le,ge,"\u22c1","\\bigvee"),ie(oe,le,ge,"\u22c0","\\bigwedge"),ie(oe,le,ge,"\u2a04","\\biguplus"),ie(oe,le,ge,"\u22c2","\\bigcap"),ie(oe,le,ge,"\u22c3","\\bigcup"),ie(oe,le,ge,"\u222b","\\int"),ie(oe,le,ge,"\u222b","\\intop"),ie(oe,le,ge,"\u222c","\\iint"),ie(oe,le,ge,"\u222d","\\iiint"),ie(oe,le,ge,"\u220f","\\prod"),ie(oe,le,ge,"\u2211","\\sum"),ie(oe,le,ge,"\u2a02","\\bigotimes"),ie(oe,le,ge,"\u2a01","\\bigoplus"),ie(oe,le,ge,"\u2a00","\\bigodot"),ie(oe,le,ge,"\u222e","\\oint"),ie(oe,le,ge,"\u222f","\\oiint"),ie(oe,le,ge,"\u2230","\\oiiint"),ie(oe,le,ge,"\u2a06","\\bigsqcup"),ie(oe,le,ge,"\u222b","\\smallint"),ie(se,le,ue,"\u2026","\\textellipsis"),ie(oe,le,ue,"\u2026","\\mathellipsis"),ie(se,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u2026","\\ldots",!0),ie(oe,le,ue,"\u22ef","\\@cdots",!0),ie(oe,le,ue,"\u22f1","\\ddots",!0),ie(oe,le,xe,"\u22ee","\\varvdots"),ie(oe,le,me,"\u02ca","\\acute"),ie(oe,le,me,"\u02cb","\\grave"),ie(oe,le,me,"\xa8","\\ddot"),ie(oe,le,me,"~","\\tilde"),ie(oe,le,me,"\u02c9","\\bar"),ie(oe,le,me,"\u02d8","\\breve"),ie(oe,le,me,"\u02c7","\\check"),ie(oe,le,me,"^","\\hat"),ie(oe,le,me,"\u20d7","\\vec"),ie(oe,le,me,"\u02d9","\\dot"),ie(oe,le,me,"\u02da","\\mathring"),ie(oe,le,de,"\ue131","\\@imath"),ie(oe,le,de,"\ue237","\\@jmath"),ie(oe,le,xe,"\u0131","\u0131"),ie(oe,le,xe,"\u0237","\u0237"),ie(se,le,xe,"\u0131","\\i",!0),ie(se,le,xe,"\u0237","\\j",!0),ie(se,le,xe,"\xdf","\\ss",!0),ie(se,le,xe,"\xe6","\\ae",!0),ie(se,le,xe,"\u0153","\\oe",!0),ie(se,le,xe,"\xf8","\\o",!0),ie(se,le,xe,"\xc6","\\AE",!0),ie(se,le,xe,"\u0152","\\OE",!0),ie(se,le,xe,"\xd8","\\O",!0),ie(se,le,me,"\u02ca","\\'"),ie(se,le,me,"\u02cb","\\`"),ie(se,le,me,"\u02c6","\\^"),ie(se,le,me,"\u02dc","\\~"),ie(se,le,me,"\u02c9","\\="),ie(se,le,me,"\u02d8","\\u"),ie(se,le,me,"\u02d9","\\."),ie(se,le,me,"\xb8","\\c"),ie(se,le,me,"\u02da","\\r"),ie(se,le,me,"\u02c7","\\v"),ie(se,le,me,"\xa8",'\\"'),ie(se,le,me,"\u02dd","\\H"),ie(se,le,me,"\u25ef","\\textcircled");var we={"--":!0,"---":!0,"``":!0,"''":!0};ie(se,le,xe,"\u2013","--",!0),ie(se,le,xe,"\u2013","\\textendash"),ie(se,le,xe,"\u2014","---",!0),ie(se,le,xe,"\u2014","\\textemdash"),ie(se,le,xe,"\u2018","`",!0),ie(se,le,xe,"\u2018","\\textquoteleft"),ie(se,le,xe,"\u2019","'",!0),ie(se,le,xe,"\u2019","\\textquoteright"),ie(se,le,xe,"\u201c","``",!0),ie(se,le,xe,"\u201c","\\textquotedblleft"),ie(se,le,xe,"\u201d","''",!0),ie(se,le,xe,"\u201d","\\textquotedblright"),ie(oe,le,xe,"\xb0","\\degree",!0),ie(se,le,xe,"\xb0","\\degree"),ie(se,le,xe,"\xb0","\\textdegree",!0),ie(oe,le,xe,"\xa3","\\pounds"),ie(oe,le,xe,"\xa3","\\mathsterling",!0),ie(se,le,xe,"\xa3","\\pounds"),ie(se,le,xe,"\xa3","\\textsterling",!0),ie(oe,he,xe,"\u2720","\\maltese"),ie(se,he,xe,"\u2720","\\maltese");for(var ke='0123456789/@."',Se=0;Se<14;Se++){var Me=ke.charAt(Se);ie(oe,le,xe,Me,Me)}for(var ze='0123456789!@*()-=+";:?/.,',Ae=0;Ae<25;Ae++){var Te=ze.charAt(Ae);ie(se,le,xe,Te,Te)}for(var Be="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",Ce=0;Ce<52;Ce++){var Ne=Be.charAt(Ce);ie(oe,le,de,Ne,Ne),ie(se,le,xe,Ne,Ne)}ie(oe,he,xe,"C","\u2102"),ie(se,he,xe,"C","\u2102"),ie(oe,he,xe,"H","\u210d"),ie(se,he,xe,"H","\u210d"),ie(oe,he,xe,"N","\u2115"),ie(se,he,xe,"N","\u2115"),ie(oe,he,xe,"P","\u2119"),ie(se,he,xe,"P","\u2119"),ie(oe,he,xe,"Q","\u211a"),ie(se,he,xe,"Q","\u211a"),ie(oe,he,xe,"R","\u211d"),ie(se,he,xe,"R","\u211d"),ie(oe,he,xe,"Z","\u2124"),ie(se,he,xe,"Z","\u2124"),ie(oe,le,de,"h","\u210e"),ie(se,le,de,"h","\u210e");for(var qe="",Ie=0;Ie<52;Ie++){var Re=Be.charAt(Ie);ie(oe,le,de,Re,qe=String.fromCharCode(55349,56320+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56372+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56424+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56580+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56684+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56736+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56788+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56840+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56944+Ie)),ie(se,le,xe,Re,qe),Ie<26&&(ie(oe,le,de,Re,qe=String.fromCharCode(55349,56632+Ie)),ie(se,le,xe,Re,qe),ie(oe,le,de,Re,qe=String.fromCharCode(55349,56476+Ie)),ie(se,le,xe,Re,qe))}ie(oe,le,de,"k",qe=String.fromCharCode(55349,56668)),ie(se,le,xe,"k",qe);for(var He=0;He<10;He++){var Oe=He.toString();ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57294+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57314+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57324+He)),ie(se,le,xe,Oe,qe),ie(oe,le,de,Oe,qe=String.fromCharCode(55349,57334+He)),ie(se,le,xe,Oe,qe)}for(var Ee="\xd0\xde\xfe",Le=0;Le<3;Le++){var De=Ee.charAt(Le);ie(oe,le,de,De,De),ie(se,le,xe,De,De)}var Ve=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathboldfrak","textboldfrak","Fraktur-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],Pe=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],Fe=function(e,t,r){return ne[r][e]&&ne[r][e].replace&&(e=ne[r][e].replace),{value:e,metrics:I(e,t,r)}},Ge=function(e,t,r,a,n){var i,o=Fe(e,t,r),s=o.metrics;if(e=o.value,s){var l=s.italic;("text"===r||a&&"mathit"===a.font)&&(l=0),i=new K(e,s.height,s.depth,l,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+e+"' in style '"+t+"' and mode '"+r+"'"),i=new K(e,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var h=a.getColor();h&&(i.style.color=h)}return i},Ue=(e,t)=>{if(U(e.classes)!==U(t.classes)||e.skew!==t.skew||e.maxFontSize!==t.maxFontSize)return!1;if(1===e.classes.length){var r=e.classes[0];if("mbin"===r||"mord"===r)return!1}for(var a in e.style)if(e.style.hasOwnProperty(a)&&e.style[a]!==t.style[a])return!1;for(var n in t.style)if(t.style.hasOwnProperty(n)&&e.style[n]!==t.style[n])return!1;return!0},Ye=function(e){for(var t=0,r=0,a=0,n=0;nt&&(t=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}e.height=t,e.depth=r,e.maxFontSize=a},Xe=function(e,t,r,a){var n=new _(e,t,r,a);return Ye(n),n},We=(e,t,r,a)=>new _(e,t,r,a),_e=function(e){var t=new B(e);return Ye(t),t},je=function(e,t,r){var a="";switch(e){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=e}return a+"-"+("textbf"===t&&"textit"===r?"BoldItalic":"textbf"===t?"Bold":"textit"===t?"Italic":"Regular")},$e={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Ze={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659]},Ke={fontMap:$e,makeSymbol:Ge,mathsym:function(e,t,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Fe(e,"Main-Bold",t).metrics?Ge(e,"Main-Bold",t,r,a.concat(["mathbf"])):"\\"===e||"main"===ne[t][e].font?Ge(e,"Main-Regular",t,r,a):Ge(e,"AMS-Regular",t,r,a.concat(["amsrm"]))},makeSpan:Xe,makeSvgSpan:We,makeLineSpan:function(e,t,r){var a=Xe([e],[],t);return a.height=Math.max(r||t.fontMetrics().defaultRuleThickness,t.minRuleThickness),a.style.borderBottomWidth=G(a.height),a.maxFontSize=1,a},makeAnchor:function(e,t,r,a){var n=new j(e,t,r,a);return Ye(n),n},makeFragment:_e,wrapFragment:function(e,t){return e instanceof B?Xe([],[e],t):e},makeVList:function(e,t){for(var{children:r,depth:a}=function(e){if("individualShift"===e.positionType){for(var t=e.children,r=[t[0]],a=-t[0].shift-t[0].elem.depth,n=a,i=1;i0)return Ge(n,h,a,t,o.concat(m));if(l){var c,p;if("boldsymbol"===l){var u=function(e,t,r,a,n){return"textord"!==n&&Fe(e,"Math-BoldItalic",t).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(n,a,0,0,r);c=u.fontName,p=[u.fontClass]}else s?(c=$e[l].fontName,p=[l]):(c=je(l,t.fontWeight,t.fontShape),p=[l,t.fontWeight,t.fontShape]);if(Fe(n,c,a).metrics)return Ge(n,c,a,t,o.concat(p));if(we.hasOwnProperty(n)&&"Typewriter"===c.slice(0,10)){for(var d=[],g=0;g{var r=Xe(["mspace"],[],t),a=F(e,t);return r.style.marginRight=G(a),r},staticSvg:function(e,t){var[r,a,n]=Ze[e],i=new Q(r),o=new J([i],{width:G(a),height:G(n),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+1e3*n,preserveAspectRatio:"xMinYMin"}),s=We(["overlay"],[o],t);return s.height=n,s.style.height=G(n),s.style.width=G(a),s},svgData:Ze,tryCombineChars:e=>{for(var t=0;t{var r=t.classes[0],a=e.classes[0];"mbin"===r&&m.contains(pt,a)?t.classes[0]="mord":"mbin"===a&&m.contains(ct,r)&&(e.classes[0]="mord")}),{node:c},p,u),ft(n,((e,t)=>{var r=yt(t),a=yt(e),n=r&&a?e.hasClass("mtight")?rt[r][a]:tt[r][a]:null;if(n)return Ke.makeGlue(n,l)}),{node:c},p,u),n},ft=function e(t,r,a,n,i){n&&t.push(n);for(var o=0;or=>{t.splice(e+1,0,r),o++})(o)}}n&&t.pop()},vt=function(e){return e instanceof B||e instanceof j||e instanceof _&&e.hasClass("enclosing")?e:null},bt=function e(t,r){var a=vt(t);if(a){var n=a.children;if(n.length){if("right"===r)return e(n[n.length-1],"right");if("left"===r)return e(n[0],"left")}}return t},yt=function(e,t){return e?(t&&(e=bt(e,t)),dt[e.classes[0]]||null):null},xt=function(e,t){var r=["nulldelimiter"].concat(e.baseSizingClasses());return mt(t.concat(r))},wt=function(e,t,r){if(!e)return mt();if(nt[e.type]){var a=nt[e.type](e,t);if(r&&t.size!==r.size){a=mt(t.sizingClasses(r),[a],t);var n=t.sizeMultiplier/r.sizeMultiplier;a.height*=n,a.depth*=n}return a}throw new i("Got group of unknown type: '"+e.type+"'")};function kt(e,t){var r=mt(["base"],e,t),a=mt(["strut"]);return a.style.height=G(r.height+r.depth),r.depth&&(a.style.verticalAlign=G(-r.depth)),r.children.unshift(a),r}function St(e,t){var r=null;1===e.length&&"tag"===e[0].type&&(r=e[0].tag,e=e[0].body);var a,n=gt(e,t,"root");2===n.length&&n[1].hasClass("tag")&&(a=n.pop());for(var i,o=[],s=[],l=0;l0&&(o.push(kt(s,t)),s=[]),o.push(n[l]));s.length>0&&o.push(kt(s,t)),r?((i=kt(gt(r,t,!0))).classes=["tag"],o.push(i)):a&&o.push(a);var m=mt(["katex-html"],o);if(m.setAttribute("aria-hidden","true"),i){var c=i.children[0];c.style.height=G(m.height+m.depth),m.depth&&(c.style.verticalAlign=G(-m.depth))}return m}function Mt(e){return new B(e)}class zt{constructor(e,t,r){this.type=void 0,this.attributes=void 0,this.children=void 0,this.classes=void 0,this.type=e,this.attributes={},this.children=t||[],this.classes=r||[]}setAttribute(e,t){this.attributes[e]=t}getAttribute(e){return this.attributes[e]}toNode(){var e=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var t in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,t)&&e.setAttribute(t,this.attributes[t]);this.classes.length>0&&(e.className=U(this.classes));for(var r=0;r0&&(e+=' class ="'+m.escape(U(this.classes))+'"'),e+=">";for(var r=0;r"}toText(){return this.children.map((e=>e.toText())).join("")}}class At{constructor(e){this.text=void 0,this.text=e}toNode(){return document.createTextNode(this.text)}toMarkup(){return m.escape(this.toText())}toText(){return this.text}}var Tt={MathNode:zt,TextNode:At,SpaceNode:class{constructor(e){this.width=void 0,this.character=void 0,this.width=e,this.character=e>=.05555&&e<=.05556?"\u200a":e>=.1666&&e<=.1667?"\u2009":e>=.2222&&e<=.2223?"\u2005":e>=.2777&&e<=.2778?"\u2005\u200a":e>=-.05556&&e<=-.05555?"\u200a\u2063":e>=-.1667&&e<=-.1666?"\u2009\u2063":e>=-.2223&&e<=-.2222?"\u205f\u2063":e>=-.2778&&e<=-.2777?"\u2005\u2063":null}toNode(){if(this.character)return document.createTextNode(this.character);var e=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return e.setAttribute("width",G(this.width)),e}toMarkup(){return this.character?""+this.character+"":''}toText(){return this.character?this.character:" "}},newDocumentFragment:Mt},Bt=function(e,t,r){return!ne[t][e]||!ne[t][e].replace||55349===e.charCodeAt(0)||we.hasOwnProperty(e)&&r&&(r.fontFamily&&"tt"===r.fontFamily.slice(4,6)||r.font&&"tt"===r.font.slice(4,6))||(e=ne[t][e].replace),new Tt.TextNode(e)},Ct=function(e){return 1===e.length?e[0]:new Tt.MathNode("mrow",e)},Nt=function(e,t){if("texttt"===t.fontFamily)return"monospace";if("textsf"===t.fontFamily)return"textit"===t.fontShape&&"textbf"===t.fontWeight?"sans-serif-bold-italic":"textit"===t.fontShape?"sans-serif-italic":"textbf"===t.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===t.fontShape&&"textbf"===t.fontWeight)return"bold-italic";if("textit"===t.fontShape)return"italic";if("textbf"===t.fontWeight)return"bold";var r=t.font;if(!r||"mathnormal"===r)return null;var a=e.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===e.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=e.text;return m.contains(["\\imath","\\jmath"],n)?null:(ne[a][n]&&ne[a][n].replace&&(n=ne[a][n].replace),I(n,Ke.fontMap[r].fontName,a)?Ke.fontMap[r].variant:null)},qt=function(e,t,r){if(1===e.length){var a=Rt(e[0],t);return r&&a instanceof zt&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o0&&(m.text=m.text.slice(0,1)+"\u0338"+m.text.slice(1),i.pop())}}}i.push(s),n=s}return i},It=function(e,t,r){return Ct(qt(e,t,r))},Rt=function(e,t){if(!e)return new Tt.MathNode("mrow");if(it[e.type])return it[e.type](e,t);throw new i("Got group of unknown type: '"+e.type+"'")};function Ht(e,t,r,a,n){var i,o=qt(e,r);i=1===o.length&&o[0]instanceof zt&&m.contains(["mrow","mtable"],o[0].type)?o[0]:new Tt.MathNode("mrow",o);var s=new Tt.MathNode("annotation",[new Tt.TextNode(t)]);s.setAttribute("encoding","application/x-tex");var l=new Tt.MathNode("semantics",[i,s]),h=new Tt.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),a&&h.setAttribute("display","block");var c=n?"katex":"katex-mathml";return Ke.makeSpan([c],[h])}var Ot=function(e){return new L({style:e.displayMode?k.DISPLAY:k.TEXT,maxSize:e.maxSize,minRuleThickness:e.minRuleThickness})},Et=function(e,t){if(t.displayMode){var r=["katex-display"];t.leqno&&r.push("leqno"),t.fleqn&&r.push("fleqn"),e=Ke.makeSpan(r,[e])}return e},Lt={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb","\\cdrightarrow":"\u2192","\\cdleftarrow":"\u2190","\\cdlongequal":"="},Dt={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],"\\cdrightarrow":[["rightarrow"],3,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],"\\cdleftarrow":[["leftarrow"],3,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],"\\cdlongequal":[["longequal"],3,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},Vt=function(e,t,r,a,n){var i,o=e.height+e.depth+r+a;if(/fbox|color|angl/.test(t)){if(i=Ke.makeSpan(["stretchy",t],[],n),"fbox"===t){var s=n.color&&n.getColor();s&&(i.style.borderColor=s)}}else{var l=[];/^[bx]cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(t)&&l.push(new ee({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var h=new J(l,{width:"100%",height:G(o)});i=Ke.makeSvgSpan([],[h],n)}return i.height=o,i.style.height=G(o),i},Pt=function(e){var t=new Tt.MathNode("mo",[new Tt.TextNode(Lt[e.replace(/^\\/,"")])]);return t.setAttribute("stretchy","true"),t},Ft=function(e,t){var{span:r,minWidth:a,height:n}=function(){var r=4e5,a=e.label.slice(1);if(m.contains(["widehat","widecheck","widetilde","utilde"],a)){var n,i,o,s="ordgroup"===(d=e.base).type?d.body.length:1;if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var l=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][l],n=[0,239,300,360,420][l],o=[0,.24,.3,.3,.36,.42][l],i=a+l):(r=[0,600,1033,2339,2340][l],n=[0,260,286,306,312][l],o=[0,.26,.286,.3,.306,.34][l],i="tilde"+l)}var h=new Q(i),c=new J([h],{width:"100%",height:G(o),viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Ke.makeSvgSpan([],[c],t),minWidth:0,height:o}}var p,u,d,g=[],f=Dt[a],[v,b,y]=f,x=y/1e3,w=v.length;if(1===w)p=["hide-tail"],u=[f[3]];else if(2===w)p=["halfarrow-left","halfarrow-right"],u=["xMinYMin","xMaxYMin"];else{if(3!==w)throw new Error("Correct katexImagesData or update code here to support\n "+w+" children.");p=["brace-left","brace-center","brace-right"],u=["xMinYMin","xMidYMin","xMaxYMin"]}for(var k=0;k0&&(r.style.minWidth=G(a)),r};function Gt(e,t){if(!e||e.type!==t)throw new Error("Expected node of type "+t+", but got "+(e?"node of type "+e.type:String(e)));return e}function Ut(e){var t=Yt(e);if(!t)throw new Error("Expected node of symbol group type, but got "+(e?"node of type "+e.type:String(e)));return t}function Yt(e){return e&&("atom"===e.type||ae.hasOwnProperty(e.type))?e:null}var Xt=(e,t)=>{var r,a,n;e&&"supsub"===e.type?(r=(a=Gt(e.base,"accent")).base,e.base=r,n=function(e){if(e instanceof _)return e;throw new Error("Expected span but got "+String(e)+".")}(wt(e,t)),e.base=a):r=(a=Gt(e,"accent")).base;var i=wt(r,t.havingCrampedStyle()),o=0;if(a.isShifty&&m.isCharacterBox(r)){var s=m.getBaseElem(r);o=te(wt(s,t.havingCrampedStyle())).skew}var l,h="\\c"===a.label,c=h?i.height+i.depth:Math.min(i.height,t.fontMetrics().xHeight);if(a.isStretchy)l=Ft(a,t),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+G(2*o)+")",marginLeft:G(2*o)}:void 0}]},t);else{var p,u;"\\vec"===a.label?(p=Ke.staticSvg("vec",t),u=Ke.svgData.vec[1]):((p=te(p=Ke.makeOrd({mode:a.mode,text:a.label},t,"textord"))).italic=0,u=p.width,h&&(c+=p.depth)),l=Ke.makeSpan(["accent-body"],[p]);var d="\\textcircled"===a.label;d&&(l.classes.push("accent-full"),c=i.height);var g=o;d||(g-=u/2),l.style.left=G(g),"\\textcircled"===a.label&&(l.style.top=".2em"),l=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-c},{type:"elem",elem:l}]},t)}var f=Ke.makeSpan(["mord","accent"],[l],t);return n?(n.children[0]=f,n.height=Math.max(f.height,n.height),n.classes[0]="mord",n):f},Wt=(e,t)=>{var r=e.isStretchy?Pt(e.label):new Tt.MathNode("mo",[Bt(e.label,e.mode)]),a=new Tt.MathNode("mover",[Rt(e.base,t),r]);return a.setAttribute("accent","true"),a},_t=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map((e=>"\\"+e)).join("|"));ot({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:(e,t)=>{var r=lt(t[0]),a=!_t.test(e.funcName),n=!a||"\\widehat"===e.funcName||"\\widetilde"===e.funcName||"\\widecheck"===e.funcName;return{type:"accent",mode:e.parser.mode,label:e.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\c","\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!0,argTypes:["primitive"]},handler:(e,t)=>{var r=t[0],a=e.parser.mode;return"math"===a&&(e.parser.settings.reportNonstrict("mathVsTextAccents","LaTeX's accent "+e.funcName+" works only in text mode"),a="text"),{type:"accent",mode:a,label:e.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Xt,mathmlBuilder:Wt}),ot({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:(e,t)=>{var r=wt(e.base,t),a=Ft(e,t),n="\\utilde"===e.label?.12:0,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","accentunder"],[i],t)},mathmlBuilder:(e,t)=>{var r=Pt(e.label),a=new Tt.MathNode("munder",[Rt(e.base,t),r]);return a.setAttribute("accentunder","true"),a}});var jt=e=>{var t=new Tt.MathNode("mpadded",e?[e]:[]);return t.setAttribute("width","+0.6em"),t.setAttribute("lspace","0.3em"),t};ot({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium","\\\\cdrightarrow","\\\\cdleftarrow","\\\\cdlongequal"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a,funcName:n}=e;return{type:"xArrow",mode:a.mode,label:n,body:t[0],below:r[0]}},htmlBuilder(e,t){var r,a=t.style,n=t.havingStyle(a.sup()),i=Ke.wrapFragment(wt(e.body,n,t),t),o="\\x"===e.label.slice(0,2)?"x":"cd";i.classes.push(o+"-arrow-pad"),e.below&&(n=t.havingStyle(a.sub()),(r=Ke.wrapFragment(wt(e.below,n,t),t)).classes.push(o+"-arrow-pad"));var s,l=Ft(e,t),h=-t.fontMetrics().axisHeight+.5*l.height,m=-t.fontMetrics().axisHeight-.5*l.height-.111;if((i.depth>.25||"\\xleftequilibrium"===e.label)&&(m-=i.depth),r){var c=-t.fontMetrics().axisHeight+r.height+.5*l.height+.111;s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h},{type:"elem",elem:r,shift:c}]},t)}else s=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:m},{type:"elem",elem:l,shift:h}]},t);return s.children[0].children[0].children[1].classes.push("svg-align"),Ke.makeSpan(["mrel","x-arrow"],[s],t)},mathmlBuilder(e,t){var r,a=Pt(e.label);if(a.setAttribute("minsize","x"===e.label.charAt(0)?"1.75em":"3.0em"),e.body){var n=jt(Rt(e.body,t));if(e.below){var i=jt(Rt(e.below,t));r=new Tt.MathNode("munderover",[a,i,n])}else r=new Tt.MathNode("mover",[a,n])}else if(e.below){var o=jt(Rt(e.below,t));r=new Tt.MathNode("munder",[a,o])}else r=jt(),r=new Tt.MathNode("mover",[a,r]);return r}});var $t=Ke.makeSpan;function Zt(e,t){var r=gt(e.body,t,!0);return $t([e.mclass],r,t)}function Kt(e,t){var r,a=qt(e.body,t);return"minner"===e.mclass?r=new Tt.MathNode("mpadded",a):"mord"===e.mclass?e.isCharacterBox?(r=a[0]).type="mi":r=new Tt.MathNode("mi",a):(e.isCharacterBox?(r=a[0]).type="mo":r=new Tt.MathNode("mo",a),"mbin"===e.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"===e.mclass||"mclose"===e.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0em"):"minner"===e.mclass&&(r.attributes.lspace="0.0556em",r.attributes.width="+0.1111em")),r}ot({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1,primitive:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"mclass",mode:r.mode,mclass:"m"+a.slice(5),body:ht(n),isCharacterBox:m.isCharacterBox(n)}},htmlBuilder:Zt,mathmlBuilder:Kt});var Jt=e=>{var t="ordgroup"===e.type&&e.body.length?e.body[0]:e;return"atom"!==t.type||"bin"!==t.family&&"rel"!==t.family?"mord":"m"+t.family};ot({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler(e,t){var{parser:r}=e;return{type:"mclass",mode:r.mode,mclass:Jt(t[0]),body:ht(t[1]),isCharacterBox:m.isCharacterBox(t[1])}}}),ot({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler(e,t){var r,{parser:a,funcName:n}=e,i=t[1],o=t[0];r="\\stackrel"!==n?Jt(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:ht(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===n?null:o,sub:"\\underset"===n?o:null};return{type:"mclass",mode:a.mode,mclass:r,body:[l],isCharacterBox:m.isCharacterBox(l)}},htmlBuilder:Zt,mathmlBuilder:Kt}),ot({type:"pmb",names:["\\pmb"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"pmb",mode:r.mode,mclass:Jt(t[0]),body:ht(t[0])}},htmlBuilder(e,t){var r=gt(e.body,t,!0),a=Ke.makeSpan([e.mclass],r,t);return a.style.textShadow="0.02em 0.01em 0.04px",a},mathmlBuilder(e,t){var r=qt(e.body,t),a=new Tt.MathNode("mstyle",r);return a.setAttribute("style","text-shadow: 0.02em 0.01em 0.04px"),a}});var Qt={">":"\\\\cdrightarrow","<":"\\\\cdleftarrow","=":"\\\\cdlongequal",A:"\\uparrow",V:"\\downarrow","|":"\\Vert",".":"no arrow"},er=e=>"textord"===e.type&&"@"===e.text;function tr(e,t,r){var a=Qt[e];switch(a){case"\\\\cdrightarrow":case"\\\\cdleftarrow":return r.callFunction(a,[t[0]],[t[1]]);case"\\uparrow":case"\\downarrow":var n={type:"atom",text:a,mode:"math",family:"rel"},i={type:"ordgroup",mode:"math",body:[r.callFunction("\\\\cdleft",[t[0]],[]),r.callFunction("\\Big",[n],[]),r.callFunction("\\\\cdright",[t[1]],[])]};return r.callFunction("\\\\cdparent",[i],[]);case"\\\\cdlongequal":return r.callFunction("\\\\cdlongequal",[],[]);case"\\Vert":return r.callFunction("\\Big",[{type:"textord",text:"\\Vert",mode:"math"}],[]);default:return{type:"textord",text:" ",mode:"math"}}}ot({type:"cdlabel",names:["\\\\cdleft","\\\\cdright"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"cdlabel",mode:r.mode,side:a.slice(4),label:t[0]}},htmlBuilder(e,t){var r=t.havingStyle(t.style.sup()),a=Ke.wrapFragment(wt(e.label,r,t),t);return a.classes.push("cd-label-"+e.side),a.style.bottom=G(.8-a.depth),a.height=0,a.depth=0,a},mathmlBuilder(e,t){var r=new Tt.MathNode("mrow",[Rt(e.label,t)]);return(r=new Tt.MathNode("mpadded",[r])).setAttribute("width","0"),"left"===e.side&&r.setAttribute("lspace","-1width"),r.setAttribute("voffset","0.7em"),(r=new Tt.MathNode("mstyle",[r])).setAttribute("displaystyle","false"),r.setAttribute("scriptlevel","1"),r}}),ot({type:"cdlabelparent",names:["\\\\cdparent"],props:{numArgs:1},handler(e,t){var{parser:r}=e;return{type:"cdlabelparent",mode:r.mode,fragment:t[0]}},htmlBuilder(e,t){var r=Ke.wrapFragment(wt(e.fragment,t),t);return r.classes.push("cd-vert-arrow"),r},mathmlBuilder:(e,t)=>new Tt.MathNode("mrow",[Rt(e.fragment,t)])}),ot({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler(e,t){for(var{parser:r}=e,a=Gt(t[0],"ordgroup").body,n="",o=0;o=1114111)throw new i("\\@char with invalid code point "+n);return l<=65535?s=String.fromCharCode(l):(l-=65536,s=String.fromCharCode(55296+(l>>10),56320+(1023&l))),{type:"textord",mode:r.mode,text:s}}});var rr=(e,t)=>{var r=gt(e.body,t.withColor(e.color),!1);return Ke.makeFragment(r)},ar=(e,t)=>{var r=qt(e.body,t.withColor(e.color)),a=new Tt.MathNode("mstyle",r);return a.setAttribute("mathcolor",e.color),a};ot({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,argTypes:["color","original"]},handler(e,t){var{parser:r}=e,a=Gt(t[0],"color-token").color,n=t[1];return{type:"color",mode:r.mode,color:a,body:ht(n)}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,argTypes:["color"]},handler(e,t){var{parser:r,breakOnTokenText:a}=e,n=Gt(t[0],"color-token").color;r.gullet.macros.set("\\current@color",n);var i=r.parseExpression(!0,a);return{type:"color",mode:r.mode,color:n,body:i}},htmlBuilder:rr,mathmlBuilder:ar}),ot({type:"cr",names:["\\\\"],props:{numArgs:0,numOptionalArgs:0,allowedInText:!0},handler(e,t,r){var{parser:a}=e,n="["===a.gullet.future().text?a.parseSizeGroup(!0):null,i=!a.settings.displayMode||!a.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode");return{type:"cr",mode:a.mode,newLine:i,size:n&&Gt(n,"size").value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mspace"],[],t);return e.newLine&&(r.classes.push("newline"),e.size&&(r.style.marginTop=G(F(e.size,t)))),r},mathmlBuilder(e,t){var r=new Tt.MathNode("mspace");return e.newLine&&(r.setAttribute("linebreak","newline"),e.size&&r.setAttribute("height",G(F(e.size,t)))),r}});var nr={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},ir=e=>{var t=e.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(t))throw new i("Expected a control sequence",e);return t},or=(e,t,r,a)=>{var n=e.gullet.macros.get(r.text);null==n&&(r.noexpand=!0,n={tokens:[r],numArgs:0,unexpandable:!e.gullet.isExpandable(r.text)}),e.gullet.macros.set(t,n,a)};ot({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t,funcName:r}=e;t.consumeSpaces();var a=t.fetch();if(nr[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=nr[a.text]),Gt(t.parseFunction(),"internal");throw new i("Invalid token after macro prefix",a)}}),ot({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=t.gullet.popToken(),n=a.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(n))throw new i("Expected a control sequence",a);for(var o,s=0,l=[[]];"{"!==t.gullet.future().text;)if("#"===(a=t.gullet.popToken()).text){if("{"===t.gullet.future().text){o=t.gullet.future(),l[s].push("{");break}if(a=t.gullet.popToken(),!/^[1-9]$/.test(a.text))throw new i('Invalid argument number "'+a.text+'"');if(parseInt(a.text)!==s+1)throw new i('Argument number "'+a.text+'" out of order');s++,l.push([])}else{if("EOF"===a.text)throw new i("Expected a macro definition");l[s].push(a.text)}var{tokens:h}=t.gullet.consumeArg();return o&&h.unshift(o),"\\edef"!==r&&"\\xdef"!==r||(h=t.gullet.expandTokens(h)).reverse(),t.gullet.macros.set(n,{tokens:h,numArgs:s,delimiters:l},r===nr[r]),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken());t.gullet.consumeSpaces();var n=(e=>{var t=e.gullet.popToken();return"="===t.text&&" "===(t=e.gullet.popToken()).text&&(t=e.gullet.popToken()),t})(t);return or(t,a,n,"\\\\globallet"===r),{type:"internal",mode:t.mode}}}),ot({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e){var{parser:t,funcName:r}=e,a=ir(t.gullet.popToken()),n=t.gullet.popToken(),i=t.gullet.popToken();return or(t,a,i,"\\\\globalfuture"===r),t.gullet.pushToken(i),t.gullet.pushToken(n),{type:"internal",mode:t.mode}}});var sr=function(e,t,r){var a=I(ne.math[e]&&ne.math[e].replace||e,t,r);if(!a)throw new Error("Unsupported symbol "+e+" and font size "+t+".");return a},lr=function(e,t,r,a){var n=r.havingBaseStyle(t),i=Ke.makeSpan(a.concat(n.sizingClasses(r)),[e],r),o=n.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=n.sizeMultiplier,i},hr=function(e,t,r){var a=t.havingBaseStyle(r),n=(1-t.sizeMultiplier/a.sizeMultiplier)*t.fontMetrics().axisHeight;e.classes.push("delimcenter"),e.style.top=G(n),e.height-=n,e.depth+=n},mr=function(e,t,r,a,n,i){var o=function(e,t,r,a){return Ke.makeSymbol(e,"Size"+t+"-Regular",r,a)}(e,t,n,a),s=lr(Ke.makeSpan(["delimsizing","size"+t],[o],a),k.TEXT,a,i);return r&&hr(s,a,k.TEXT),s},cr=function(e,t,r){var a;return a="Size1-Regular"===t?"delim-size1":"delim-size4",{type:"elem",elem:Ke.makeSpan(["delimsizinginner",a],[Ke.makeSpan([],[Ke.makeSymbol(e,t,r)])])}},pr=function(e,t,r){var a=C["Size4-Regular"][e.charCodeAt(0)]?C["Size4-Regular"][e.charCodeAt(0)][4]:C["Size1-Regular"][e.charCodeAt(0)][4],n=new Q("inner",function(e,t){switch(e){case"\u239c":return"M291 0 H417 V"+t+" H291z M291 0 H417 V"+t+" H291z";case"\u2223":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145z";case"\u2225":return"M145 0 H188 V"+t+" H145z M145 0 H188 V"+t+" H145zM367 0 H410 V"+t+" H367z M367 0 H410 V"+t+" H367z";case"\u239f":return"M457 0 H583 V"+t+" H457z M457 0 H583 V"+t+" H457z";case"\u23a2":return"M319 0 H403 V"+t+" H319z M319 0 H403 V"+t+" H319z";case"\u23a5":return"M263 0 H347 V"+t+" H263z M263 0 H347 V"+t+" H263z";case"\u23aa":return"M384 0 H504 V"+t+" H384z M384 0 H504 V"+t+" H384z";case"\u23d0":return"M312 0 H355 V"+t+" H312z M312 0 H355 V"+t+" H312z";case"\u2016":return"M257 0 H300 V"+t+" H257z M257 0 H300 V"+t+" H257zM478 0 H521 V"+t+" H478z M478 0 H521 V"+t+" H478z";default:return""}}(e,Math.round(1e3*t))),i=new J([n],{width:G(a),height:G(t),style:"width:"+G(a),viewBox:"0 0 "+1e3*a+" "+Math.round(1e3*t),preserveAspectRatio:"xMinYMin"}),o=Ke.makeSvgSpan([],[i],r);return o.height=t,o.style.height=G(t),o.style.width=G(a),{type:"elem",elem:o}},ur={type:"kern",size:-.008},dr=["|","\\lvert","\\rvert","\\vert"],gr=["\\|","\\lVert","\\rVert","\\Vert"],fr=function(e,t,r,a,n,i){var o,s,l,h,c="",p=0;o=l=h=e,s=null;var u="Size1-Regular";"\\uparrow"===e?l=h="\u23d0":"\\Uparrow"===e?l=h="\u2016":"\\downarrow"===e?o=l="\u23d0":"\\Downarrow"===e?o=l="\u2016":"\\updownarrow"===e?(o="\\uparrow",l="\u23d0",h="\\downarrow"):"\\Updownarrow"===e?(o="\\Uparrow",l="\u2016",h="\\Downarrow"):m.contains(dr,e)?(l="\u2223",c="vert",p=333):m.contains(gr,e)?(l="\u2225",c="doublevert",p=556):"["===e||"\\lbrack"===e?(o="\u23a1",l="\u23a2",h="\u23a3",u="Size4-Regular",c="lbrack",p=667):"]"===e||"\\rbrack"===e?(o="\u23a4",l="\u23a5",h="\u23a6",u="Size4-Regular",c="rbrack",p=667):"\\lfloor"===e||"\u230a"===e?(l=o="\u23a2",h="\u23a3",u="Size4-Regular",c="lfloor",p=667):"\\lceil"===e||"\u2308"===e?(o="\u23a1",l=h="\u23a2",u="Size4-Regular",c="lceil",p=667):"\\rfloor"===e||"\u230b"===e?(l=o="\u23a5",h="\u23a6",u="Size4-Regular",c="rfloor",p=667):"\\rceil"===e||"\u2309"===e?(o="\u23a4",l=h="\u23a5",u="Size4-Regular",c="rceil",p=667):"("===e||"\\lparen"===e?(o="\u239b",l="\u239c",h="\u239d",u="Size4-Regular",c="lparen",p=875):")"===e||"\\rparen"===e?(o="\u239e",l="\u239f",h="\u23a0",u="Size4-Regular",c="rparen",p=875):"\\{"===e||"\\lbrace"===e?(o="\u23a7",s="\u23a8",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\}"===e||"\\rbrace"===e?(o="\u23ab",s="\u23ac",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lgroup"===e||"\u27ee"===e?(o="\u23a7",h="\u23a9",l="\u23aa",u="Size4-Regular"):"\\rgroup"===e||"\u27ef"===e?(o="\u23ab",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\lmoustache"===e||"\u23b0"===e?(o="\u23a7",h="\u23ad",l="\u23aa",u="Size4-Regular"):"\\rmoustache"!==e&&"\u23b1"!==e||(o="\u23ab",h="\u23a9",l="\u23aa",u="Size4-Regular");var d=sr(o,u,n),g=d.height+d.depth,f=sr(l,u,n),v=f.height+f.depth,b=sr(h,u,n),y=b.height+b.depth,x=0,w=1;if(null!==s){var S=sr(s,u,n);x=S.height+S.depth,w=2}var M=g+y+x,z=M+Math.max(0,Math.ceil((t-M)/(w*v)))*w*v,A=a.fontMetrics().axisHeight;r&&(A*=a.sizeMultiplier);var T=z/2-A,B=[];if(c.length>0){var C=z-g-y,N=Math.round(1e3*z),q=function(e,t){switch(e){case"lbrack":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v1759 h347 v-84\nH403z M403 1759 V0 H319 V1759 v"+t+" v1759 h84z";case"rbrack":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v1759 H0 v84 H347z\nM347 1759 V0 H263 V1759 v"+t+" v1759 h84z";case"vert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z";case"doublevert":return"M145 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M188 15 H145 v585 v"+t+" v585 h43z\nM367 15 v585 v"+t+" v585 c2.667,10,9.667,15,21,15\nc10,0,16.667,-5,20,-15 v-585 v"+-t+" v-585 c-2.667,-10,-9.667,-15,-21,-15\nc-10,0,-16.667,5,-20,15z M410 15 H367 v585 v"+t+" v585 h43z";case"lfloor":return"M319 602 V0 H403 V602 v"+t+" v1715 h263 v84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"rfloor":return"M319 602 V0 H403 V602 v"+t+" v1799 H0 v-84 H319z\nMM319 602 V0 H403 V602 v"+t+" v1715 H319z";case"lceil":return"M403 1759 V84 H666 V0 H319 V1759 v"+t+" v602 h84z\nM403 1759 V0 H319 V1759 v"+t+" v602 h84z";case"rceil":return"M347 1759 V0 H0 V84 H263 V1759 v"+t+" v602 h84z\nM347 1759 V0 h-84 V1759 v"+t+" v602 h84z";case"lparen":return"M863,9c0,-2,-2,-5,-6,-9c0,0,-17,0,-17,0c-12.7,0,-19.3,0.3,-20,1\nc-5.3,5.3,-10.3,11,-15,17c-242.7,294.7,-395.3,682,-458,1162c-21.3,163.3,-33.3,349,\n-36,557 l0,"+(t+84)+"c0.2,6,0,26,0,60c2,159.3,10,310.7,24,454c53.3,528,210,\n949.7,470,1265c4.7,6,9.7,11.7,15,17c0.7,0.7,7,1,19,1c0,0,18,0,18,0c4,-4,6,-7,6,-9\nc0,-2.7,-3.3,-8.7,-10,-18c-135.3,-192.7,-235.5,-414.3,-300.5,-665c-65,-250.7,-102.5,\n-544.7,-112.5,-882c-2,-104,-3,-167,-3,-189\nl0,-"+(t+92)+"c0,-162.7,5.7,-314,17,-454c20.7,-272,63.7,-513,129,-723c65.3,\n-210,155.3,-396.3,270,-559c6.7,-9.3,10,-15.3,10,-18z";case"rparen":return"M76,0c-16.7,0,-25,3,-25,9c0,2,2,6.3,6,13c21.3,28.7,42.3,60.3,\n63,95c96.7,156.7,172.8,332.5,228.5,527.5c55.7,195,92.8,416.5,111.5,664.5\nc11.3,139.3,17,290.7,17,454c0,28,1.7,43,3.3,45l0,"+(t+9)+"\nc-3,4,-3.3,16.7,-3.3,38c0,162,-5.7,313.7,-17,455c-18.7,248,-55.8,469.3,-111.5,664\nc-55.7,194.7,-131.8,370.3,-228.5,527c-20.7,34.7,-41.7,66.3,-63,95c-2,3.3,-4,7,-6,11\nc0,7.3,5.7,11,17,11c0,0,11,0,11,0c9.3,0,14.3,-0.3,15,-1c5.3,-5.3,10.3,-11,15,-17\nc242.7,-294.7,395.3,-681.7,458,-1161c21.3,-164.7,33.3,-350.7,36,-558\nl0,-"+(t+144)+"c-2,-159.3,-10,-310.7,-24,-454c-53.3,-528,-210,-949.7,\n-470,-1265c-4.7,-6,-9.7,-11.7,-15,-17c-0.7,-0.7,-6.7,-1,-18,-1z";default:throw new Error("Unknown stretchy delimiter.")}}(c,Math.round(1e3*C)),I=new Q(c,q),R=(p/1e3).toFixed(3)+"em",H=(N/1e3).toFixed(3)+"em",O=new J([I],{width:R,height:H,viewBox:"0 0 "+p+" "+N}),E=Ke.makeSvgSpan([],[O],a);E.height=N/1e3,E.style.width=R,E.style.height=H,B.push({type:"elem",elem:E})}else{if(B.push(cr(h,u,n)),B.push(ur),null===s){var L=z-g-y+.016;B.push(pr(l,L,a))}else{var D=(z-g-y-x)/2+.016;B.push(pr(l,D,a)),B.push(ur),B.push(cr(s,u,n)),B.push(ur),B.push(pr(l,D,a))}B.push(ur),B.push(cr(o,u,n))}var V=a.havingBaseStyle(k.TEXT),P=Ke.makeVList({positionType:"bottom",positionData:T,children:B},V);return lr(Ke.makeSpan(["delimsizing","mult"],[P],V),k.TEXT,a,i)},vr=.08,br=function(e,t,r,a,n){var i=function(e,t,r){t*=1e3;var a="";switch(e){case"sqrtMain":a=function(e,t){return"M95,"+(622+e+t)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+e/2.075+" -"+e+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+e)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize1":a=function(e,t){return"M263,"+(601+e+t)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+e/2.084+" -"+e+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+e)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize2":a=function(e,t){return"M983 "+(10+e+t)+"\nl"+e/3.13+" -"+e+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+e)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+e)+" "+t+"h400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize3":a=function(e,t){return"M424,"+(2398+e+t)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+e/4.223+" -"+e+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+e)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+e)+" "+t+"\nh400000v"+(40+e)+"h-400000z"}(t,A);break;case"sqrtSize4":a=function(e,t){return"M473,"+(2713+e+t)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+e/5.298+" -"+e+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+e)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+e)+" "+t+"h400000v"+(40+e)+"H1017.7z"}(t,A);break;case"sqrtTall":a=function(e,t,r){return"M702 "+(e+t)+"H400000"+(40+e)+"\nH742v"+(r-54-t-e)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+t+"H400000v"+(40+e)+"H742z"}(t,A,r)}return a}(e,a,r),o=new Q(e,i),s=new J([o],{width:"400em",height:G(t),viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Ke.makeSvgSpan(["hide-tail"],[s],n)},yr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],xr=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],wr=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],kr=[0,1.2,1.8,2.4,3],Sr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],Mr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"stack"}],zr=[{type:"small",style:k.SCRIPTSCRIPT},{type:"small",style:k.SCRIPT},{type:"small",style:k.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],Ar=function(e){if("small"===e.type)return"Main-Regular";if("large"===e.type)return"Size"+e.size+"-Regular";if("stack"===e.type)return"Size4-Regular";throw new Error("Add support for delim type '"+e.type+"' here.")},Tr=function(e,t,r,a){for(var n=Math.min(2,3-a.style.size);nt)return r[n]}return r[r.length-1]},Br=function(e,t,r,a,n,i){var o;"<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),o=m.contains(wr,e)?Sr:m.contains(yr,e)?zr:Mr;var s=Tr(e,t,o,a);return"small"===s.type?function(e,t,r,a,n,i){var o=Ke.makeSymbol(e,"Main-Regular",n,a),s=lr(o,t,a,i);return r&&hr(s,a,t),s}(e,s.style,r,a,n,i):"large"===s.type?mr(e,s.size,r,a,n,i):fr(e,t,r,a,n,i)},Cr={sqrtImage:function(e,t){var r,a,n=t.havingBaseSizing(),i=Tr("\\surd",e*n.sizeMultiplier,zr,n),o=n.sizeMultiplier,s=Math.max(0,t.minRuleThickness-t.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(e<1?o=1:e<1.4&&(o=.7),h=(1+s)/o,(r=br("sqrtMain",l=(1+s+vr)/o,m=1e3+1e3*s+80,s,t)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*kr[i.size],h=(kr[i.size]+s)/o,l=(kr[i.size]+s+vr)/o,(r=br("sqrtSize"+i.size,l,m,s,t)).style.minWidth="1.02em",a=1/o):(l=e+s+vr,h=e+s,m=Math.floor(1e3*e+s)+80,(r=br("sqrtTall",l,m,s,t)).style.minWidth="0.742em",a=1.056),r.height=h,r.style.height=G(l),{span:r,advanceWidth:a,ruleWidth:(t.fontMetrics().sqrtRuleThickness+s)*o}},sizedDelim:function(e,t,r,a,n){if("<"===e||"\\lt"===e||"\u27e8"===e?e="\\langle":">"!==e&&"\\gt"!==e&&"\u27e9"!==e||(e="\\rangle"),m.contains(yr,e)||m.contains(wr,e))return mr(e,t,!1,r,a,n);if(m.contains(xr,e))return fr(e,kr[t],!1,r,a,n);throw new i("Illegal delimiter: '"+e+"'")},sizeToMaxHeight:kr,customSizedDelim:Br,leftRightDelim:function(e,t,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,l=Math.max(t-o,r+o),h=Math.max(l/500*901,2*l-s);return Br(e,h,!0,a,n,i)}},Nr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},qr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function Ir(e,t){var r=Yt(e);if(r&&m.contains(qr,r.text))return r;throw new i(r?"Invalid delimiter '"+r.text+"' after '"+t.funcName+"'":"Invalid delimiter type '"+e.type+"'",e)}function Rr(e){if(!e.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}ot({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1,argTypes:["primitive"]},handler:(e,t)=>{var r=Ir(t[0],e);return{type:"delimsizing",mode:e.parser.mode,size:Nr[e.funcName].size,mclass:Nr[e.funcName].mclass,delim:r.text}},htmlBuilder:(e,t)=>"."===e.delim?Ke.makeSpan([e.mclass]):Cr.sizedDelim(e.delim,e.size,t,e.mode,[e.mclass]),mathmlBuilder:e=>{var t=[];"."!==e.delim&&t.push(Bt(e.delim,e.mode));var r=new Tt.MathNode("mo",t);"mopen"===e.mclass||"mclose"===e.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r.setAttribute("stretchy","true");var a=G(Cr.sizeToMaxHeight[e.size]);return r.setAttribute("minsize",a),r.setAttribute("maxsize",a),r}}),ot({type:"leftright-right",names:["\\right"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=e.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new i("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:e.parser.mode,delim:Ir(t[0],e).text,color:r}}}),ot({type:"leftright",names:["\\left"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e),a=e.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Gt(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:(e,t)=>{Rr(e);for(var r,a,n=gt(e.body,t,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l{Rr(e);var r=qt(e.body,t);if("."!==e.left){var a=new Tt.MathNode("mo",[Bt(e.left,e.mode)]);a.setAttribute("fence","true"),r.unshift(a)}if("."!==e.right){var n=new Tt.MathNode("mo",[Bt(e.right,e.mode)]);n.setAttribute("fence","true"),e.rightColor&&n.setAttribute("mathcolor",e.rightColor),r.push(n)}return Ct(r)}}),ot({type:"middle",names:["\\middle"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var r=Ir(t[0],e);if(!e.parser.leftrightDepth)throw new i("\\middle without preceding \\left",r);return{type:"middle",mode:e.parser.mode,delim:r.text}},htmlBuilder:(e,t)=>{var r;if("."===e.delim)r=xt(t,[]);else{r=Cr.sizedDelim(e.delim,1,t,e.mode,[]);var a={delim:e.delim,options:t};r.isMiddle=a}return r},mathmlBuilder:(e,t)=>{var r="\\vert"===e.delim||"|"===e.delim?Bt("|","text"):Bt(e.delim,e.mode),a=new Tt.MathNode("mo",[r]);return a.setAttribute("fence","true"),a.setAttribute("lspace","0.05em"),a.setAttribute("rspace","0.05em"),a}});var Hr=(e,t)=>{var r,a,n,i=Ke.wrapFragment(wt(e.body,t),t),o=e.label.slice(1),s=t.sizeMultiplier,l=0,h=m.isCharacterBox(e.body);if("sout"===o)(r=Ke.makeSpan(["stretchy","sout"])).height=t.fontMetrics().defaultRuleThickness/s,l=-.5*t.fontMetrics().xHeight;else if("phase"===o){var c=F({number:.6,unit:"pt"},t),p=F({number:.35,unit:"ex"},t);s/=t.havingBaseSizing().sizeMultiplier;var u=i.height+i.depth+c+p;i.style.paddingLeft=G(u/2+c);var d=Math.floor(1e3*u*s),g="M400000 "+(a=d)+" H0 L"+a/2+" 0 l65 45 L145 "+(a-80)+" H400000z",f=new J([new Q("phase",g)],{width:"400em",height:G(d/1e3),viewBox:"0 0 400000 "+d,preserveAspectRatio:"xMinYMin slice"});(r=Ke.makeSvgSpan(["hide-tail"],[f],t)).style.height=G(u),l=i.depth+c+p}else{/cancel/.test(o)?h||i.classes.push("cancel-pad"):"angl"===o?i.classes.push("anglpad"):i.classes.push("boxpad");var v=0,b=0,y=0;/box/.test(o)?(y=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness),b=v=t.fontMetrics().fboxsep+("colorbox"===o?0:y)):"angl"===o?(v=4*(y=Math.max(t.fontMetrics().defaultRuleThickness,t.minRuleThickness)),b=Math.max(0,.25-i.depth)):b=v=h?.2:0,r=Vt(i,o,v,b,t),/fbox|boxed|fcolorbox/.test(o)?(r.style.borderStyle="solid",r.style.borderWidth=G(y)):"angl"===o&&.049!==y&&(r.style.borderTopWidth=G(y),r.style.borderRightWidth=G(y)),l=i.depth+b,e.backgroundColor&&(r.style.backgroundColor=e.backgroundColor,e.borderColor&&(r.style.borderColor=e.borderColor))}if(e.backgroundColor)n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:l},{type:"elem",elem:i,shift:0}]},t);else{var x=/cancel|phase/.test(o)?["svg-align"]:[];n=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:0},{type:"elem",elem:r,shift:l,wrapperClasses:x}]},t)}return/cancel/.test(o)&&(n.height=i.height,n.depth=i.depth),/cancel/.test(o)&&!h?Ke.makeSpan(["mord","cancel-lap"],[n],t):Ke.makeSpan(["mord"],[n],t)},Or=(e,t)=>{var r=0,a=new Tt.MathNode(e.label.indexOf("colorbox")>-1?"mpadded":"menclose",[Rt(e.body,t)]);switch(e.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\phase":a.setAttribute("notation","phasorangle");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\angl":a.setAttribute("notation","actuarial");break;case"\\fcolorbox":case"\\colorbox":if(r=t.fontMetrics().fboxsep*t.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===e.label){var n=Math.max(t.fontMetrics().fboxrule,t.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(e.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return e.backgroundColor&&a.setAttribute("mathbackground",e.backgroundColor),a};ot({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,argTypes:["color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=t[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,argTypes:["color","color","text"]},handler(e,t,r){var{parser:a,funcName:n}=e,i=Gt(t[0],"color-token").color,o=Gt(t[1],"color-token").color,s=t[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\fbox",body:t[0]}}}),ot({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout","\\phase"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"enclose",mode:r.mode,label:a,body:n}},htmlBuilder:Hr,mathmlBuilder:Or}),ot({type:"enclose",names:["\\angl"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"enclose",mode:r.mode,label:"\\angl",body:t[0]}}});var Er={};function Lr(e){for(var{type:t,names:r,props:a,handler:n,htmlBuilder:i,mathmlBuilder:o}=e,s={type:t,numArgs:a.numArgs||0,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l{if(!e.parser.settings.displayMode)throw new i("{"+e.envName+"} can be used only in display mode.")};function Gr(e){if(-1===e.indexOf("ed"))return-1===e.indexOf("*")}function Ur(e,t,r){var{hskipBeforeAndAfter:a,addJot:o,cols:s,arraystretch:l,colSeparationType:h,autoTag:m,singleRow:c,emptySingleRow:p,maxNumCols:u,leqno:d}=t;if(e.gullet.beginGroup(),c||e.gullet.macros.set("\\cr","\\\\\\relax"),!l){var g=e.gullet.expandMacroAsText("\\arraystretch");if(null==g)l=1;else if(!(l=parseFloat(g))||l<0)throw new i("Invalid \\arraystretch: "+g)}e.gullet.beginGroup();var f=[],v=[f],b=[],y=[],x=null!=m?[]:void 0;function w(){m&&e.gullet.macros.set("\\@eqnsw","1",!0)}function k(){x&&(e.gullet.macros.get("\\df@tag")?(x.push(e.subparse([new n("\\df@tag")])),e.gullet.macros.set("\\df@tag",void 0,!0)):x.push(Boolean(m)&&"1"===e.gullet.macros.get("\\@eqnsw")))}for(w(),y.push(Pr(e));;){var S=e.parseExpression(!1,c?"\\end":"\\\\");e.gullet.endGroup(),e.gullet.beginGroup(),S={type:"ordgroup",mode:e.mode,body:S},r&&(S={type:"styling",mode:e.mode,style:r,body:[S]}),f.push(S);var M=e.fetch().text;if("&"===M){if(u&&f.length===u){if(c||h)throw new i("Too many tab characters: &",e.nextToken);e.settings.reportNonstrict("textEnv","Too few columns specified in the {array} column argument.")}e.consume()}else{if("\\end"===M){k(),1===f.length&&"styling"===S.type&&0===S.body[0].body.length&&(v.length>1||!p)&&v.pop(),y.length0&&(y+=.25),h.push({pos:y,isDashed:e[t]})}for(x(o[0]),r=0;r0&&(M<(B+=b)&&(M=B),B=0),e.addJot&&(M+=g),z.height=S,z.depth=M,y+=S,z.pos=y,y+=M+B,l[r]=z,x(o[r+1])}var C,N,q=y/2+t.fontMetrics().axisHeight,I=e.cols||[],R=[],H=[];if(e.tags&&e.tags.some((e=>e)))for(r=0;r=s)){var W=void 0;(a>0||e.hskipBeforeAndAfter)&&0!==(W=m.deflt(V.pregap,u))&&((C=Ke.makeSpan(["arraycolsep"],[])).style.width=G(W),R.push(C));var _=[];for(r=0;r0){for(var K=Ke.makeLineSpan("hline",t,c),J=Ke.makeLineSpan("hdashline",t,c),Q=[{type:"elem",elem:l,shift:0}];h.length>0;){var ee=h.pop(),te=ee.pos-q;ee.isDashed?Q.push({type:"elem",elem:J,shift:te}):Q.push({type:"elem",elem:K,shift:te})}l=Ke.makeVList({positionType:"individualShift",children:Q},t)}if(0===H.length)return Ke.makeSpan(["mord"],[l],t);var re=Ke.makeVList({positionType:"individualShift",children:H},t);return re=Ke.makeSpan(["tag"],[re],t),Ke.makeFragment([l,re])},Wr={c:"center ",l:"left ",r:"right "},_r=function(e,t){for(var r=[],a=new Tt.MathNode("mtd",[],["mtr-glue"]),n=new Tt.MathNode("mtd",[],["mml-eqn-num"]),i=0;i0){var u=e.cols,d="",g=!1,f=0,v=u.length;"separator"===u[0].type&&(c+="top ",f=1),"separator"===u[u.length-1].type&&(c+="bottom ",v-=1);for(var b=f;b0?"left ":"",c+=S[S.length-1].length>0?"right ":"";for(var M=1;M-1?"alignat":"align",o="split"===e.envName,s=Ur(e.parser,{cols:a,addJot:!0,autoTag:o?void 0:Gr(e.envName),emptySingleRow:!0,colSeparationType:n,maxNumCols:o?2:void 0,leqno:e.parser.settings.leqno},"display"),l=0,h={type:"ordgroup",mode:e.mode,body:[]};if(t[0]&&"ordgroup"===t[0].type){for(var m="",c=0;c0&&p&&(g=1),a[u]={type:"align",align:d,pregap:g,postgap:0}}return s.colSeparationType=p?"align":"alignat",s};Lr({type:"array",names:["array","darray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lcr".indexOf(t))return{type:"align",align:t};if("|"===t)return{type:"separator",separator:"|"};if(":"===t)return{type:"separator",separator:":"};throw new i("Unknown column alignment: "+t,e)})),a={cols:r,hskipBeforeAndAfter:!0,maxNumCols:r.length};return Ur(e.parser,a,Yr(e.envName))},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix","matrix*","pmatrix*","bmatrix*","Bmatrix*","vmatrix*","Vmatrix*"],props:{numArgs:0},handler(e){var t={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[e.envName.replace("*","")],r="c",a={hskipBeforeAndAfter:!1,cols:[{type:"align",align:r}]};if("*"===e.envName.charAt(e.envName.length-1)){var n=e.parser;if(n.consumeSpaces(),"["===n.fetch().text){if(n.consume(),n.consumeSpaces(),r=n.fetch().text,-1==="lcr".indexOf(r))throw new i("Expected l or c or r",n.nextToken);n.consume(),n.consumeSpaces(),n.expect("]"),n.consume(),a.cols=[{type:"align",align:r}]}}var o=Ur(e.parser,a,Yr(e.envName)),s=Math.max(0,...o.body.map((e=>e.length)));return o.cols=new Array(s).fill({type:"align",align:r}),t?{type:"leftright",mode:e.mode,body:[o],left:t[0],right:t[1],rightColor:void 0}:o},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:.5},"script");return t.colSeparationType="small",t},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["subarray"],props:{numArgs:1},handler(e,t){var r=(Yt(t[0])?[t[0]]:Gt(t[0],"ordgroup").body).map((function(e){var t=Ut(e).text;if(-1!=="lc".indexOf(t))return{type:"align",align:t};throw new i("Unknown column alignment: "+t,e)}));if(r.length>1)throw new i("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=Ur(e.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new i("{subarray} can contain only one column");return a},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler(e){var t=Ur(e.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},Yr(e.envName));return{type:"leftright",mode:e.mode,body:[t],left:e.envName.indexOf("r")>-1?".":"\\{",right:e.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["align","align*","aligned","split"],props:{numArgs:0},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["gathered","gather","gather*"],props:{numArgs:0},handler(e){m.contains(["gather","gather*"],e.envName)&&Fr(e);var t={cols:[{type:"align",align:"c"}],addJot:!0,colSeparationType:"gather",autoTag:Gr(e.envName),emptySingleRow:!0,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["alignat","alignat*","alignedat"],props:{numArgs:1},handler:jr,htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["equation","equation*"],props:{numArgs:0},handler(e){Fr(e);var t={autoTag:Gr(e.envName),emptySingleRow:!0,singleRow:!0,maxNumCols:1,leqno:e.parser.settings.leqno};return Ur(e.parser,t,"display")},htmlBuilder:Xr,mathmlBuilder:_r}),Lr({type:"array",names:["CD"],props:{numArgs:0},handler:e=>(Fr(e),function(e){var t=[];for(e.gullet.beginGroup(),e.gullet.macros.set("\\cr","\\\\\\relax"),e.gullet.beginGroup();;){t.push(e.parseExpression(!1,"\\\\")),e.gullet.endGroup(),e.gullet.beginGroup();var r=e.fetch().text;if("&"!==r&&"\\\\"!==r){if("\\end"===r){0===t[t.length-1].length&&t.pop();break}throw new i("Expected \\\\ or \\cr or \\end",e.nextToken)}e.consume()}for(var a,n,o=[],s=[o],l=0;l-1);else{if(!("<>AV".indexOf(p)>-1))throw new i('Expected one of "<>AV=|." after @',h[c]);for(var d=0;d<2;d++){for(var g=!0,f=c+1;f{var r=e.font,a=t.withFont(r);return wt(e.body,a)},Kr=(e,t)=>{var r=e.font,a=t.withFont(r);return Rt(e.body,a)},Jr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};ot({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,allowedInArgument:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=lt(t[0]),i=a;return i in Jr&&(i=Jr[i]),{type:"font",mode:r.mode,font:i.slice(1),body:n}},htmlBuilder:Zr,mathmlBuilder:Kr}),ot({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1},handler:(e,t)=>{var{parser:r}=e,a=t[0],n=m.isCharacterBox(a);return{type:"mclass",mode:r.mode,mclass:Jt(a),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:a}],isCharacterBox:n}}}),ot({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a,breakOnTokenText:n}=e,{mode:i}=r,o=r.parseExpression(!0,n);return{type:"font",mode:i,font:"math"+a.slice(1),body:{type:"ordgroup",mode:r.mode,body:o}}},htmlBuilder:Zr,mathmlBuilder:Kr});var Qr=(e,t)=>{var r=t;return"display"===e?r=r.id>=k.SCRIPT.id?r.text():k.DISPLAY:"text"===e&&r.size===k.DISPLAY.size?r=k.TEXT:"script"===e?r=k.SCRIPT:"scriptscript"===e&&(r=k.SCRIPTSCRIPT),r},ea=(e,t)=>{var r,a=Qr(e.size,t.style),n=a.fracNum(),i=a.fracDen();r=t.havingStyle(n);var o=wt(e.numer,r,t);if(e.continued){var s=8.5/t.fontMetrics().ptPerEm,l=3.5/t.fontMetrics().ptPerEm;o.height=o.height0?3*c:7*c,d=t.fontMetrics().denom1):(m>0?(p=t.fontMetrics().num2,u=c):(p=t.fontMetrics().num3,u=3*c),d=t.fontMetrics().denom2),h){var x=t.fontMetrics().axisHeight;p-o.depth-(x+.5*m){var r=new Tt.MathNode("mfrac",[Rt(e.numer,t),Rt(e.denom,t)]);if(e.hasBarLine){if(e.barSize){var a=F(e.barSize,t);r.setAttribute("linethickness",G(a))}}else r.setAttribute("linethickness","0px");var n=Qr(e.size,t.style);if(n.size!==t.style.size){r=new Tt.MathNode("mstyle",[r]);var i=n.size===k.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",i),r.setAttribute("scriptlevel","0")}if(null!=e.leftDelim||null!=e.rightDelim){var o=[];if(null!=e.leftDelim){var s=new Tt.MathNode("mo",[new Tt.TextNode(e.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),o.push(s)}if(o.push(r),null!=e.rightDelim){var l=new Tt.MathNode("mo",[new Tt.TextNode(e.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),o.push(l)}return Ct(o)}return r};ot({type:"genfrac",names:["\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,allowedInArgument:!0},handler:(e,t)=>{var r,{parser:a,funcName:n}=e,i=t[0],o=t[1],s=null,l=null,h="auto";switch(n){case"\\dfrac":case"\\frac":case"\\tfrac":r=!0;break;case"\\\\atopfrac":r=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":r=!1,s="(",l=")";break;case"\\\\bracefrac":r=!1,s="\\{",l="\\}";break;case"\\\\brackfrac":r=!1,s="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:a.mode,continued:!1,numer:i,denom:o,hasBarLine:r,leftDelim:s,rightDelim:l,size:h,barSize:null}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"genfrac",names:["\\cfrac"],props:{numArgs:2},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=t[1];return{type:"genfrac",mode:r.mode,continued:!0,numer:n,denom:i,hasBarLine:!0,leftDelim:null,rightDelim:null,size:"display",barSize:null}}}),ot({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler(e){var t,{parser:r,funcName:a,token:n}=e;switch(a){case"\\over":t="\\frac";break;case"\\choose":t="\\binom";break;case"\\atop":t="\\\\atopfrac";break;case"\\brace":t="\\\\bracefrac";break;case"\\brack":t="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:t,token:n}}});var ra=["display","text","script","scriptscript"],aa=function(e){var t=null;return e.length>0&&(t="."===(t=e)?null:t),t};ot({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,allowedInArgument:!0,argTypes:["math","math","size","text","math","math"]},handler(e,t){var r,{parser:a}=e,n=t[4],i=t[5],o=lt(t[0]),s="atom"===o.type&&"open"===o.family?aa(o.text):null,l=lt(t[1]),h="atom"===l.type&&"close"===l.family?aa(l.text):null,m=Gt(t[2],"size"),c=null;r=!!m.isBlank||(c=m.value).number>0;var p="auto",u=t[3];if("ordgroup"===u.type){if(u.body.length>0){var d=Gt(u.body[0],"textord");p=ra[Number(d.text)]}}else u=Gt(u,"textord"),p=ra[Number(u.text)];return{type:"genfrac",mode:a.mode,numer:n,denom:i,continued:!1,hasBarLine:r,barSize:c,leftDelim:s,rightDelim:h,size:p}},htmlBuilder:ea,mathmlBuilder:ta}),ot({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler(e,t){var{parser:r,funcName:a,token:n}=e;return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Gt(t[0],"size").value,token:n}}}),ot({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0],i=function(e){if(!e)throw new Error("Expected non-null, but got "+String(e));return e}(Gt(t[1],"infix").size),o=t[2],s=i.number>0;return{type:"genfrac",mode:r.mode,numer:n,denom:o,continued:!1,hasBarLine:s,barSize:i,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:ea,mathmlBuilder:ta});var na=(e,t)=>{var r,a,n=t.style;"supsub"===e.type?(r=e.sup?wt(e.sup,t.havingStyle(n.sup()),t):wt(e.sub,t.havingStyle(n.sub()),t),a=Gt(e.base,"horizBrace")):a=Gt(e,"horizBrace");var i,o=wt(a.base,t.havingBaseStyle(k.DISPLAY)),s=Ft(a,t);if(a.isOver?(i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},t)).children[0].children[0].children[1].classes.push("svg-align"):(i=Ke.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},t)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t);i=a.isOver?Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},t):Ke.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},t)}return Ke.makeSpan(["mord",a.isOver?"mover":"munder"],[i],t)};ot({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler(e,t){var{parser:r,funcName:a}=e;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:t[0]}},htmlBuilder:na,mathmlBuilder:(e,t)=>{var r=Pt(e.label);return new Tt.MathNode(e.isOver?"mover":"munder",[Rt(e.base,t),r])}}),ot({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[1],n=Gt(t[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:ht(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:(e,t)=>{var r=gt(e.body,t,!1);return Ke.makeAnchor(e.href,[],r,t)},mathmlBuilder:(e,t)=>{var r=It(e.body,t);return r instanceof zt||(r=new zt("mrow",[r])),r.setAttribute("href",e.href),r}}),ot({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=Gt(t[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;inew Tt.MathNode("mrow",qt(e.body,t))}),ot({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:(e,t)=>{var r,{parser:a,funcName:n,token:o}=e,s=Gt(t[0],"raw").string,l=t[1];a.settings.strict&&a.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var h={};switch(n){case"\\htmlClass":h.class=s,r={command:"\\htmlClass",class:s};break;case"\\htmlId":h.id=s,r={command:"\\htmlId",id:s};break;case"\\htmlStyle":h.style=s,r={command:"\\htmlStyle",style:s};break;case"\\htmlData":for(var m=s.split(","),c=0;c{var r=gt(e.body,t,!1),a=["enclosing"];e.attributes.class&&a.push(...e.attributes.class.trim().split(/\s+/));var n=Ke.makeSpan(a,r,t);for(var i in e.attributes)"class"!==i&&e.attributes.hasOwnProperty(i)&&n.setAttribute(i,e.attributes[i]);return n},mathmlBuilder:(e,t)=>It(e.body,t)}),ot({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"htmlmathml",mode:r.mode,html:ht(t[0]),mathml:ht(t[1])}},htmlBuilder:(e,t)=>{var r=gt(e.html,t,!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>It(e.mathml,t)});var ia=function(e){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(e))return{number:+e,unit:"bp"};var t=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e);if(!t)throw new i("Invalid size: '"+e+"' in \\includegraphics");var r={number:+(t[1]+t[2]),unit:t[3]};if(!P(r))throw new i("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};ot({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:(e,t,r)=>{var{parser:a}=e,n={number:0,unit:"em"},o={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var h=Gt(r[0],"raw").string.split(","),m=0;m{var r=F(e.height,t),a=0;e.totalheight.number>0&&(a=F(e.totalheight,t)-r);var n=0;e.width.number>0&&(n=F(e.width,t));var i={height:G(r+a)};n>0&&(i.width=G(n)),a>0&&(i.verticalAlign=G(-a));var o=new $(e.src,e.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mglyph",[]);r.setAttribute("alt",e.alt);var a=F(e.height,t),n=0;if(e.totalheight.number>0&&(n=F(e.totalheight,t)-a,r.setAttribute("valign",G(-n))),r.setAttribute("height",G(a+n)),e.width.number>0){var i=F(e.width,t);r.setAttribute("width",G(i))}return r.setAttribute("src",e.src),r}}),ot({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],primitive:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=Gt(t[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:(e,t)=>Ke.makeGlue(e.dimension,t),mathmlBuilder(e,t){var r=F(e.dimension,t);return new Tt.SpaceNode(r)}}),ot({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=t[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:(e,t)=>{var r;"clap"===e.alignment?(r=Ke.makeSpan([],[wt(e.body,t)]),r=Ke.makeSpan(["inner"],[r],t)):r=Ke.makeSpan(["inner"],[wt(e.body,t)]);var a=Ke.makeSpan(["fix"],[]),n=Ke.makeSpan([e.alignment],[r,a],t),i=Ke.makeSpan(["strut"]);return i.style.height=G(n.height+n.depth),n.depth&&(i.style.verticalAlign=G(-n.depth)),n.children.unshift(i),n=Ke.makeSpan(["thinbox"],[n],t),Ke.makeSpan(["mord","vbox"],[n],t)},mathmlBuilder:(e,t)=>{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);if("rlap"!==e.alignment){var a="llap"===e.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),ot({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){var{funcName:r,parser:a}=e,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),ot({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler(e,t){throw new i("Mismatched "+e.funcName)}});var oa=(e,t)=>{switch(t.style.size){case k.DISPLAY.size:return e.display;case k.TEXT.size:return e.text;case k.SCRIPT.size:return e.script;case k.SCRIPTSCRIPT.size:return e.scriptscript;default:return e.text}};ot({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4,primitive:!0},handler:(e,t)=>{var{parser:r}=e;return{type:"mathchoice",mode:r.mode,display:ht(t[0]),text:ht(t[1]),script:ht(t[2]),scriptscript:ht(t[3])}},htmlBuilder:(e,t)=>{var r=oa(e,t),a=gt(r,t,!1);return Ke.makeFragment(a)},mathmlBuilder:(e,t)=>{var r=oa(e,t);return It(r,t)}});var sa=(e,t,r,a,n,i,o)=>{e=Ke.makeSpan([],[e]);var s,l,h,c=r&&m.isCharacterBox(r);if(t){var p=wt(t,a.havingStyle(n.sup()),a);l={elem:p,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-p.depth)}}if(r){var u=wt(r,a.havingStyle(n.sub()),a);s={elem:u,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-u.height)}}if(l&&s){var d=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:d,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var g=e.height-o;h=Ke.makeVList({positionType:"top",positionData:g,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:G(-i)},{type:"kern",size:s.kern},{type:"elem",elem:e}]},a)}else{if(!l)return e;var f=e.depth+o;h=Ke.makeVList({positionType:"bottom",positionData:f,children:[{type:"elem",elem:e},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:G(i)},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}var v=[h];if(s&&0!==i&&!c){var b=Ke.makeSpan(["mspace"],[],a);b.style.marginRight=G(i),v.unshift(b)}return Ke.makeSpan(["mop","op-limits"],v,a)},la=["\\smallint"],ha=(e,t)=>{var r,a,n,i=!1;"supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"op"),i=!0):n=Gt(e,"op");var o,s=t.style,l=!1;if(s.size===k.DISPLAY.size&&n.symbol&&!m.contains(la,n.name)&&(l=!0),n.symbol){var h=l?"Size2-Regular":"Size1-Regular",c="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(c=n.name.slice(1),n.name="oiint"===c?"\\iint":"\\iiint"),o=Ke.makeSymbol(n.name,h,"math",t,["mop","op-symbol",l?"large-op":"small-op"]),c.length>0){var p=o.italic,u=Ke.staticSvg(c+"Size"+(l?"2":"1"),t);o=Ke.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:u,shift:l?.08:0}]},t),n.name="\\"+c,o.classes.unshift("mop"),o.italic=p}}else if(n.body){var d=gt(n.body,t,!0);1===d.length&&d[0]instanceof K?(o=d[0]).classes[0]="mop":o=Ke.makeSpan(["mop"],d,t)}else{for(var g=[],f=1;f{var r;if(e.symbol)r=new zt("mo",[Bt(e.name,e.mode)]),m.contains(la,e.name)&&r.setAttribute("largeop","false");else if(e.body)r=new zt("mo",qt(e.body,t));else{r=new zt("mi",[new At(e.name.slice(1))]);var a=new zt("mo",[Bt("\u2061","text")]);r=e.parentIsSupSub?new zt("mrow",[r,a]):Mt([r,a])}return r},ca={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};ot({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:(e,t)=>{var{parser:r,funcName:a}=e,n=a;return 1===n.length&&(n=ca[n]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:n}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\mathop"],props:{numArgs:1,primitive:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:ht(a)}},htmlBuilder:ha,mathmlBuilder:ma});var pa={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};ot({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e;return{type:"op",mode:t.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:ha,mathmlBuilder:ma}),ot({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler(e){var{parser:t,funcName:r}=e,a=r;return 1===a.length&&(a=pa[a]),{type:"op",mode:t.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:a}},htmlBuilder:ha,mathmlBuilder:ma});var ua=(e,t)=>{var r,a,n,i,o=!1;if("supsub"===e.type?(r=e.sup,a=e.sub,n=Gt(e.base,"operatorname"),o=!0):n=Gt(e,"operatorname"),n.body.length>0){for(var s=n.body.map((e=>{var t=e.text;return"string"==typeof t?{type:"textord",mode:e.mode,text:t}:e})),l=gt(s,t.withFont("mathrm"),!0),h=0;h{var{parser:r,funcName:a}=e,n=t[0];return{type:"operatorname",mode:r.mode,body:ht(n),alwaysHandleSupSub:"\\operatornamewithlimits"===a,limits:!1,parentIsSupSub:!1}},htmlBuilder:ua,mathmlBuilder:(e,t)=>{for(var r=qt(e.body,t.withFont("mathrm")),a=!0,n=0;ne.toText())).join("");r=[new Tt.TextNode(s)]}var l=new Tt.MathNode("mi",r);l.setAttribute("mathvariant","normal");var h=new Tt.MathNode("mo",[Bt("\u2061","text")]);return e.parentIsSupSub?new Tt.MathNode("mrow",[l,h]):Tt.newDocumentFragment([l,h])}}),Vr("\\operatorname","\\@ifstar\\operatornamewithlimits\\operatorname@"),st({type:"ordgroup",htmlBuilder:(e,t)=>e.semisimple?Ke.makeFragment(gt(e.body,t,!1)):Ke.makeSpan(["mord"],gt(e.body,t,!0),t),mathmlBuilder:(e,t)=>It(e.body,t,!0)}),ot({type:"overline",names:["\\overline"],props:{numArgs:1},handler(e,t){var{parser:r}=e,a=t[0];return{type:"overline",mode:r.mode,body:a}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle()),a=Ke.makeLineSpan("overline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:a},{type:"kern",size:n}]},t);return Ke.makeSpan(["mord","overline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("mover",[Rt(e.body,t),r]);return a.setAttribute("accent","true"),a}}),ot({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"phantom",mode:r.mode,body:ht(a)}},htmlBuilder:(e,t)=>{var r=gt(e.body,t.withPhantom(),!1);return Ke.makeFragment(r)},mathmlBuilder:(e,t)=>{var r=qt(e.body,t);return new Tt.MathNode("mphantom",r)}}),ot({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"hphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan([],[wt(e.body,t.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var a=0;a{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}}),ot({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:(e,t)=>{var{parser:r}=e,a=t[0];return{type:"vphantom",mode:r.mode,body:a}},htmlBuilder:(e,t)=>{var r=Ke.makeSpan(["inner"],[wt(e.body,t.withPhantom())]),a=Ke.makeSpan(["fix"],[]);return Ke.makeSpan(["mord","rlap"],[r,a],t)},mathmlBuilder:(e,t)=>{var r=qt(ht(e.body),t),a=new Tt.MathNode("mphantom",r),n=new Tt.MathNode("mpadded",[a]);return n.setAttribute("width","0px"),n}}),ot({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler(e,t){var{parser:r}=e,a=Gt(t[0],"size").value,n=t[1];return{type:"raisebox",mode:r.mode,dy:a,body:n}},htmlBuilder(e,t){var r=wt(e.body,t),a=F(e.dy,t);return Ke.makeVList({positionType:"shift",positionData:-a,children:[{type:"elem",elem:r}]},t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]),a=e.dy.number+e.dy.unit;return r.setAttribute("voffset",a),r}}),ot({type:"internal",names:["\\relax"],props:{numArgs:0,allowedInText:!0},handler(e){var{parser:t}=e;return{type:"internal",mode:t.mode}}}),ot({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler(e,t,r){var{parser:a}=e,n=r[0],i=Gt(t[0],"size"),o=Gt(t[1],"size");return{type:"rule",mode:a.mode,shift:n&&Gt(n,"size").value,width:i.value,height:o.value}},htmlBuilder(e,t){var r=Ke.makeSpan(["mord","rule"],[],t),a=F(e.width,t),n=F(e.height,t),i=e.shift?F(e.shift,t):0;return r.style.borderRightWidth=G(a),r.style.borderTopWidth=G(n),r.style.bottom=G(i),r.width=a,r.height=n+i,r.depth=-i,r.maxFontSize=1.125*n*t.sizeMultiplier,r},mathmlBuilder(e,t){var r=F(e.width,t),a=F(e.height,t),n=e.shift?F(e.shift,t):0,i=t.color&&t.getColor()||"black",o=new Tt.MathNode("mspace");o.setAttribute("mathbackground",i),o.setAttribute("width",G(r)),o.setAttribute("height",G(a));var s=new Tt.MathNode("mpadded",[o]);return n>=0?s.setAttribute("height",G(n)):(s.setAttribute("height",G(n)),s.setAttribute("depth",G(-n))),s.setAttribute("voffset",G(n)),s}});var ga=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];ot({type:"sizing",names:ga,props:{numArgs:0,allowedInText:!0},handler:(e,t)=>{var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:ga.indexOf(a)+1,body:i}},htmlBuilder:(e,t)=>{var r=t.havingSize(e.size);return da(e.body,r,t)},mathmlBuilder:(e,t)=>{var r=t.havingSize(e.size),a=qt(e.body,r),n=new Tt.MathNode("mstyle",a);return n.setAttribute("mathsize",G(r.sizeMultiplier)),n}}),ot({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:(e,t,r)=>{var{parser:a}=e,n=!1,i=!1,o=r[0]&&Gt(r[0],"ordgroup");if(o)for(var s="",l=0;l{var r=Ke.makeSpan([],[wt(e.body,t)]);if(!e.smashHeight&&!e.smashDepth)return r;if(e.smashHeight&&(r.height=0,r.children))for(var a=0;a{var r=new Tt.MathNode("mpadded",[Rt(e.body,t)]);return e.smashHeight&&r.setAttribute("height","0px"),e.smashDepth&&r.setAttribute("depth","0px"),r}}),ot({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler(e,t,r){var{parser:a}=e,n=r[0],i=t[0];return{type:"sqrt",mode:a.mode,body:i,index:n}},htmlBuilder(e,t){var r=wt(e.body,t.havingCrampedStyle());0===r.height&&(r.height=t.fontMetrics().xHeight),r=Ke.wrapFragment(r,t);var a=t.fontMetrics().defaultRuleThickness,n=a;t.style.idr.height+r.depth+i&&(i=(i+m-r.height-r.depth)/2);var c=s.height-r.height-i-l;r.style.paddingLeft=G(h);var p=Ke.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+c)},{type:"elem",elem:s},{type:"kern",size:l}]},t);if(e.index){var u=t.havingStyle(k.SCRIPTSCRIPT),d=wt(e.index,u,t),g=.6*(p.height-p.depth),f=Ke.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:d}]},t),v=Ke.makeSpan(["root"],[f]);return Ke.makeSpan(["mord","sqrt"],[v,p],t)}return Ke.makeSpan(["mord","sqrt"],[p],t)},mathmlBuilder(e,t){var{body:r,index:a}=e;return a?new Tt.MathNode("mroot",[Rt(r,t),Rt(a,t)]):new Tt.MathNode("msqrt",[Rt(r,t)])}});var fa={display:k.DISPLAY,text:k.TEXT,script:k.SCRIPT,scriptscript:k.SCRIPTSCRIPT};ot({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0,primitive:!0},handler(e,t){var{breakOnTokenText:r,funcName:a,parser:n}=e,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r).withFont("");return da(e.body,a,t)},mathmlBuilder(e,t){var r=fa[e.style],a=t.havingStyle(r),n=qt(e.body,a),i=new Tt.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[e.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});st({type:"supsub",htmlBuilder(e,t){var r=function(e,t){var r=e.base;return r?"op"===r.type?r.limits&&(t.style.size===k.DISPLAY.size||r.alwaysHandleSupSub)?ha:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(t.style.size===k.DISPLAY.size||r.limits)?ua:null:"accent"===r.type?m.isCharacterBox(r.base)?Xt:null:"horizBrace"===r.type&&!e.sub===r.isOver?na:null:null}(e,t);if(r)return r(e,t);var a,n,i,{base:o,sup:s,sub:l}=e,h=wt(o,t),c=t.fontMetrics(),p=0,u=0,d=o&&m.isCharacterBox(o);if(s){var g=t.havingStyle(t.style.sup());a=wt(s,g,t),d||(p=h.height-g.fontMetrics().supDrop*g.sizeMultiplier/t.sizeMultiplier)}if(l){var f=t.havingStyle(t.style.sub());n=wt(l,f,t),d||(u=h.depth+f.fontMetrics().subDrop*f.sizeMultiplier/t.sizeMultiplier)}i=t.style===k.DISPLAY?c.sup1:t.style.cramped?c.sup3:c.sup2;var v,b=t.sizeMultiplier,y=G(.5/c.ptPerEm/b),x=null;if(n){var w=e.base&&"op"===e.base.type&&e.base.name&&("\\oiint"===e.base.name||"\\oiiint"===e.base.name);(h instanceof K||w)&&(x=G(-h.italic))}if(a&&n){p=Math.max(p,i,a.depth+.25*c.xHeight),u=Math.max(u,c.sub2);var S=4*c.defaultRuleThickness;if(p-a.depth-(n.height-u)0&&(p+=M,u-=M)}var z=[{type:"elem",elem:n,shift:u,marginRight:y,marginLeft:x},{type:"elem",elem:a,shift:-p,marginRight:y}];v=Ke.makeVList({positionType:"individualShift",children:z},t)}else if(n){u=Math.max(u,c.sub1,n.height-.8*c.xHeight);var A=[{type:"elem",elem:n,marginLeft:x,marginRight:y}];v=Ke.makeVList({positionType:"shift",positionData:u,children:A},t)}else{if(!a)throw new Error("supsub must have either sup or sub.");p=Math.max(p,i,a.depth+.25*c.xHeight),v=Ke.makeVList({positionType:"shift",positionData:-p,children:[{type:"elem",elem:a,marginRight:y}]},t)}var T=yt(h,"right")||"mord";return Ke.makeSpan([T],[h,Ke.makeSpan(["msupsub"],[v])],t)},mathmlBuilder(e,t){var r,a=!1;e.base&&"horizBrace"===e.base.type&&!!e.sup===e.base.isOver&&(a=!0,r=e.base.isOver),!e.base||"op"!==e.base.type&&"operatorname"!==e.base.type||(e.base.parentIsSupSub=!0);var n,i=[Rt(e.base,t)];if(e.sub&&i.push(Rt(e.sub,t)),e.sup&&i.push(Rt(e.sup,t)),a)n=r?"mover":"munder";else if(e.sub)if(e.sup){var o=e.base;n=o&&"op"===o.type&&o.limits&&t.style===k.DISPLAY||o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(t.style===k.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=e.base;n=s&&"op"===s.type&&s.limits&&(t.style===k.DISPLAY||s.alwaysHandleSupSub)||s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||t.style===k.DISPLAY)?"munder":"msub"}else{var l=e.base;n=l&&"op"===l.type&&l.limits&&(t.style===k.DISPLAY||l.alwaysHandleSupSub)||l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||t.style===k.DISPLAY)?"mover":"msup"}return new Tt.MathNode(n,i)}}),st({type:"atom",htmlBuilder:(e,t)=>Ke.mathsym(e.text,e.mode,t,["m"+e.family]),mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[Bt(e.text,e.mode)]);if("bin"===e.family){var a=Nt(e,t);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===e.family?r.setAttribute("separator","true"):"open"!==e.family&&"close"!==e.family||r.setAttribute("stretchy","false");return r}});var va={mi:"italic",mn:"normal",mtext:"normal"};st({type:"mathord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"mathord"),mathmlBuilder(e,t){var r=new Tt.MathNode("mi",[Bt(e.text,e.mode,t)]),a=Nt(e,t)||"italic";return a!==va[r.type]&&r.setAttribute("mathvariant",a),r}}),st({type:"textord",htmlBuilder:(e,t)=>Ke.makeOrd(e,t,"textord"),mathmlBuilder(e,t){var r,a=Bt(e.text,e.mode,t),n=Nt(e,t)||"normal";return r="text"===e.mode?new Tt.MathNode("mtext",[a]):/[0-9]/.test(e.text)?new Tt.MathNode("mn",[a]):"\\prime"===e.text?new Tt.MathNode("mo",[a]):new Tt.MathNode("mi",[a]),n!==va[r.type]&&r.setAttribute("mathvariant",n),r}});var ba={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},ya={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};st({type:"spacing",htmlBuilder(e,t){if(ya.hasOwnProperty(e.text)){var r=ya[e.text].className||"";if("text"===e.mode){var a=Ke.makeOrd(e,t,"textord");return a.classes.push(r),a}return Ke.makeSpan(["mspace",r],[Ke.mathsym(e.text,e.mode,t)],t)}if(ba.hasOwnProperty(e.text))return Ke.makeSpan(["mspace",ba[e.text]],[],t);throw new i('Unknown type of space "'+e.text+'"')},mathmlBuilder(e,t){if(!ya.hasOwnProperty(e.text)){if(ba.hasOwnProperty(e.text))return new Tt.MathNode("mspace");throw new i('Unknown type of space "'+e.text+'"')}return new Tt.MathNode("mtext",[new Tt.TextNode("\xa0")])}});var xa=()=>{var e=new Tt.MathNode("mtd",[]);return e.setAttribute("width","50%"),e};st({type:"tag",mathmlBuilder(e,t){var r=new Tt.MathNode("mtable",[new Tt.MathNode("mtr",[xa(),new Tt.MathNode("mtd",[It(e.body,t)]),xa(),new Tt.MathNode("mtd",[It(e.tag,t)])])]);return r.setAttribute("width","100%"),r}});var wa={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},ka={"\\textbf":"textbf","\\textmd":"textmd"},Sa={"\\textit":"textit","\\textup":"textup"},Ma=(e,t)=>{var r=e.font;return r?wa[r]?t.withTextFontFamily(wa[r]):ka[r]?t.withTextFontWeight(ka[r]):"\\emph"===r?"textit"===t.fontShape?t.withTextFontShape("textup"):t.withTextFontShape("textit"):t.withTextFontShape(Sa[r]):t};ot({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup","\\emph"],props:{numArgs:1,argTypes:["text"],allowedInArgument:!0,allowedInText:!0},handler(e,t){var{parser:r,funcName:a}=e,n=t[0];return{type:"text",mode:r.mode,body:ht(n),font:a}},htmlBuilder(e,t){var r=Ma(e,t),a=gt(e.body,r,!0);return Ke.makeSpan(["mord","text"],a,r)},mathmlBuilder(e,t){var r=Ma(e,t);return It(e.body,r)}}),ot({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler(e,t){var{parser:r}=e;return{type:"underline",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=Ke.makeLineSpan("underline-line",t),n=t.fontMetrics().defaultRuleThickness,i=Ke.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},t);return Ke.makeSpan(["mord","underline"],[i],t)},mathmlBuilder(e,t){var r=new Tt.MathNode("mo",[new Tt.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new Tt.MathNode("munder",[Rt(e.body,t),r]);return a.setAttribute("accentunder","true"),a}}),ot({type:"vcenter",names:["\\vcenter"],props:{numArgs:1,argTypes:["original"],allowedInText:!1},handler(e,t){var{parser:r}=e;return{type:"vcenter",mode:r.mode,body:t[0]}},htmlBuilder(e,t){var r=wt(e.body,t),a=t.fontMetrics().axisHeight,n=.5*(r.height-a-(r.depth+a));return Ke.makeVList({positionType:"shift",positionData:n,children:[{type:"elem",elem:r}]},t)},mathmlBuilder:(e,t)=>new Tt.MathNode("mpadded",[Rt(e.body,t)],["vcenter"])}),ot({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler(e,t,r){throw new i("\\verb ended by end of line instead of matching delimiter")},htmlBuilder(e,t){for(var r=za(e),a=[],n=t.havingStyle(t.style.text()),i=0;ie.body.replace(/ /g,e.star?"\u2423":"\xa0"),Aa=at,Ta="[ \r\n\t]",Ba="(\\\\[a-zA-Z@]+)"+Ta+"*",Ca="[\u0300-\u036f]",Na=new RegExp(Ca+"+$"),qa="("+Ta+"+)|\\\\(\n|[ \r\t]+\n?)[ \r\t]*|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff]"+Ca+"*|[\ud800-\udbff][\udc00-\udfff]"+Ca+"*|\\\\verb\\*([^]).*?\\4|\\\\verb([^*a-zA-Z]).*?\\5|"+Ba+"|\\\\[^\ud800-\udfff])";class Ia{constructor(e,t){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=e,this.settings=t,this.tokenRegex=new RegExp(qa,"g"),this.catcodes={"%":14,"~":13}}setCatcode(e,t){this.catcodes[e]=t}lex(){var e=this.input,t=this.tokenRegex.lastIndex;if(t===e.length)return new n("EOF",new a(this,t,t));var r=this.tokenRegex.exec(e);if(null===r||r.index!==t)throw new i("Unexpected character: '"+e[t]+"'",new n(e[t],new a(this,t,t+1)));var o=r[6]||r[3]||(r[2]?"\\ ":" ");if(14===this.catcodes[o]){var s=e.indexOf("\n",this.tokenRegex.lastIndex);return-1===s?(this.tokenRegex.lastIndex=e.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}return new n(o,new a(this,t,this.tokenRegex.lastIndex))}}class Ra{constructor(e,t){void 0===e&&(e={}),void 0===t&&(t={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=t,this.builtins=e,this.undefStack=[]}beginGroup(){this.undefStack.push({})}endGroup(){if(0===this.undefStack.length)throw new i("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var e=this.undefStack.pop();for(var t in e)e.hasOwnProperty(t)&&(null==e[t]?delete this.current[t]:this.current[t]=e[t])}endGroups(){for(;this.undefStack.length>0;)this.endGroup()}has(e){return this.current.hasOwnProperty(e)||this.builtins.hasOwnProperty(e)}get(e){return this.current.hasOwnProperty(e)?this.current[e]:this.builtins[e]}set(e,t,r){if(void 0===r&&(r=!1),r){for(var a=0;a0&&(this.undefStack[this.undefStack.length-1][e]=t)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(e)&&(n[e]=this.current[e])}null==t?delete this.current[e]:this.current[e]=t}}var Ha=Dr;Vr("\\noexpand",(function(e){var t=e.popToken();return e.isExpandable(t.text)&&(t.noexpand=!0,t.treatAsRelax=!0),{tokens:[t],numArgs:0}})),Vr("\\expandafter",(function(e){var t=e.popToken();return e.expandOnce(!0),{tokens:[t],numArgs:0}})),Vr("\\@firstoftwo",(function(e){return{tokens:e.consumeArgs(2)[0],numArgs:0}})),Vr("\\@secondoftwo",(function(e){return{tokens:e.consumeArgs(2)[1],numArgs:0}})),Vr("\\@ifnextchar",(function(e){var t=e.consumeArgs(3);e.consumeSpaces();var r=e.future();return 1===t[0].length&&t[0][0].text===r.text?{tokens:t[1],numArgs:0}:{tokens:t[2],numArgs:0}})),Vr("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),Vr("\\TextOrMath",(function(e){var t=e.consumeArgs(2);return"text"===e.mode?{tokens:t[0],numArgs:0}:{tokens:t[1],numArgs:0}}));var Oa={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};Vr("\\char",(function(e){var t,r=e.popToken(),a="";if("'"===r.text)t=8,r=e.popToken();else if('"'===r.text)t=16,r=e.popToken();else if("`"===r.text)if("\\"===(r=e.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new i("\\char` missing argument");a=r.text.charCodeAt(0)}else t=10;if(t){if(null==(a=Oa[r.text])||a>=t)throw new i("Invalid base-"+t+" digit "+r.text);for(var n;null!=(n=Oa[e.future().text])&&n{var a=e.consumeArg().tokens;if(1!==a.length)throw new i("\\newcommand's first argument must be a macro name");var n=a[0].text,o=e.isDefined(n);if(o&&!t)throw new i("\\newcommand{"+n+"} attempting to redefine "+n+"; use \\renewcommand");if(!o&&!r)throw new i("\\renewcommand{"+n+"} when command "+n+" does not yet exist; use \\newcommand");var s=0;if(1===(a=e.consumeArg().tokens).length&&"["===a[0].text){for(var l="",h=e.expandNextToken();"]"!==h.text&&"EOF"!==h.text;)l+=h.text,h=e.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new i("Invalid number of arguments: "+l);s=parseInt(l),a=e.consumeArg().tokens}return e.macros.set(n,{tokens:a,numArgs:s}),""};Vr("\\newcommand",(e=>Ea(e,!1,!0))),Vr("\\renewcommand",(e=>Ea(e,!0,!1))),Vr("\\providecommand",(e=>Ea(e,!0,!0))),Vr("\\message",(e=>{var t=e.consumeArgs(1)[0];return console.log(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\errmessage",(e=>{var t=e.consumeArgs(1)[0];return console.error(t.reverse().map((e=>e.text)).join("")),""})),Vr("\\show",(e=>{var t=e.popToken(),r=t.text;return console.log(t,e.macros.get(r),Aa[r],ne.math[r],ne.text[r]),""})),Vr("\\bgroup","{"),Vr("\\egroup","}"),Vr("~","\\nobreakspace"),Vr("\\lq","`"),Vr("\\rq","'"),Vr("\\aa","\\r a"),Vr("\\AA","\\r A"),Vr("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),Vr("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),Vr("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),Vr("\u212c","\\mathscr{B}"),Vr("\u2130","\\mathscr{E}"),Vr("\u2131","\\mathscr{F}"),Vr("\u210b","\\mathscr{H}"),Vr("\u2110","\\mathscr{I}"),Vr("\u2112","\\mathscr{L}"),Vr("\u2133","\\mathscr{M}"),Vr("\u211b","\\mathscr{R}"),Vr("\u212d","\\mathfrak{C}"),Vr("\u210c","\\mathfrak{H}"),Vr("\u2128","\\mathfrak{Z}"),Vr("\\Bbbk","\\Bbb{k}"),Vr("\xb7","\\cdotp"),Vr("\\llap","\\mathllap{\\textrm{#1}}"),Vr("\\rlap","\\mathrlap{\\textrm{#1}}"),Vr("\\clap","\\mathclap{\\textrm{#1}}"),Vr("\\mathstrut","\\vphantom{(}"),Vr("\\underbar","\\underline{\\text{#1}}"),Vr("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),Vr("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),Vr("\\ne","\\neq"),Vr("\u2260","\\neq"),Vr("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),Vr("\u2209","\\notin"),Vr("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),Vr("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),Vr("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),Vr("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),Vr("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),Vr("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),Vr("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),Vr("\u27c2","\\perp"),Vr("\u203c","\\mathclose{!\\mkern-0.8mu!}"),Vr("\u220c","\\notni"),Vr("\u231c","\\ulcorner"),Vr("\u231d","\\urcorner"),Vr("\u231e","\\llcorner"),Vr("\u231f","\\lrcorner"),Vr("\xa9","\\copyright"),Vr("\xae","\\textregistered"),Vr("\ufe0f","\\textregistered"),Vr("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),Vr("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),Vr("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),Vr("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),Vr("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}"),Vr("\u22ee","\\vdots"),Vr("\\varGamma","\\mathit{\\Gamma}"),Vr("\\varDelta","\\mathit{\\Delta}"),Vr("\\varTheta","\\mathit{\\Theta}"),Vr("\\varLambda","\\mathit{\\Lambda}"),Vr("\\varXi","\\mathit{\\Xi}"),Vr("\\varPi","\\mathit{\\Pi}"),Vr("\\varSigma","\\mathit{\\Sigma}"),Vr("\\varUpsilon","\\mathit{\\Upsilon}"),Vr("\\varPhi","\\mathit{\\Phi}"),Vr("\\varPsi","\\mathit{\\Psi}"),Vr("\\varOmega","\\mathit{\\Omega}"),Vr("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),Vr("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu\\relax"),Vr("\\boxed","\\fbox{$\\displaystyle{#1}$}"),Vr("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),Vr("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),Vr("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");var La={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};Vr("\\dots",(function(e){var t="\\dotso",r=e.expandAfterFuture().text;return r in La?t=La[r]:("\\not"===r.slice(0,4)||r in ne.math&&m.contains(["bin","rel"],ne.math[r].group))&&(t="\\dotsb"),t}));var Da={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};Vr("\\dotso",(function(e){return e.future().text in Da?"\\ldots\\,":"\\ldots"})),Vr("\\dotsc",(function(e){var t=e.future().text;return t in Da&&","!==t?"\\ldots\\,":"\\ldots"})),Vr("\\cdots",(function(e){return e.future().text in Da?"\\@cdots\\,":"\\@cdots"})),Vr("\\dotsb","\\cdots"),Vr("\\dotsm","\\cdots"),Vr("\\dotsi","\\!\\cdots"),Vr("\\dotsx","\\ldots\\,"),Vr("\\DOTSI","\\relax"),Vr("\\DOTSB","\\relax"),Vr("\\DOTSX","\\relax"),Vr("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),Vr("\\,","\\tmspace+{3mu}{.1667em}"),Vr("\\thinspace","\\,"),Vr("\\>","\\mskip{4mu}"),Vr("\\:","\\tmspace+{4mu}{.2222em}"),Vr("\\medspace","\\:"),Vr("\\;","\\tmspace+{5mu}{.2777em}"),Vr("\\thickspace","\\;"),Vr("\\!","\\tmspace-{3mu}{.1667em}"),Vr("\\negthinspace","\\!"),Vr("\\negmedspace","\\tmspace-{4mu}{.2222em}"),Vr("\\negthickspace","\\tmspace-{5mu}{.277em}"),Vr("\\enspace","\\kern.5em "),Vr("\\enskip","\\hskip.5em\\relax"),Vr("\\quad","\\hskip1em\\relax"),Vr("\\qquad","\\hskip2em\\relax"),Vr("\\tag","\\@ifstar\\tag@literal\\tag@paren"),Vr("\\tag@paren","\\tag@literal{({#1})}"),Vr("\\tag@literal",(e=>{if(e.macros.get("\\df@tag"))throw new i("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"})),Vr("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),Vr("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),Vr("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),Vr("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),Vr("\\newline","\\\\\\relax"),Vr("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var Va=G(C["Main-Regular"]["T".charCodeAt(0)][1]-.7*C["Main-Regular"]["A".charCodeAt(0)][1]);Vr("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),Vr("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+Va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),Vr("\\hspace","\\@ifstar\\@hspacer\\@hspace"),Vr("\\@hspace","\\hskip #1\\relax"),Vr("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),Vr("\\ordinarycolon",":"),Vr("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),Vr("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),Vr("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),Vr("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),Vr("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),Vr("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),Vr("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),Vr("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),Vr("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),Vr("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),Vr("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),Vr("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),Vr("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),Vr("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),Vr("\u2237","\\dblcolon"),Vr("\u2239","\\eqcolon"),Vr("\u2254","\\coloneqq"),Vr("\u2255","\\eqqcolon"),Vr("\u2a74","\\Coloneqq"),Vr("\\ratio","\\vcentcolon"),Vr("\\coloncolon","\\dblcolon"),Vr("\\colonequals","\\coloneqq"),Vr("\\coloncolonequals","\\Coloneqq"),Vr("\\equalscolon","\\eqqcolon"),Vr("\\equalscoloncolon","\\Eqqcolon"),Vr("\\colonminus","\\coloneq"),Vr("\\coloncolonminus","\\Coloneq"),Vr("\\minuscolon","\\eqcolon"),Vr("\\minuscoloncolon","\\Eqcolon"),Vr("\\coloncolonapprox","\\Colonapprox"),Vr("\\coloncolonsim","\\Colonsim"),Vr("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),Vr("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),Vr("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),Vr("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),Vr("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),Vr("\\injlim","\\DOTSB\\operatorname*{inj\\,lim}"),Vr("\\projlim","\\DOTSB\\operatorname*{proj\\,lim}"),Vr("\\varlimsup","\\DOTSB\\operatorname*{\\overline{lim}}"),Vr("\\varliminf","\\DOTSB\\operatorname*{\\underline{lim}}"),Vr("\\varinjlim","\\DOTSB\\operatorname*{\\underrightarrow{lim}}"),Vr("\\varprojlim","\\DOTSB\\operatorname*{\\underleftarrow{lim}}"),Vr("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),Vr("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),Vr("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),Vr("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),Vr("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),Vr("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),Vr("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),Vr("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),Vr("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),Vr("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),Vr("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),Vr("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),Vr("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),Vr("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),Vr("\\imath","\\html@mathml{\\@imath}{\u0131}"),Vr("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),Vr("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),Vr("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),Vr("\u27e6","\\llbracket"),Vr("\u27e7","\\rrbracket"),Vr("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),Vr("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),Vr("\u2983","\\lBrace"),Vr("\u2984","\\rBrace"),Vr("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),Vr("\u29b5","\\minuso"),Vr("\\darr","\\downarrow"),Vr("\\dArr","\\Downarrow"),Vr("\\Darr","\\Downarrow"),Vr("\\lang","\\langle"),Vr("\\rang","\\rangle"),Vr("\\uarr","\\uparrow"),Vr("\\uArr","\\Uparrow"),Vr("\\Uarr","\\Uparrow"),Vr("\\N","\\mathbb{N}"),Vr("\\R","\\mathbb{R}"),Vr("\\Z","\\mathbb{Z}"),Vr("\\alef","\\aleph"),Vr("\\alefsym","\\aleph"),Vr("\\Alpha","\\mathrm{A}"),Vr("\\Beta","\\mathrm{B}"),Vr("\\bull","\\bullet"),Vr("\\Chi","\\mathrm{X}"),Vr("\\clubs","\\clubsuit"),Vr("\\cnums","\\mathbb{C}"),Vr("\\Complex","\\mathbb{C}"),Vr("\\Dagger","\\ddagger"),Vr("\\diamonds","\\diamondsuit"),Vr("\\empty","\\emptyset"),Vr("\\Epsilon","\\mathrm{E}"),Vr("\\Eta","\\mathrm{H}"),Vr("\\exist","\\exists"),Vr("\\harr","\\leftrightarrow"),Vr("\\hArr","\\Leftrightarrow"),Vr("\\Harr","\\Leftrightarrow"),Vr("\\hearts","\\heartsuit"),Vr("\\image","\\Im"),Vr("\\infin","\\infty"),Vr("\\Iota","\\mathrm{I}"),Vr("\\isin","\\in"),Vr("\\Kappa","\\mathrm{K}"),Vr("\\larr","\\leftarrow"),Vr("\\lArr","\\Leftarrow"),Vr("\\Larr","\\Leftarrow"),Vr("\\lrarr","\\leftrightarrow"),Vr("\\lrArr","\\Leftrightarrow"),Vr("\\Lrarr","\\Leftrightarrow"),Vr("\\Mu","\\mathrm{M}"),Vr("\\natnums","\\mathbb{N}"),Vr("\\Nu","\\mathrm{N}"),Vr("\\Omicron","\\mathrm{O}"),Vr("\\plusmn","\\pm"),Vr("\\rarr","\\rightarrow"),Vr("\\rArr","\\Rightarrow"),Vr("\\Rarr","\\Rightarrow"),Vr("\\real","\\Re"),Vr("\\reals","\\mathbb{R}"),Vr("\\Reals","\\mathbb{R}"),Vr("\\Rho","\\mathrm{P}"),Vr("\\sdot","\\cdot"),Vr("\\sect","\\S"),Vr("\\spades","\\spadesuit"),Vr("\\sub","\\subset"),Vr("\\sube","\\subseteq"),Vr("\\supe","\\supseteq"),Vr("\\Tau","\\mathrm{T}"),Vr("\\thetasym","\\vartheta"),Vr("\\weierp","\\wp"),Vr("\\Zeta","\\mathrm{Z}"),Vr("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),Vr("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),Vr("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),Vr("\\bra","\\mathinner{\\langle{#1}|}"),Vr("\\ket","\\mathinner{|{#1}\\rangle}"),Vr("\\braket","\\mathinner{\\langle{#1}\\rangle}"),Vr("\\Bra","\\left\\langle#1\\right|"),Vr("\\Ket","\\left|#1\\right\\rangle");var Pa=e=>t=>{var r=t.consumeArg().tokens,a=t.consumeArg().tokens,n=t.consumeArg().tokens,i=t.consumeArg().tokens,o=t.macros.get("|"),s=t.macros.get("\\|");t.macros.beginGroup();var l=t=>r=>{e&&(r.macros.set("|",o),n.length&&r.macros.set("\\|",s));var i=t;!t&&n.length&&("|"===r.future().text&&(r.popToken(),i=!0));return{tokens:i?n:a,numArgs:0}};t.macros.set("|",l(!1)),n.length&&t.macros.set("\\|",l(!0));var h=t.consumeArg().tokens,m=t.expandTokens([...i,...h,...r]);return t.macros.endGroup(),{tokens:m.reverse(),numArgs:0}};Vr("\\bra@ket",Pa(!1)),Vr("\\bra@set",Pa(!0)),Vr("\\Braket","\\bra@ket{\\left\\langle}{\\,\\middle\\vert\\,}{\\,\\middle\\vert\\,}{\\right\\rangle}"),Vr("\\Set","\\bra@set{\\left\\{\\:}{\\;\\middle\\vert\\;}{\\;\\middle\\Vert\\;}{\\:\\right\\}}"),Vr("\\set","\\bra@set{\\{\\,}{\\mid}{}{\\,\\}}"),Vr("\\angln","{\\angl n}"),Vr("\\blue","\\textcolor{##6495ed}{#1}"),Vr("\\orange","\\textcolor{##ffa500}{#1}"),Vr("\\pink","\\textcolor{##ff00af}{#1}"),Vr("\\red","\\textcolor{##df0030}{#1}"),Vr("\\green","\\textcolor{##28ae7b}{#1}"),Vr("\\gray","\\textcolor{gray}{#1}"),Vr("\\purple","\\textcolor{##9d38bd}{#1}"),Vr("\\blueA","\\textcolor{##ccfaff}{#1}"),Vr("\\blueB","\\textcolor{##80f6ff}{#1}"),Vr("\\blueC","\\textcolor{##63d9ea}{#1}"),Vr("\\blueD","\\textcolor{##11accd}{#1}"),Vr("\\blueE","\\textcolor{##0c7f99}{#1}"),Vr("\\tealA","\\textcolor{##94fff5}{#1}"),Vr("\\tealB","\\textcolor{##26edd5}{#1}"),Vr("\\tealC","\\textcolor{##01d1c1}{#1}"),Vr("\\tealD","\\textcolor{##01a995}{#1}"),Vr("\\tealE","\\textcolor{##208170}{#1}"),Vr("\\greenA","\\textcolor{##b6ffb0}{#1}"),Vr("\\greenB","\\textcolor{##8af281}{#1}"),Vr("\\greenC","\\textcolor{##74cf70}{#1}"),Vr("\\greenD","\\textcolor{##1fab54}{#1}"),Vr("\\greenE","\\textcolor{##0d923f}{#1}"),Vr("\\goldA","\\textcolor{##ffd0a9}{#1}"),Vr("\\goldB","\\textcolor{##ffbb71}{#1}"),Vr("\\goldC","\\textcolor{##ff9c39}{#1}"),Vr("\\goldD","\\textcolor{##e07d10}{#1}"),Vr("\\goldE","\\textcolor{##a75a05}{#1}"),Vr("\\redA","\\textcolor{##fca9a9}{#1}"),Vr("\\redB","\\textcolor{##ff8482}{#1}"),Vr("\\redC","\\textcolor{##f9685d}{#1}"),Vr("\\redD","\\textcolor{##e84d39}{#1}"),Vr("\\redE","\\textcolor{##bc2612}{#1}"),Vr("\\maroonA","\\textcolor{##ffbde0}{#1}"),Vr("\\maroonB","\\textcolor{##ff92c6}{#1}"),Vr("\\maroonC","\\textcolor{##ed5fa6}{#1}"),Vr("\\maroonD","\\textcolor{##ca337c}{#1}"),Vr("\\maroonE","\\textcolor{##9e034e}{#1}"),Vr("\\purpleA","\\textcolor{##ddd7ff}{#1}"),Vr("\\purpleB","\\textcolor{##c6b9fc}{#1}"),Vr("\\purpleC","\\textcolor{##aa87ff}{#1}"),Vr("\\purpleD","\\textcolor{##7854ab}{#1}"),Vr("\\purpleE","\\textcolor{##543b78}{#1}"),Vr("\\mintA","\\textcolor{##f5f9e8}{#1}"),Vr("\\mintB","\\textcolor{##edf2df}{#1}"),Vr("\\mintC","\\textcolor{##e0e5cc}{#1}"),Vr("\\grayA","\\textcolor{##f6f7f7}{#1}"),Vr("\\grayB","\\textcolor{##f0f1f2}{#1}"),Vr("\\grayC","\\textcolor{##e3e5e6}{#1}"),Vr("\\grayD","\\textcolor{##d6d8da}{#1}"),Vr("\\grayE","\\textcolor{##babec2}{#1}"),Vr("\\grayF","\\textcolor{##888d93}{#1}"),Vr("\\grayG","\\textcolor{##626569}{#1}"),Vr("\\grayH","\\textcolor{##3b3e40}{#1}"),Vr("\\grayI","\\textcolor{##21242c}{#1}"),Vr("\\kaBlue","\\textcolor{##314453}{#1}"),Vr("\\kaGreen","\\textcolor{##71B307}{#1}");var Fa={"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0};class Ga{constructor(e,t,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=t,this.expansionCount=0,this.feed(e),this.macros=new Ra(Ha,t.macros),this.mode=r,this.stack=[]}feed(e){this.lexer=new Ia(e,this.settings)}switchMode(e){this.mode=e}beginGroup(){this.macros.beginGroup()}endGroup(){this.macros.endGroup()}endGroups(){this.macros.endGroups()}future(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]}popToken(){return this.future(),this.stack.pop()}pushToken(e){this.stack.push(e)}pushTokens(e){this.stack.push(...e)}scanArgument(e){var t,r,a;if(e){if(this.consumeSpaces(),"["!==this.future().text)return null;t=this.popToken(),({tokens:a,end:r}=this.consumeArg(["]"]))}else({tokens:a,start:t,end:r}=this.consumeArg());return this.pushToken(new n("EOF",r.loc)),this.pushTokens(a),t.range(r,"")}consumeSpaces(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}}consumeArg(e){var t=[],r=e&&e.length>0;r||this.consumeSpaces();var a,n=this.future(),o=0,s=0;do{if(a=this.popToken(),t.push(a),"{"===a.text)++o;else if("}"===a.text){if(-1===--o)throw new i("Extra }",a)}else if("EOF"===a.text)throw new i("Unexpected end of input in a macro argument, expected '"+(e&&r?e[s]:"}")+"'",a);if(e&&r)if((0===o||1===o&&"{"===e[s])&&a.text===e[s]){if(++s===e.length){t.splice(-s,s);break}}else s=0}while(0!==o||r);return"{"===n.text&&"}"===t[t.length-1].text&&(t.pop(),t.shift()),t.reverse(),{tokens:t,start:n,end:a}}consumeArgs(e,t){if(t){if(t.length!==e+1)throw new i("The length of delimiters doesn't match the number of args!");for(var r=t[0],a=0;athis.settings.maxExpand)throw new i("Too many expansions: infinite loop or need to increase maxExpand setting")}expandOnce(e){var t=this.popToken(),r=t.text,a=t.noexpand?null:this._getExpansion(r);if(null==a||e&&a.unexpandable){if(e&&null==a&&"\\"===r[0]&&!this.isDefined(r))throw new i("Undefined control sequence: "+r);return this.pushToken(t),!1}this.countExpansion(1);var n=a.tokens,o=this.consumeArgs(a.numArgs,a.delimiters);if(a.numArgs)for(var s=(n=n.slice()).length-1;s>=0;--s){var l=n[s];if("#"===l.text){if(0===s)throw new i("Incomplete placeholder at end of macro body",l);if("#"===(l=n[--s]).text)n.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new i("Not a valid argument number",l);n.splice(s,2,...o[+l.text-1])}}}return this.pushTokens(n),n.length}expandAfterFuture(){return this.expandOnce(),this.future()}expandNextToken(){for(;;)if(!1===this.expandOnce()){var e=this.stack.pop();return e.treatAsRelax&&(e.text="\\relax"),e}throw new Error}expandMacro(e){return this.macros.has(e)?this.expandTokens([new n(e)]):void 0}expandTokens(e){var t=[],r=this.stack.length;for(this.pushTokens(e);this.stack.length>r;)if(!1===this.expandOnce(!0)){var a=this.stack.pop();a.treatAsRelax&&(a.noexpand=!1,a.treatAsRelax=!1),t.push(a)}return this.countExpansion(t.length),t}expandMacroAsText(e){var t=this.expandMacro(e);return t?t.map((e=>e.text)).join(""):t}_getExpansion(e){var t=this.macros.get(e);if(null==t)return t;if(1===e.length){var r=this.lexer.catcodes[e];if(null!=r&&13!==r)return}var a="function"==typeof t?t(this):t;if("string"==typeof a){var n=0;if(-1!==a.indexOf("#"))for(var i=a.replace(/##/g,"");-1!==i.indexOf("#"+(n+1));)++n;for(var o=new Ia(a,this.settings),s=[],l=o.lex();"EOF"!==l.text;)s.push(l),l=o.lex();return s.reverse(),{tokens:s,numArgs:n}}return a}isDefined(e){return this.macros.has(e)||Aa.hasOwnProperty(e)||ne.math.hasOwnProperty(e)||ne.text.hasOwnProperty(e)||Fa.hasOwnProperty(e)}isExpandable(e){var t=this.macros.get(e);return null!=t?"string"==typeof t||"function"==typeof t||!t.unexpandable:Aa.hasOwnProperty(e)&&!Aa[e].primitive}}var Ua=/^[\u208a\u208b\u208c\u208d\u208e\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089\u2090\u2091\u2095\u1d62\u2c7c\u2096\u2097\u2098\u2099\u2092\u209a\u1d63\u209b\u209c\u1d64\u1d65\u2093\u1d66\u1d67\u1d68\u1d69\u1d6a]/,Ya=Object.freeze({"\u208a":"+","\u208b":"-","\u208c":"=","\u208d":"(","\u208e":")","\u2080":"0","\u2081":"1","\u2082":"2","\u2083":"3","\u2084":"4","\u2085":"5","\u2086":"6","\u2087":"7","\u2088":"8","\u2089":"9","\u2090":"a","\u2091":"e","\u2095":"h","\u1d62":"i","\u2c7c":"j","\u2096":"k","\u2097":"l","\u2098":"m","\u2099":"n","\u2092":"o","\u209a":"p","\u1d63":"r","\u209b":"s","\u209c":"t","\u1d64":"u","\u1d65":"v","\u2093":"x","\u1d66":"\u03b2","\u1d67":"\u03b3","\u1d68":"\u03c1","\u1d69":"\u03d5","\u1d6a":"\u03c7","\u207a":"+","\u207b":"-","\u207c":"=","\u207d":"(","\u207e":")","\u2070":"0","\xb9":"1","\xb2":"2","\xb3":"3","\u2074":"4","\u2075":"5","\u2076":"6","\u2077":"7","\u2078":"8","\u2079":"9","\u1d2c":"A","\u1d2e":"B","\u1d30":"D","\u1d31":"E","\u1d33":"G","\u1d34":"H","\u1d35":"I","\u1d36":"J","\u1d37":"K","\u1d38":"L","\u1d39":"M","\u1d3a":"N","\u1d3c":"O","\u1d3e":"P","\u1d3f":"R","\u1d40":"T","\u1d41":"U","\u2c7d":"V","\u1d42":"W","\u1d43":"a","\u1d47":"b","\u1d9c":"c","\u1d48":"d","\u1d49":"e","\u1da0":"f","\u1d4d":"g","\u02b0":"h","\u2071":"i","\u02b2":"j","\u1d4f":"k","\u02e1":"l","\u1d50":"m","\u207f":"n","\u1d52":"o","\u1d56":"p","\u02b3":"r","\u02e2":"s","\u1d57":"t","\u1d58":"u","\u1d5b":"v","\u02b7":"w","\u02e3":"x","\u02b8":"y","\u1dbb":"z","\u1d5d":"\u03b2","\u1d5e":"\u03b3","\u1d5f":"\u03b4","\u1d60":"\u03d5","\u1d61":"\u03c7","\u1dbf":"\u03b8"}),Xa={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"},"\u0327":{text:"\\c"}},Wa={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u1e09":"c\u0327\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\xe7":"c\u0327","\u010f":"d\u030c","\u1e0b":"d\u0307","\u1e11":"d\u0327","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u1e1d":"e\u0327\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u0229":"e\u0327","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u0123":"g\u0327","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\u1e29":"h\u0327","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u0137":"k\u0327","\u013a":"l\u0301","\u013e":"l\u030c","\u013c":"l\u0327","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\u0146":"n\u0327","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u0157":"r\u0327","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u015f":"s\u0327","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\u0163":"t\u0327","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u1e08":"C\u0327\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\xc7":"C\u0327","\u010e":"D\u030c","\u1e0a":"D\u0307","\u1e10":"D\u0327","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u1e1c":"E\u0327\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u0228":"E\u0327","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u0122":"G\u0327","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\u1e28":"H\u0327","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0136":"K\u0327","\u0139":"L\u0301","\u013d":"L\u030c","\u013b":"L\u0327","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\u0145":"N\u0327","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u0156":"R\u0327","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u015e":"S\u0327","\u0164":"T\u030c","\u1e6a":"T\u0307","\u0162":"T\u0327","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"};class _a{constructor(e,t){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new Ga(e,t,this.mode),this.settings=t,this.leftrightDepth=0}expect(e,t){if(void 0===t&&(t=!0),this.fetch().text!==e)throw new i("Expected '"+e+"', got '"+this.fetch().text+"'",this.fetch());t&&this.consume()}consume(){this.nextToken=null}fetch(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken}switchMode(e){this.mode=e,this.gullet.switchMode(e)}parse(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");try{var e=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),e}finally{this.gullet.endGroups()}}subparse(e){var t=this.nextToken;this.consume(),this.gullet.pushToken(new n("}")),this.gullet.pushTokens(e);var r=this.parseExpression(!1);return this.expect("}"),this.nextToken=t,r}parseExpression(e,t){for(var r=[];;){"math"===this.mode&&this.consumeSpaces();var a=this.fetch();if(-1!==_a.endOfExpression.indexOf(a.text))break;if(t&&a.text===t)break;if(e&&Aa[a.text]&&Aa[a.text].infix)break;var n=this.parseAtom(t);if(!n)break;"internal"!==n.type&&r.push(n)}return"text"===this.mode&&this.formLigatures(r),this.handleInfixNodes(r)}handleInfixNodes(e){for(var t,r=-1,a=0;a=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+t[0]+'" used in math mode',e);var l,h=ne[this.mode][t].group,m=a.range(e);if(re.hasOwnProperty(h)){var c=h;l={type:"atom",mode:this.mode,family:c,loc:m,text:t}}else l={type:h,mode:this.mode,loc:m,text:t};o=l}else{if(!(t.charCodeAt(0)>=128))return null;this.settings.strict&&(z(t.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+t[0]+'" used in math mode',e):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+t[0]+'" ('+t.charCodeAt(0)+")",e)),o={type:"textord",mode:"text",loc:a.range(e),text:t}}if(this.consume(),s)for(var p=0;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-0.6/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/examples/emojivoto.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.6/examples/"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.6/deployment"}}');var i=n(74848),s=n(28453);const a={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Downloading the deployment",id:"downloading-the-deployment",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(69314).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"downloading-the-deployment",children:"Downloading the deployment"}),"\n",(0,i.jsx)(t.p,{children:"The emojivoto deployment files are part of a zip file in the Contrast release. You can download the\nlatest deployment by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/latest/download/emojivoto-demo.zip\n"})}),"\n",(0,i.jsxs)(t.p,{children:["After that, unzip the ",(0,i.jsx)(t.code,{children:"emojivoto-demo.zip"})," file to extract the ",(0,i.jsx)(t.code,{children:"deployment/"})," directory."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"unzip emojivoto-demo.zip\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,i.jsxs)(t.p,{children:["Contrast depends on a ",(0,i.jsxs)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:["custom Kubernetes ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," (",(0,i.jsx)(t.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,i.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate deployment/\n"})}),"\n",(0,i.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,i.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,i.jsx)(t.code,{children:"contrast-cc-"}),"\nwas added to the pods to signal they should be run as Confidential Containers. In addition, the Contrast\n",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-initializer",children:"Initializer"})," was added as an init container to these workloads to\nfacilitate the attestation and certificate pulling before the actual workload is started."]}),(0,i.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the embedded reference values to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, we're ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using embedded reference values. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},69314:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2247.7219b8c6.js b/pr-preview/pr-976/assets/js/2247.7219b8c6.js new file mode 100644 index 0000000000..f529e08799 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2247.7219b8c6.js @@ -0,0 +1 @@ +(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2247],{26527:function(t,e,i){var r;r=function(t){return(()=>{"use strict";var e={658:t=>{t.exports=null!=Object.assign?Object.assign.bind(Object):function(t){for(var e=arguments.length,i=Array(e>1?e-1:0),r=1;r{var r=function(t,e){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return function(t,e){var i=[],r=!0,n=!1,o=void 0;try{for(var s,a=t[Symbol.iterator]();!(r=(s=a.next()).done)&&(i.push(s.value),!e||i.length!==e);r=!0);}catch(h){n=!0,o=h}finally{try{!r&&a.return&&a.return()}finally{if(n)throw o}}return i}(t,e);throw new TypeError("Invalid attempt to destructure non-iterable instance")},n=i(140).layoutBase.LinkedList,o={getTopMostNodes:function(t){for(var e={},i=0;i0&&l.merge(t)}));for(var c=0;c1){l=a[0],c=l.connectedEdges().length,a.forEach((function(t){t.connectedEdges().length0&&r.set("dummy"+(r.size+1),u),p},relocateComponent:function(t,e,i){if(!i.fixedNodeConstraint){var n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,a=Number.NEGATIVE_INFINITY;if("draft"==i.quality){var h=!0,l=!1,c=void 0;try{for(var d,g=e.nodeIndexes[Symbol.iterator]();!(h=(d=g.next()).done);h=!0){var u=d.value,p=r(u,2),f=p[0],v=p[1],y=i.cy.getElementById(f);if(y){var m=y.boundingBox(),E=e.xCoords[v]-m.w/2,N=e.xCoords[v]+m.w/2,T=e.yCoords[v]-m.h/2,A=e.yCoords[v]+m.h/2;Eo&&(o=N),Ta&&(a=A)}}}catch(C){l=!0,c=C}finally{try{!h&&g.return&&g.return()}finally{if(l)throw c}}var w=t.x-(o+n)/2,L=t.y-(a+s)/2;e.xCoords=e.xCoords.map((function(t){return t+w})),e.yCoords=e.yCoords.map((function(t){return t+L}))}else{Object.keys(e).forEach((function(t){var i=e[t],r=i.getRect().x,h=i.getRect().x+i.getRect().width,l=i.getRect().y,c=i.getRect().y+i.getRect().height;ro&&(o=h),la&&(a=c)}));var I=t.x-(o+n)/2,_=t.y-(a+s)/2;Object.keys(e).forEach((function(t){var i=e[t];i.setCenter(i.getCenterX()+I,i.getCenterY()+_)}))}}},calcBoundingBox:function(t,e,i,r){for(var n=Number.MAX_SAFE_INTEGER,o=Number.MIN_SAFE_INTEGER,s=Number.MAX_SAFE_INTEGER,a=Number.MIN_SAFE_INTEGER,h=void 0,l=void 0,c=void 0,d=void 0,g=t.descendants().not(":parent"),u=g.length,p=0;p(h=e[r.get(f.id())]-f.width()/2)&&(n=h),o<(l=e[r.get(f.id())]+f.width()/2)&&(o=l),s>(c=i[r.get(f.id())]-f.height()/2)&&(s=c),a<(d=i[r.get(f.id())]+f.height()/2)&&(a=d)}var v={};return v.topLeftX=n,v.topLeftY=s,v.width=o-n,v.height=a-s,v},calcParentsWithoutChildren:function(t,e){var i=t.collection();return e.nodes(":parent").forEach((function(t){var e=!1;t.children().forEach((function(t){"none"!=t.css("display")&&(e=!0)})),e||i.merge(t)})),i}};t.exports=o},816:(t,e,i)=>{var r=i(548),n=i(140).CoSELayout,o=i(140).CoSENode,s=i(140).layoutBase.PointD,a=i(140).layoutBase.DimensionD,h=i(140).layoutBase.LayoutConstants,l=i(140).layoutBase.FDLayoutConstants,c=i(140).CoSEConstants;t.exports={coseLayout:function(t,e){var i=t.cy,d=t.eles,g=d.nodes(),u=d.edges(),p=void 0,f=void 0,v=void 0,y={};t.randomize&&(p=e.nodeIndexes,f=e.xCoords,v=e.yCoords);var m=function(t){return"function"==typeof t},E=function(t,e){return m(t)?t(e):t},N=r.calcParentsWithoutChildren(i,d);null!=t.nestingFactor&&(c.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=l.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=t.nestingFactor),null!=t.gravity&&(c.DEFAULT_GRAVITY_STRENGTH=l.DEFAULT_GRAVITY_STRENGTH=t.gravity),null!=t.numIter&&(c.MAX_ITERATIONS=l.MAX_ITERATIONS=t.numIter),null!=t.gravityRange&&(c.DEFAULT_GRAVITY_RANGE_FACTOR=l.DEFAULT_GRAVITY_RANGE_FACTOR=t.gravityRange),null!=t.gravityCompound&&(c.DEFAULT_COMPOUND_GRAVITY_STRENGTH=l.DEFAULT_COMPOUND_GRAVITY_STRENGTH=t.gravityCompound),null!=t.gravityRangeCompound&&(c.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=t.gravityRangeCompound),null!=t.initialEnergyOnIncremental&&(c.DEFAULT_COOLING_FACTOR_INCREMENTAL=l.DEFAULT_COOLING_FACTOR_INCREMENTAL=t.initialEnergyOnIncremental),null!=t.tilingCompareBy&&(c.TILING_COMPARE_BY=t.tilingCompareBy),"proof"==t.quality?h.QUALITY=2:h.QUALITY=0,c.NODE_DIMENSIONS_INCLUDE_LABELS=l.NODE_DIMENSIONS_INCLUDE_LABELS=h.NODE_DIMENSIONS_INCLUDE_LABELS=t.nodeDimensionsIncludeLabels,c.DEFAULT_INCREMENTAL=l.DEFAULT_INCREMENTAL=h.DEFAULT_INCREMENTAL=!t.randomize,c.ANIMATE=l.ANIMATE=h.ANIMATE=t.animate,c.TILE=t.tile,c.TILING_PADDING_VERTICAL="function"==typeof t.tilingPaddingVertical?t.tilingPaddingVertical.call():t.tilingPaddingVertical,c.TILING_PADDING_HORIZONTAL="function"==typeof t.tilingPaddingHorizontal?t.tilingPaddingHorizontal.call():t.tilingPaddingHorizontal,c.DEFAULT_INCREMENTAL=l.DEFAULT_INCREMENTAL=h.DEFAULT_INCREMENTAL=!0,c.PURE_INCREMENTAL=!t.randomize,h.DEFAULT_UNIFORM_LEAF_NODE_SIZES=t.uniformNodeDimensions,"transformed"==t.step&&(c.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,c.ENFORCE_CONSTRAINTS=!1,c.APPLY_LAYOUT=!1),"enforced"==t.step&&(c.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,c.ENFORCE_CONSTRAINTS=!0,c.APPLY_LAYOUT=!1),"cose"==t.step&&(c.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,c.ENFORCE_CONSTRAINTS=!1,c.APPLY_LAYOUT=!0),"all"==t.step&&(t.randomize?c.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:c.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,c.ENFORCE_CONSTRAINTS=!0,c.APPLY_LAYOUT=!0),t.fixedNodeConstraint||t.alignmentConstraint||t.relativePlacementConstraint?c.TREE_REDUCTION_ON_INCREMENTAL=!1:c.TREE_REDUCTION_ON_INCREMENTAL=!0;var T=new n,A=T.newGraphManager();return function t(e,i,n,h){for(var l=i.length,c=0;c0&&t(n.getGraphManager().add(n.newGraph(),u),g,n,h)}}(A.addRoot(),r.getTopMostNodes(g),T,t),function(e,i,r){for(var n=0,o=0,s=0;s0?c.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=n/o:m(t.idealEdgeLength)?c.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=50:c.DEFAULT_EDGE_LENGTH=l.DEFAULT_EDGE_LENGTH=t.idealEdgeLength,c.MIN_REPULSION_DIST=l.MIN_REPULSION_DIST=l.DEFAULT_EDGE_LENGTH/10,c.DEFAULT_RADIAL_SEPARATION=l.DEFAULT_EDGE_LENGTH)}(T,A,u),function(t,e){e.fixedNodeConstraint&&(t.constraints.fixedNodeConstraint=e.fixedNodeConstraint),e.alignmentConstraint&&(t.constraints.alignmentConstraint=e.alignmentConstraint),e.relativePlacementConstraint&&(t.constraints.relativePlacementConstraint=e.relativePlacementConstraint)}(T,t),T.runLayout(),y}}},212:(t,e,i)=>{var r=function(){function t(t,e){for(var i=0;i0)if(d){var g=o.getTopMostNodes(t.eles.nodes());if((h=o.connectComponents(e,t.eles,g)).forEach((function(t){var e=t.boundingBox();l.push({x:e.x1+e.w/2,y:e.y1+e.h/2})})),t.randomize&&h.forEach((function(e){t.eles=e,r.push(s(t))})),"default"==t.quality||"proof"==t.quality){var u=e.collection();if(t.tile){var p=new Map,f=0,v={nodeIndexes:p,xCoords:[],yCoords:[]},y=[];if(h.forEach((function(t,e){0==t.edges().length&&(t.nodes().forEach((function(e,i){u.merge(t.nodes()[i]),e.isParent()||(v.nodeIndexes.set(t.nodes()[i].id(),f++),v.xCoords.push(t.nodes()[0].position().x),v.yCoords.push(t.nodes()[0].position().y))})),y.push(e))})),u.length>1){var m=u.boundingBox();l.push({x:m.x1+m.w/2,y:m.y1+m.h/2}),h.push(u),r.push(v);for(var E=y.length-1;E>=0;E--)h.splice(y[E],1),r.splice(y[E],1),l.splice(y[E],1)}}h.forEach((function(e,i){t.eles=e,n.push(a(t,r[i])),o.relocateComponent(l[i],n[i],t)}))}else h.forEach((function(e,i){o.relocateComponent(l[i],r[i],t)}));var N=new Set;if(h.length>1){var T=[],A=i.filter((function(t){return"none"==t.css("display")}));h.forEach((function(e,i){var s=void 0;if("draft"==t.quality&&(s=r[i].nodeIndexes),e.nodes().not(A).length>0){var a={edges:[],nodes:[]},h=void 0;e.nodes().not(A).forEach((function(e){if("draft"==t.quality)if(e.isParent()){var l=o.calcBoundingBox(e,r[i].xCoords,r[i].yCoords,s);a.nodes.push({x:l.topLeftX,y:l.topLeftY,width:l.width,height:l.height})}else h=s.get(e.id()),a.nodes.push({x:r[i].xCoords[h]-e.boundingbox().w/2,y:r[i].yCoords[h]-e.boundingbox().h/2,width:e.boundingbox().w,height:e.boundingbox().h});else n[i][e.id()]&&a.nodes.push({x:n[i][e.id()].getLeft(),y:n[i][e.id()].getTop(),width:n[i][e.id()].getWidth(),height:n[i][e.id()].getHeight()})})),e.edges().forEach((function(e){var h=e.source(),l=e.target();if("none"!=h.css("display")&&"none"!=l.css("display"))if("draft"==t.quality){var c=s.get(h.id()),d=s.get(l.id()),g=[],u=[];if(h.isParent()){var p=o.calcBoundingBox(h,r[i].xCoords,r[i].yCoords,s);g.push(p.topLeftX+p.width/2),g.push(p.topLeftY+p.height/2)}else g.push(r[i].xCoords[c]),g.push(r[i].yCoords[c]);if(l.isParent()){var f=o.calcBoundingBox(l,r[i].xCoords,r[i].yCoords,s);u.push(f.topLeftX+f.width/2),u.push(f.topLeftY+f.height/2)}else u.push(r[i].xCoords[d]),u.push(r[i].yCoords[d]);a.edges.push({startX:g[0],startY:g[1],endX:u[0],endY:u[1]})}else n[i][h.id()]&&n[i][l.id()]&&a.edges.push({startX:n[i][h.id()].getCenterX(),startY:n[i][h.id()].getCenterY(),endX:n[i][l.id()].getCenterX(),endY:n[i][l.id()].getCenterY()})})),a.nodes.length>0&&(T.push(a),N.add(i))}}));var w=c.packComponents(T,t.randomize).shifts;if("draft"==t.quality)r.forEach((function(t,e){var i=t.xCoords.map((function(t){return t+w[e].dx})),r=t.yCoords.map((function(t){return t+w[e].dy}));t.xCoords=i,t.yCoords=r}));else{var L=0;N.forEach((function(t){Object.keys(n[t]).forEach((function(e){var i=n[t][e];i.setCenter(i.getCenterX()+w[L].dx,i.getCenterY()+w[L].dy)})),L++}))}}}else{var I=t.eles.boundingBox();if(l.push({x:I.x1+I.w/2,y:I.y1+I.h/2}),t.randomize){var _=s(t);r.push(_)}"default"==t.quality||"proof"==t.quality?(n.push(a(t,r[0])),o.relocateComponent(l[0],n[0],t)):o.relocateComponent(l[0],r[0],t)}var C=function(e,i){if("default"==t.quality||"proof"==t.quality){"number"==typeof e&&(e=i);var o=void 0,s=void 0,a=e.data("id");return n.forEach((function(t){a in t&&(o={x:t[a].getRect().getCenterX(),y:t[a].getRect().getCenterY()},s=t[a])})),t.nodeDimensionsIncludeLabels&&(s.labelWidth&&("left"==s.labelPosHorizontal?o.x+=s.labelWidth/2:"right"==s.labelPosHorizontal&&(o.x-=s.labelWidth/2)),s.labelHeight&&("top"==s.labelPosVertical?o.y+=s.labelHeight/2:"bottom"==s.labelPosVertical&&(o.y-=s.labelHeight/2))),null==o&&(o={x:e.position("x"),y:e.position("y")}),{x:o.x,y:o.y}}var h=void 0;return r.forEach((function(t){var i=t.nodeIndexes.get(e.id());null!=i&&(h={x:t.xCoords[i],y:t.yCoords[i]})})),null==h&&(h={x:e.position("x"),y:e.position("y")}),{x:h.x,y:h.y}};if("default"==t.quality||"proof"==t.quality||t.randomize){var M=o.calcParentsWithoutChildren(e,i),x=i.filter((function(t){return"none"==t.css("display")}));t.eles=i.not(x),i.nodes().not(":parent").not(x).layoutPositions(this,t,C),M.length>0&&M.forEach((function(t){t.position(C(t))}))}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")}}]),t}();t.exports=l},657:(t,e,i)=>{var r=i(548),n=i(140).layoutBase.Matrix,o=i(140).layoutBase.SVD;t.exports={spectralLayout:function(t){var e=t.cy,i=t.eles,s=i.nodes(),a=i.nodes(":parent"),h=new Map,l=new Map,c=new Map,d=[],g=[],u=[],p=[],f=[],v=[],y=[],m=[],E=void 0,N=1e8,T=1e-9,A=t.piTol,w=t.samplingType,L=t.nodeSeparation,I=void 0,_=function(t,e,i){for(var r=[],n=0,o=0,s=0,a=void 0,h=[],c=0,g=1,u=0;u=n;){s=r[n++];for(var p=d[s],y=0;yc&&(c=f[T],g=T)}return g};r.connectComponents(e,i,r.getTopMostNodes(s),h),a.forEach((function(t){r.connectComponents(e,i,r.getTopMostNodes(t.descendants().intersection(i)),h)}));for(var C=0,M=0;M0&&(r.isParent()?d[e].push(c.get(r.id())):d[e].push(r.id()))}))}));var S=function(t){var i=l.get(t),r=void 0;h.get(t).forEach((function(n){r=e.getElementById(n).isParent()?c.get(n):n,d[i].push(r),d[l.get(r)].push(t)}))},P=!0,U=!1,Y=void 0;try{for(var k,H=h.keys()[Symbol.iterator]();!(P=(k=H.next()).done);P=!0)S(k.value)}catch(K){U=!0,Y=K}finally{try{!P&&H.return&&H.return()}finally{if(U)throw Y}}var X=void 0;if((E=l.size)>2){I=E=1)break;l=h}for(var p=0;p=1)break;l=h}for(var y=0;y{var r=i(212),n=function(t){t&&t("layout","fcose",r)};"undefined"!=typeof cytoscape&&n(cytoscape),t.exports=n},140:e=>{e.exports=t}},i={},r=function t(r){var n=i[r];if(void 0!==n)return n.exports;var o=i[r]={exports:{}};return e[r](o,o.exports,t),o.exports}(579);return r})()},t.exports=r(i(41709))},41709:function(t,e,i){var r;r=function(t){return(()=>{"use strict";var e={45:(t,e,i)=>{var r={};r.layoutBase=i(551),r.CoSEConstants=i(806),r.CoSEEdge=i(767),r.CoSEGraph=i(880),r.CoSEGraphManager=i(578),r.CoSELayout=i(765),r.CoSENode=i(991),r.ConstraintHandler=i(902),t.exports=r},806:(t,e,i)=>{var r=i(551).FDLayoutConstants;function n(){}for(var o in r)n[o]=r[o];n.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,n.DEFAULT_RADIAL_SEPARATION=r.DEFAULT_EDGE_LENGTH,n.DEFAULT_COMPONENT_SEPERATION=60,n.TILE=!0,n.TILING_PADDING_VERTICAL=10,n.TILING_PADDING_HORIZONTAL=10,n.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,n.ENFORCE_CONSTRAINTS=!0,n.APPLY_LAYOUT=!0,n.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,n.TREE_REDUCTION_ON_INCREMENTAL=!0,n.PURE_INCREMENTAL=n.DEFAULT_INCREMENTAL,t.exports=n},767:(t,e,i)=>{var r=i(551).FDLayoutEdge;function n(t,e,i){r.call(this,t,e,i)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},880:(t,e,i)=>{var r=i(551).LGraph;function n(t,e,i){r.call(this,t,e,i)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},578:(t,e,i)=>{var r=i(551).LGraphManager;function n(t){r.call(this,t)}for(var o in n.prototype=Object.create(r.prototype),r)n[o]=r[o];t.exports=n},765:(t,e,i)=>{var r=i(551).FDLayout,n=i(578),o=i(880),s=i(991),a=i(767),h=i(806),l=i(902),c=i(551).FDLayoutConstants,d=i(551).LayoutConstants,g=i(551).Point,u=i(551).PointD,p=i(551).DimensionD,f=i(551).Layout,v=i(551).Integer,y=i(551).IGeometry,m=i(551).LGraph,E=i(551).Transform,N=i(551).LinkedList;function T(){r.call(this),this.toBeTiled={},this.constraints={}}for(var A in T.prototype=Object.create(r.prototype),r)T[A]=r[A];T.prototype.newGraphManager=function(){var t=new n(this);return this.graphManager=t,t},T.prototype.newGraph=function(t){return new o(null,this.graphManager,t)},T.prototype.newNode=function(t){return new s(this.graphManager,t)},T.prototype.newEdge=function(t){return new a(null,null,t)},T.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.isSubLayout||(h.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=h.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=c.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=c.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=c.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=c.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},T.prototype.initSpringEmbedder=function(){r.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/c.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},T.prototype.layout=function(){return d.DEFAULT_CREATE_BENDS_AS_NEEDED&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},T.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental)h.TREE_REDUCTION_ON_INCREMENTAL&&(this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation(),e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter((function(t){return e.has(t)})),this.graphManager.setAllNodesToApplyGravitation(i));else{var t=this.getFlatForest();if(t.length>0)this.positionNodesRadially(t);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(i),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(l.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),h.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},T.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%c.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),e=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(e),this.graphManager.updateBounds(),this.updateGrid(),h.PURE_INCREMENTAL?this.coolingFactor=c.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=c.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),h.PURE_INCREMENTAL?this.coolingFactor=c.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=c.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var i=!this.isTreeGrowing&&!this.isGrowthFinished,r=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(i,r),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},T.prototype.getPositionsData=function(){for(var t=this.graphManager.getAllNodes(),e={},i=0;i0&&this.updateDisplacements(),e=0;e0&&(r.fixedNodeWeight=o)}if(this.constraints.relativePlacementConstraint){var s=new Map,a=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach((function(e){t.fixedNodesOnHorizontal.add(e),t.fixedNodesOnVertical.add(e)})),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical){var l=this.constraints.alignmentConstraint.vertical;for(i=0;i=2*t.length/3;r--)e=Math.floor(Math.random()*(r+1)),i=t[r],t[r]=t[e],t[e]=i;return t},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach((function(e){if(e.left){var i=s.has(e.left)?s.get(e.left):e.left,r=s.has(e.right)?s.get(e.right):e.right;t.nodesInRelativeHorizontal.includes(i)||(t.nodesInRelativeHorizontal.push(i),t.nodeToRelativeConstraintMapHorizontal.set(i,[]),t.dummyToNodeForVerticalAlignment.has(i)?t.nodeToTempPositionMapHorizontal.set(i,t.idToNodeMap.get(t.dummyToNodeForVerticalAlignment.get(i)[0]).getCenterX()):t.nodeToTempPositionMapHorizontal.set(i,t.idToNodeMap.get(i).getCenterX())),t.nodesInRelativeHorizontal.includes(r)||(t.nodesInRelativeHorizontal.push(r),t.nodeToRelativeConstraintMapHorizontal.set(r,[]),t.dummyToNodeForVerticalAlignment.has(r)?t.nodeToTempPositionMapHorizontal.set(r,t.idToNodeMap.get(t.dummyToNodeForVerticalAlignment.get(r)[0]).getCenterX()):t.nodeToTempPositionMapHorizontal.set(r,t.idToNodeMap.get(r).getCenterX())),t.nodeToRelativeConstraintMapHorizontal.get(i).push({right:r,gap:e.gap}),t.nodeToRelativeConstraintMapHorizontal.get(r).push({left:i,gap:e.gap})}else{var n=a.has(e.top)?a.get(e.top):e.top,o=a.has(e.bottom)?a.get(e.bottom):e.bottom;t.nodesInRelativeVertical.includes(n)||(t.nodesInRelativeVertical.push(n),t.nodeToRelativeConstraintMapVertical.set(n,[]),t.dummyToNodeForHorizontalAlignment.has(n)?t.nodeToTempPositionMapVertical.set(n,t.idToNodeMap.get(t.dummyToNodeForHorizontalAlignment.get(n)[0]).getCenterY()):t.nodeToTempPositionMapVertical.set(n,t.idToNodeMap.get(n).getCenterY())),t.nodesInRelativeVertical.includes(o)||(t.nodesInRelativeVertical.push(o),t.nodeToRelativeConstraintMapVertical.set(o,[]),t.dummyToNodeForHorizontalAlignment.has(o)?t.nodeToTempPositionMapVertical.set(o,t.idToNodeMap.get(t.dummyToNodeForHorizontalAlignment.get(o)[0]).getCenterY()):t.nodeToTempPositionMapVertical.set(o,t.idToNodeMap.get(o).getCenterY())),t.nodeToRelativeConstraintMapVertical.get(n).push({bottom:o,gap:e.gap}),t.nodeToRelativeConstraintMapVertical.get(o).push({top:n,gap:e.gap})}}));else{var d=new Map,g=new Map;this.constraints.relativePlacementConstraint.forEach((function(t){if(t.left){var e=s.has(t.left)?s.get(t.left):t.left,i=s.has(t.right)?s.get(t.right):t.right;d.has(e)?d.get(e).push(i):d.set(e,[i]),d.has(i)?d.get(i).push(e):d.set(i,[e])}else{var r=a.has(t.top)?a.get(t.top):t.top,n=a.has(t.bottom)?a.get(t.bottom):t.bottom;g.has(r)?g.get(r).push(n):g.set(r,[n]),g.has(n)?g.get(n).push(r):g.set(n,[r])}}));var u=function(t,e){var i=[],r=[],n=new N,o=new Set,s=0;return t.forEach((function(a,h){if(!o.has(h)){i[s]=[],r[s]=!1;var l=h;for(n.push(l),o.add(l),i[s].push(l);0!=n.length;)l=n.shift(),e.has(l)&&(r[s]=!0),t.get(l).forEach((function(t){o.has(t)||(n.push(t),o.add(t),i[s].push(t))}));s++}})),{components:i,isFixed:r}},p=u(d,t.fixedNodesOnHorizontal);this.componentsOnHorizontal=p.components,this.fixedComponentsOnHorizontal=p.isFixed;var f=u(g,t.fixedNodesOnVertical);this.componentsOnVertical=f.components,this.fixedComponentsOnVertical=f.isFixed}}},T.prototype.updateDisplacements=function(){var t=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach((function(e){var i=t.idToNodeMap.get(e.nodeId);i.displacementX=0,i.displacementY=0})),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var e=this.constraints.alignmentConstraint.vertical,i=0;i1)for(a=0;ar&&(r=Math.floor(s.y)),o=Math.floor(s.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new u(d.WORLD_CENTER_X-s.x/2,d.WORLD_CENTER_Y-s.y/2))},T.radialLayout=function(t,e,i){var r=Math.max(this.maxDiagonalInTree(t),h.DEFAULT_RADIAL_SEPARATION);T.branchRadialLayout(e,null,0,359,0,r);var n=m.calculateBounds(t),o=new E;o.setDeviceOrgX(n.getMinX()),o.setDeviceOrgY(n.getMinY()),o.setWorldOrgX(i.x),o.setWorldOrgY(i.y);for(var s=0;s1;){var v=f[0];f.splice(0,1);var m=c.indexOf(v);m>=0&&c.splice(m,1),p--,d--}g=null!=e?(c.indexOf(f[0])+1)%p:0;for(var E=Math.abs(r-i)/d,N=g;u!=d;N=++N%p){var A=c[N].getOtherEnd(t);if(A!=e){var w=(i+u*E)%360,L=(w+E)%360;T.branchRadialLayout(A,t,w,L,n+o,o),u++}}},T.maxDiagonalInTree=function(t){for(var e=v.MIN_VALUE,i=0;ie&&(e=r)}return e},T.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},T.prototype.groupZeroDegreeMembers=function(){var t=this,e={};this.memberGroups={},this.idToDummyNode={};for(var i=[],r=this.graphManager.getAllNodes(),n=0;n1){var r="DummyCompound_"+i;t.memberGroups[r]=e[i];var n=e[i][0].getParent(),o=new s(t.graphManager);o.id=r,o.paddingLeft=n.paddingLeft||0,o.paddingRight=n.paddingRight||0,o.paddingBottom=n.paddingBottom||0,o.paddingTop=n.paddingTop||0,t.idToDummyNode[r]=o;var a=t.getGraphManager().add(t.newGraph(),o),h=n.getChild();h.add(o);for(var l=0;ln?(r.rect.x-=(r.labelWidth-n)/2,r.setWidth(r.labelWidth),r.labelMarginLeft=(r.labelWidth-n)/2):"right"==r.labelPosHorizontal&&r.setWidth(n+r.labelWidth)),r.labelHeight&&("top"==r.labelPosVertical?(r.rect.y-=r.labelHeight,r.setHeight(o+r.labelHeight),r.labelMarginTop=r.labelHeight):"center"==r.labelPosVertical&&r.labelHeight>o?(r.rect.y-=(r.labelHeight-o)/2,r.setHeight(r.labelHeight),r.labelMarginTop=(r.labelHeight-o)/2):"bottom"==r.labelPosVertical&&r.setHeight(o+r.labelHeight))}}))},T.prototype.repopulateCompounds=function(){for(var t=this.compoundOrder.length-1;t>=0;t--){var e=this.compoundOrder[t],i=e.id,r=e.paddingLeft,n=e.paddingTop,o=e.labelMarginLeft,s=e.labelMarginTop;this.adjustLocations(this.tiledMemberPack[i],e.rect.x,e.rect.y,r,n,o,s)}},T.prototype.repopulateZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack;Object.keys(e).forEach((function(i){var r=t.idToDummyNode[i],n=r.paddingLeft,o=r.paddingTop,s=r.labelMarginLeft,a=r.labelMarginTop;t.adjustLocations(e[i],r.rect.x,r.rect.y,n,o,s,a)}))},T.prototype.getToBeTiled=function(t){var e=t.id;if(null!=this.toBeTiled[e])return this.toBeTiled[e];var i=t.getChild();if(null==i)return this.toBeTiled[e]=!1,!1;for(var r=i.getNodes(),n=0;n0)return this.toBeTiled[e]=!1,!1;if(null!=o.getChild()){if(!this.getToBeTiled(o))return this.toBeTiled[e]=!1,!1}else this.toBeTiled[o.id]=!1}return this.toBeTiled[e]=!0,!0},T.prototype.getNodeDegree=function(t){t.id;for(var e=t.getEdges(),i=0,r=0;rc&&(c=g.rect.height)}i+=c+t.verticalPadding}},T.prototype.tileCompoundMembers=function(t,e){var i=this;this.tiledMemberPack=[],Object.keys(t).forEach((function(r){var n=e[r];if(i.tiledMemberPack[r]=i.tileNodes(t[r],n.paddingLeft+n.paddingRight),n.rect.width=i.tiledMemberPack[r].width,n.rect.height=i.tiledMemberPack[r].height,n.setCenter(i.tiledMemberPack[r].centerX,i.tiledMemberPack[r].centerY),n.labelMarginLeft=0,n.labelMarginTop=0,h.NODE_DIMENSIONS_INCLUDE_LABELS){var o=n.rect.width,s=n.rect.height;n.labelWidth&&("left"==n.labelPosHorizontal?(n.rect.x-=n.labelWidth,n.setWidth(o+n.labelWidth),n.labelMarginLeft=n.labelWidth):"center"==n.labelPosHorizontal&&n.labelWidth>o?(n.rect.x-=(n.labelWidth-o)/2,n.setWidth(n.labelWidth),n.labelMarginLeft=(n.labelWidth-o)/2):"right"==n.labelPosHorizontal&&n.setWidth(o+n.labelWidth)),n.labelHeight&&("top"==n.labelPosVertical?(n.rect.y-=n.labelHeight,n.setHeight(s+n.labelHeight),n.labelMarginTop=n.labelHeight):"center"==n.labelPosVertical&&n.labelHeight>s?(n.rect.y-=(n.labelHeight-s)/2,n.setHeight(n.labelHeight),n.labelMarginTop=(n.labelHeight-s)/2):"bottom"==n.labelPosVertical&&n.setHeight(s+n.labelHeight))}}))},T.prototype.tileNodes=function(t,e){var i=this.tileNodesByFavoringDim(t,e,!0),r=this.tileNodesByFavoringDim(t,e,!1),n=this.getOrgRatio(i);return this.getOrgRatio(r)a&&(a=t.getWidth())}));var l,c=o/n,d=s/n,g=Math.pow(i-r,2)+4*(c+r)*(d+i)*n,u=(r-i+Math.sqrt(g))/(2*(c+r));e?(l=Math.ceil(u))==u&&l++:l=Math.floor(u);var p=l*(c+r)-r;return a>p&&(p=a),p+=2*r},T.prototype.tileNodesByFavoringDim=function(t,e,i){var r=h.TILING_PADDING_VERTICAL,n=h.TILING_PADDING_HORIZONTAL,o=h.TILING_COMPARE_BY,s={rows:[],rowWidth:[],rowHeight:[],width:0,height:e,verticalPadding:r,horizontalPadding:n,centerX:0,centerY:0};o&&(s.idealRowWidth=this.calcIdealRowWidth(t,i));var a=function(t){return t.rect.width*t.rect.height},l=function(t,e){return a(e)-a(t)};t.sort((function(t,e){var i=l;return s.idealRowWidth?(i=o)(t.id,e.id):i(t,e)}));for(var c=0,d=0,g=0;g0&&(o+=t.horizontalPadding),t.rowWidth[i]=o,t.width0&&(s+=t.verticalPadding);var a=0;s>t.rowHeight[i]&&(a=t.rowHeight[i],t.rowHeight[i]=s,a=t.rowHeight[i]-a),t.height+=a,t.rows[i].push(e)},T.prototype.getShortestRowIndex=function(t){for(var e=-1,i=Number.MAX_VALUE,r=0;ri&&(e=r,i=t.rowWidth[r]);return e},T.prototype.canAddHorizontal=function(t,e,i){if(t.idealRowWidth){var r=t.rows.length-1;return t.rowWidth[r]+e+t.horizontalPadding<=t.idealRowWidth}var n=this.getShortestRowIndex(t);if(n<0)return!0;var o=t.rowWidth[n];if(o+t.horizontalPadding+e<=t.width)return!0;var s,a,h=0;return t.rowHeight[n]0&&(h=i+t.verticalPadding-t.rowHeight[n]),s=t.width-o>=e+t.horizontalPadding?(t.height+h)/(o+e+t.horizontalPadding):(t.height+h)/t.width,h=i+t.verticalPadding,(a=t.widtho&&e!=i){r.splice(-1,1),t.rows[i].push(n),t.rowWidth[e]=t.rowWidth[e]-o,t.rowWidth[i]=t.rowWidth[i]+o,t.width=t.rowWidth[instance.getLongestRowIndex(t)];for(var s=Number.MIN_VALUE,a=0;as&&(s=r[a].height);e>0&&(s+=t.verticalPadding);var h=t.rowHeight[e]+t.rowHeight[i];t.rowHeight[e]=s,t.rowHeight[i]0)for(var d=n;d<=o;d++)l[0]+=this.grid[d][s-1].length+this.grid[d][s].length-1;if(o0)for(d=s;d<=a;d++)l[3]+=this.grid[n-1][d].length+this.grid[n][d].length-1;for(var g,u,p=v.MAX_VALUE,f=0;f{var r=i(551).FDLayoutNode,n=i(551).IMath;function o(t,e,i,n){r.call(this,t,e,i,n)}for(var s in o.prototype=Object.create(r.prototype),r)o[s]=r[s];o.prototype.calculateDisplacement=function(){var t=this.graphManager.getLayout();null!=this.getChild()&&this.fixedNodeWeight?(this.displacementX+=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementX=t.coolingFactor*t.maxNodeDisplacement*n.sign(this.displacementX)),Math.abs(this.displacementY)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementY=t.coolingFactor*t.maxNodeDisplacement*n.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},o.prototype.propogateDisplacementToChildren=function(t,e){for(var i,r=this.getChild().getNodes(),n=0;n{function r(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e0){var o=0;r.forEach((function(t){"horizontal"==e?(d.set(t,h.has(t)?l[h.get(t)]:n.get(t)),o+=d.get(t)):(d.set(t,h.has(t)?c[h.get(t)]:n.get(t)),o+=d.get(t))})),o/=r.length,t.forEach((function(t){i.has(t)||d.set(t,o)}))}else{var s=0;t.forEach((function(t){s+="horizontal"==e?h.has(t)?l[h.get(t)]:n.get(t):h.has(t)?c[h.get(t)]:n.get(t)})),s/=t.length,t.forEach((function(t){d.set(t,s)}))}}));for(var p=function(){var r=u.shift();t.get(r).forEach((function(t){if(d.get(t.id)s&&(s=m),Ea&&(a=E)}}catch(C){u=!0,p=C}finally{try{!g&&v.return&&v.return()}finally{if(u)throw p}}var N=(r+s)/2-(o+a)/2,T=!0,A=!1,w=void 0;try{for(var L,I=t[Symbol.iterator]();!(T=(L=I.next()).done);T=!0){var _=L.value;d.set(_,d.get(_)+N)}}catch(C){A=!0,w=C}finally{try{!T&&I.return&&I.return()}finally{if(A)throw w}}}))}return d},y=function(t){var e=0,i=0,r=0,n=0;if(t.forEach((function(t){t.left?l[h.get(t.left)]-l[h.get(t.right)]>=0?e++:i++:c[h.get(t.top)]-c[h.get(t.bottom)]>=0?r++:n++})),e>i&&r>n)for(var o=0;oi)for(var s=0;sn)for(var a=0;a1)e.fixedNodeConstraint.forEach((function(t,e){T[e]=[t.position.x,t.position.y],A[e]=[l[h.get(t.nodeId)],c[h.get(t.nodeId)]]})),w=!0;else if(e.alignmentConstraint)!function(){var t=0;if(e.alignmentConstraint.vertical){for(var i=e.alignmentConstraint.vertical,n=function(e){var n=new Set;i[e].forEach((function(t){n.add(t)}));var o=new Set([].concat(r(n)).filter((function(t){return I.has(t)}))),s=void 0;s=o.size>0?l[h.get(o.values().next().value)]:f(n).x,i[e].forEach((function(e){T[t]=[s,c[h.get(e)]],A[t]=[l[h.get(e)],c[h.get(e)]],t++}))},o=0;o0?l[h.get(n.values().next().value)]:f(i).y,s[e].forEach((function(e){T[t]=[l[h.get(e)],o],A[t]=[l[h.get(e)],c[h.get(e)]],t++}))},d=0;dx&&(x=M[D].length,O=D);if(x0){var j={x:0,y:0};e.fixedNodeConstraint.forEach((function(t,e){var i,r,n={x:l[h.get(t.nodeId)],y:c[h.get(t.nodeId)]},o=t.position,s=(r=n,{x:(i=o).x-r.x,y:i.y-r.y});j.x+=s.x,j.y+=s.y})),j.x/=e.fixedNodeConstraint.length,j.y/=e.fixedNodeConstraint.length,l.forEach((function(t,e){l[e]+=j.x})),c.forEach((function(t,e){c[e]+=j.y})),e.fixedNodeConstraint.forEach((function(t){l[h.get(t.nodeId)]=t.position.x,c[h.get(t.nodeId)]=t.position.y}))}if(e.alignmentConstraint){if(e.alignmentConstraint.vertical)for(var q=e.alignmentConstraint.vertical,$=function(t){var e=new Set;q[t].forEach((function(t){e.add(t)}));var i=new Set([].concat(r(e)).filter((function(t){return I.has(t)}))),n=void 0;n=i.size>0?l[h.get(i.values().next().value)]:f(e).x,e.forEach((function(t){I.has(t)||(l[h.get(t)]=n)}))},K=0;K0?c[h.get(i.values().next().value)]:f(e).y,e.forEach((function(t){I.has(t)||(c[h.get(t)]=n)}))},J=0;J{e.exports=t}},i={},r=function t(r){var n=i[r];if(void 0!==n)return n.exports;var o=i[r]={exports:{}};return e[r](o,o.exports,t),o.exports}(45);return r})()},t.exports=r(i(1917))},1917:function(t){var e;e=function(){return function(t){var e={};function i(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return t[r].call(n.exports,n,n.exports,i),n.l=!0,n.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,r){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:r})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=28)}([function(t,e,i){"use strict";function r(){}r.QUALITY=1,r.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,r.DEFAULT_INCREMENTAL=!1,r.DEFAULT_ANIMATION_ON_LAYOUT=!0,r.DEFAULT_ANIMATION_DURING_LAYOUT=!1,r.DEFAULT_ANIMATION_PERIOD=50,r.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,r.DEFAULT_GRAPH_MARGIN=15,r.NODE_DIMENSIONS_INCLUDE_LABELS=!1,r.SIMPLE_NODE_SIZE=40,r.SIMPLE_NODE_HALF_SIZE=r.SIMPLE_NODE_SIZE/2,r.EMPTY_COMPOUND_NODE_SIZE=40,r.MIN_EDGE_LENGTH=1,r.WORLD_BOUNDARY=1e6,r.INITIAL_WORLD_BOUNDARY=r.WORLD_BOUNDARY/1e3,r.WORLD_CENTER_X=1200,r.WORLD_CENTER_Y=900,t.exports=r},function(t,e,i){"use strict";var r=i(2),n=i(8),o=i(9);function s(t,e,i){r.call(this,i),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=i,this.bendpoints=[],this.source=t,this.target=e}for(var a in s.prototype=Object.create(r.prototype),r)s[a]=r[a];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(t){if(this.source===t)return this.target;if(this.target===t)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(t,e){for(var i=this.getOtherEnd(t),r=e.getGraphManager().getRoot();;){if(i.getOwner()==e)return i;if(i.getOwner()==r)break;i=i.getOwner().getParent()}return null},s.prototype.updateLength=function(){var t=new Array(4);this.isOverlapingSourceAndTarget=n.getIntersection(this.target.getRect(),this.source.getRect(),t),this.isOverlapingSourceAndTarget||(this.lengthX=t[0]-t[2],this.lengthY=t[1]-t[3],Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,i){"use strict";t.exports=function(t){this.vGraphObject=t}},function(t,e,i){"use strict";var r=i(2),n=i(10),o=i(13),s=i(0),a=i(16),h=i(5);function l(t,e,i,s){null==i&&null==s&&(s=e),r.call(this,s),null!=t.graphManager&&(t=t.graphManager),this.estimatedSize=n.MIN_VALUE,this.inclusionTreeDepth=n.MAX_VALUE,this.vGraphObject=s,this.edges=[],this.graphManager=t,this.rect=null!=i&&null!=e?new o(e.x,e.y,i.width,i.height):new o}for(var c in l.prototype=Object.create(r.prototype),r)l[c]=r[c];l.prototype.getEdges=function(){return this.edges},l.prototype.getChild=function(){return this.child},l.prototype.getOwner=function(){return this.owner},l.prototype.getWidth=function(){return this.rect.width},l.prototype.setWidth=function(t){this.rect.width=t},l.prototype.getHeight=function(){return this.rect.height},l.prototype.setHeight=function(t){this.rect.height=t},l.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},l.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},l.prototype.getCenter=function(){return new h(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},l.prototype.getLocation=function(){return new h(this.rect.x,this.rect.y)},l.prototype.getRect=function(){return this.rect},l.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},l.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},l.prototype.setRect=function(t,e){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=e.width,this.rect.height=e.height},l.prototype.setCenter=function(t,e){this.rect.x=t-this.rect.width/2,this.rect.y=e-this.rect.height/2},l.prototype.setLocation=function(t,e){this.rect.x=t,this.rect.y=e},l.prototype.moveBy=function(t,e){this.rect.x+=t,this.rect.y+=e},l.prototype.getEdgeListToNode=function(t){var e=[],i=this;return i.edges.forEach((function(r){if(r.target==t){if(r.source!=i)throw"Incorrect edge source!";e.push(r)}})),e},l.prototype.getEdgesBetween=function(t){var e=[],i=this;return i.edges.forEach((function(r){if(r.source!=i&&r.target!=i)throw"Incorrect edge source and/or target";r.target!=t&&r.source!=t||e.push(r)})),e},l.prototype.getNeighborsList=function(){var t=new Set,e=this;return e.edges.forEach((function(i){if(i.source==e)t.add(i.target);else{if(i.target!=e)throw"Incorrect incidency!";t.add(i.source)}})),t},l.prototype.withChildren=function(){var t=new Set;if(t.add(this),null!=this.child)for(var e=this.child.getNodes(),i=0;ie?(this.rect.x-=(this.labelWidth-e)/2,this.setWidth(this.labelWidth)):"right"==this.labelPosHorizontal&&this.setWidth(e+this.labelWidth)),this.labelHeight&&("top"==this.labelPosVertical?(this.rect.y-=this.labelHeight,this.setHeight(i+this.labelHeight)):"center"==this.labelPosVertical&&this.labelHeight>i?(this.rect.y-=(this.labelHeight-i)/2,this.setHeight(this.labelHeight)):"bottom"==this.labelPosVertical&&this.setHeight(i+this.labelHeight))}}},l.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==n.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},l.prototype.transform=function(t){var e=this.rect.x;e>s.WORLD_BOUNDARY?e=s.WORLD_BOUNDARY:e<-s.WORLD_BOUNDARY&&(e=-s.WORLD_BOUNDARY);var i=this.rect.y;i>s.WORLD_BOUNDARY?i=s.WORLD_BOUNDARY:i<-s.WORLD_BOUNDARY&&(i=-s.WORLD_BOUNDARY);var r=new h(e,i),n=t.inverseTransformPoint(r);this.setLocation(n.x,n.y)},l.prototype.getLeft=function(){return this.rect.x},l.prototype.getRight=function(){return this.rect.x+this.rect.width},l.prototype.getTop=function(){return this.rect.y},l.prototype.getBottom=function(){return this.rect.y+this.rect.height},l.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},t.exports=l},function(t,e,i){"use strict";var r=i(0);function n(){}for(var o in r)n[o]=r[o];n.MAX_ITERATIONS=2500,n.DEFAULT_EDGE_LENGTH=50,n.DEFAULT_SPRING_STRENGTH=.45,n.DEFAULT_REPULSION_STRENGTH=4500,n.DEFAULT_GRAVITY_STRENGTH=.4,n.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,n.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,n.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,n.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,n.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,n.COOLING_ADAPTATION_FACTOR=.33,n.ADAPTATION_LOWER_NODE_LIMIT=1e3,n.ADAPTATION_UPPER_NODE_LIMIT=5e3,n.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,n.MAX_NODE_DISPLACEMENT=3*n.MAX_NODE_DISPLACEMENT_INCREMENTAL,n.MIN_REPULSION_DIST=n.DEFAULT_EDGE_LENGTH/10,n.CONVERGENCE_CHECK_PERIOD=100,n.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,n.MIN_EDGE_LENGTH=1,n.GRID_CALCULATION_CHECK_PERIOD=10,t.exports=n},function(t,e,i){"use strict";function r(t,e){null==t&&null==e?(this.x=0,this.y=0):(this.x=t,this.y=e)}r.prototype.getX=function(){return this.x},r.prototype.getY=function(){return this.y},r.prototype.setX=function(t){this.x=t},r.prototype.setY=function(t){this.y=t},r.prototype.getDifference=function(t){return new DimensionD(this.x-t.x,this.y-t.y)},r.prototype.getCopy=function(){return new r(this.x,this.y)},r.prototype.translate=function(t){return this.x+=t.width,this.y+=t.height,this},t.exports=r},function(t,e,i){"use strict";var r=i(2),n=i(10),o=i(0),s=i(7),a=i(3),h=i(1),l=i(13),c=i(12),d=i(11);function g(t,e,i){r.call(this,i),this.estimatedSize=n.MIN_VALUE,this.margin=o.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=t,null!=e&&e instanceof s?this.graphManager=e:null!=e&&e instanceof Layout&&(this.graphManager=e.graphManager)}for(var u in g.prototype=Object.create(r.prototype),r)g[u]=r[u];g.prototype.getNodes=function(){return this.nodes},g.prototype.getEdges=function(){return this.edges},g.prototype.getGraphManager=function(){return this.graphManager},g.prototype.getParent=function(){return this.parent},g.prototype.getLeft=function(){return this.left},g.prototype.getRight=function(){return this.right},g.prototype.getTop=function(){return this.top},g.prototype.getBottom=function(){return this.bottom},g.prototype.isConnected=function(){return this.isConnected},g.prototype.add=function(t,e,i){if(null==e&&null==i){var r=t;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(r)>-1)throw"Node already in graph!";return r.owner=this,this.getNodes().push(r),r}var n=t;if(!(this.getNodes().indexOf(e)>-1&&this.getNodes().indexOf(i)>-1))throw"Source or target not in graph!";if(e.owner!=i.owner||e.owner!=this)throw"Both owners must be this graph!";return e.owner!=i.owner?null:(n.source=e,n.target=i,n.isInterGraph=!1,this.getEdges().push(n),e.edges.push(n),i!=e&&i.edges.push(n),n)},g.prototype.remove=function(t){var e=t;if(t instanceof a){if(null==e)throw"Node is null!";if(null==e.owner||e.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var i=e.edges.slice(),r=i.length,n=0;n-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(o.source.edges.splice(l,1),o.target!=o.source&&o.target.edges.splice(c,1),-1==(s=o.source.owner.getEdges().indexOf(o)))throw"Not in owner's edge list!";o.source.owner.getEdges().splice(s,1)}},g.prototype.updateLeftTop=function(){for(var t,e,i,r=n.MAX_VALUE,o=n.MAX_VALUE,s=this.getNodes(),a=s.length,h=0;h(t=l.getTop())&&(r=t),o>(e=l.getLeft())&&(o=e)}return r==n.MAX_VALUE?null:(i=null!=s[0].getParent().paddingLeft?s[0].getParent().paddingLeft:this.margin,this.left=o-i,this.top=r-i,new c(this.left,this.top))},g.prototype.updateBounds=function(t){for(var e,i,r,o,s,a=n.MAX_VALUE,h=-n.MAX_VALUE,c=n.MAX_VALUE,d=-n.MAX_VALUE,g=this.nodes,u=g.length,p=0;p(e=f.getLeft())&&(a=e),h<(i=f.getRight())&&(h=i),c>(r=f.getTop())&&(c=r),d<(o=f.getBottom())&&(d=o)}var v=new l(a,c,h-a,d-c);a==n.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),s=null!=g[0].getParent().paddingLeft?g[0].getParent().paddingLeft:this.margin,this.left=v.x-s,this.right=v.x+v.width+s,this.top=v.y-s,this.bottom=v.y+v.height+s},g.calculateBounds=function(t){for(var e,i,r,o,s=n.MAX_VALUE,a=-n.MAX_VALUE,h=n.MAX_VALUE,c=-n.MAX_VALUE,d=t.length,g=0;g(e=u.getLeft())&&(s=e),a<(i=u.getRight())&&(a=i),h>(r=u.getTop())&&(h=r),c<(o=u.getBottom())&&(c=o)}return new l(s,h,a-s,c-h)},g.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},g.prototype.getEstimatedSize=function(){if(this.estimatedSize==n.MIN_VALUE)throw"assert failed";return this.estimatedSize},g.prototype.calcEstimatedSize=function(){for(var t=0,e=this.nodes,i=e.length,r=0;r=this.nodes.length){var h=0;n.forEach((function(e){e.owner==t&&h++})),h==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},t.exports=g},function(t,e,i){"use strict";var r,n=i(1);function o(t){r=i(6),this.layout=t,this.graphs=[],this.edges=[]}o.prototype.addRoot=function(){var t=this.layout.newGraph(),e=this.layout.newNode(null),i=this.add(t,e);return this.setRootGraph(i),this.rootGraph},o.prototype.add=function(t,e,i,r,n){if(null==i&&null==r&&null==n){if(null==t)throw"Graph is null!";if(null==e)throw"Parent node is null!";if(this.graphs.indexOf(t)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(t),null!=t.parent)throw"Already has a parent!";if(null!=e.child)throw"Already has a child!";return t.parent=e,e.child=t,t}n=i,i=t;var o=(r=e).getOwner(),s=n.getOwner();if(null==o||o.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==s||s.getGraphManager()!=this)throw"Target not in this graph mgr!";if(o==s)return i.isInterGraph=!1,o.add(i,r,n);if(i.isInterGraph=!0,i.source=r,i.target=n,this.edges.indexOf(i)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(i),null==i.source||null==i.target)throw"Edge source and/or target is null!";if(-1!=i.source.edges.indexOf(i)||-1!=i.target.edges.indexOf(i))throw"Edge already in source and/or target incidency list!";return i.source.edges.push(i),i.target.edges.push(i),i},o.prototype.remove=function(t){if(t instanceof r){var e=t;if(e.getGraphManager()!=this)throw"Graph not in this graph mgr";if(e!=this.rootGraph&&(null==e.parent||e.parent.graphManager!=this))throw"Invalid parent node!";for(var i,o=[],s=(o=o.concat(e.getEdges())).length,a=0;a=e.getRight()?i[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight()):e.getX()<=t.getX()&&e.getRight()>=t.getRight()&&(i[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight())),t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()?i[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()):e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()&&(i[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()));var o=Math.abs((e.getCenterY()-t.getCenterY())/(e.getCenterX()-t.getCenterX()));e.getCenterY()===t.getCenterY()&&e.getCenterX()===t.getCenterX()&&(o=1);var s=o*i[0],a=i[1]/o;i[0]s)return i[0]=r,i[1]=h,i[2]=o,i[3]=E,!1;if(no)return i[0]=a,i[1]=n,i[2]=y,i[3]=s,!1;if(ro?(i[0]=c,i[1]=d,w=!0):(i[0]=l,i[1]=h,w=!0):I===C&&(r>o?(i[0]=a,i[1]=h,w=!0):(i[0]=g,i[1]=d,w=!0)),-_===C?o>r?(i[2]=m,i[3]=E,L=!0):(i[2]=y,i[3]=v,L=!0):_===C&&(o>r?(i[2]=f,i[3]=v,L=!0):(i[2]=N,i[3]=E,L=!0)),w&&L)return!1;if(r>o?n>s?(M=this.getCardinalDirection(I,C,4),x=this.getCardinalDirection(_,C,2)):(M=this.getCardinalDirection(-I,C,3),x=this.getCardinalDirection(-_,C,1)):n>s?(M=this.getCardinalDirection(-I,C,1),x=this.getCardinalDirection(-_,C,3)):(M=this.getCardinalDirection(I,C,2),x=this.getCardinalDirection(_,C,4)),!w)switch(M){case 1:D=h,O=r+-p/C,i[0]=O,i[1]=D;break;case 2:O=g,D=n+u*C,i[0]=O,i[1]=D;break;case 3:D=d,O=r+p/C,i[0]=O,i[1]=D;break;case 4:O=c,D=n+-u*C,i[0]=O,i[1]=D}if(!L)switch(x){case 1:b=v,R=o+-A/C,i[2]=R,i[3]=b;break;case 2:R=N,b=s+T*C,i[2]=R,i[3]=b;break;case 3:b=E,R=o+A/C,i[2]=R,i[3]=b;break;case 4:R=m,b=s+-T*C,i[2]=R,i[3]=b}}return!1},n.getCardinalDirection=function(t,e,i){return t>e?i:1+i%4},n.getIntersection=function(t,e,i,n){if(null==n)return this.getIntersection2(t,e,i);var o,s,a,h,l,c,d,g=t.x,u=t.y,p=e.x,f=e.y,v=i.x,y=i.y,m=n.x,E=n.y;return 0==(d=(o=f-u)*(h=v-m)-(s=E-y)*(a=g-p))?null:new r((a*(c=m*y-v*E)-h*(l=p*u-g*f))/d,(s*l-o*c)/d)},n.angleOfVector=function(t,e,i,r){var n=void 0;return t!==i?(n=Math.atan((r-e)/(i-t)),i=0){var c=(-h+Math.sqrt(h*h-4*a*l))/(2*a),d=(-h-Math.sqrt(h*h-4*a*l))/(2*a);return c>=0&&c<=1?[c]:d>=0&&d<=1?[d]:null}return null},n.HALF_PI=.5*Math.PI,n.ONE_AND_HALF_PI=1.5*Math.PI,n.TWO_PI=2*Math.PI,n.THREE_PI=3*Math.PI,t.exports=n},function(t,e,i){"use strict";function r(){}r.sign=function(t){return t>0?1:t<0?-1:0},r.floor=function(t){return t<0?Math.ceil(t):Math.floor(t)},r.ceil=function(t){return t<0?Math.floor(t):Math.ceil(t)},t.exports=r},function(t,e,i){"use strict";function r(){}r.MAX_VALUE=2147483647,r.MIN_VALUE=-2147483648,t.exports=r},function(t,e,i){"use strict";var r=function(){function t(t,e){for(var i=0;i0&&e;){for(a.push(l[0]);a.length>0&&e;){var c=a[0];a.splice(0,1),s.add(c);var d=c.getEdges();for(o=0;o-1&&l.splice(f,1)}s=new Set,h=new Map}else t=[]}return t},g.prototype.createDummyNodesForBendpoints=function(t){for(var e=[],i=t.source,r=this.graphManager.calcLowestCommonAncestor(t.source,t.target),n=0;n0){for(var n=this.edgeToDummyNodes.get(i),o=0;o=0&&e.splice(d,1),c.getNeighborsList().forEach((function(t){if(i.indexOf(t)<0){var e=r.get(t)-1;1==e&&h.push(t),r.set(t,e)}}))}i=i.concat(h),1!=e.length&&2!=e.length||(n=!0,o=e[0])}return o},g.prototype.setGraphManager=function(t){this.graphManager=t},t.exports=g},function(t,e,i){"use strict";function r(){}r.seed=1,r.x=0,r.nextDouble=function(){return r.x=1e4*Math.sin(r.seed++),r.x-Math.floor(r.x)},t.exports=r},function(t,e,i){"use strict";var r=i(5);function n(t,e){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}n.prototype.getWorldOrgX=function(){return this.lworldOrgX},n.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},n.prototype.getWorldOrgY=function(){return this.lworldOrgY},n.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},n.prototype.getWorldExtX=function(){return this.lworldExtX},n.prototype.setWorldExtX=function(t){this.lworldExtX=t},n.prototype.getWorldExtY=function(){return this.lworldExtY},n.prototype.setWorldExtY=function(t){this.lworldExtY=t},n.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},n.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},n.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},n.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},n.prototype.getDeviceExtX=function(){return this.ldeviceExtX},n.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},n.prototype.getDeviceExtY=function(){return this.ldeviceExtY},n.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},n.prototype.transformX=function(t){var e=0,i=this.lworldExtX;return 0!=i&&(e=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/i),e},n.prototype.transformY=function(t){var e=0,i=this.lworldExtY;return 0!=i&&(e=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/i),e},n.prototype.inverseTransformX=function(t){var e=0,i=this.ldeviceExtX;return 0!=i&&(e=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/i),e},n.prototype.inverseTransformY=function(t){var e=0,i=this.ldeviceExtY;return 0!=i&&(e=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/i),e},n.prototype.inverseTransformPoint=function(t){return new r(this.inverseTransformX(t.x),this.inverseTransformY(t.y))},t.exports=n},function(t,e,i){"use strict";var r=i(15),n=i(4),o=i(0),s=i(8),a=i(9);function h(){r.call(this),this.useSmartIdealEdgeLengthCalculation=n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=n.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=n.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=n.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=n.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*n.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=n.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=n.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=n.MAX_ITERATIONS}for(var l in h.prototype=Object.create(r.prototype),r)h[l]=r[l];h.prototype.initParameters=function(){r.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=n.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var t,e,i,r,s,a,h,l=this.getGraphManager().getAllEdges(),c=0;cn.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*n.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-n.ADAPTATION_LOWER_NODE_LIMIT)/(n.ADAPTATION_UPPER_NODE_LIMIT-n.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-n.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=n.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>n.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(n.COOLING_ADAPTATION_FACTOR,1-(t-n.ADAPTATION_LOWER_NODE_LIMIT)/(n.ADAPTATION_UPPER_NODE_LIMIT-n.ADAPTATION_LOWER_NODE_LIMIT)*(1-n.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=n.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.displacementThresholdPerNode=3*n.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var t,e=this.getAllEdges(),i=0;i0&&void 0!==arguments[0])||arguments[0],a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],h=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%n.GRID_CALCULATION_CHECK_PERIOD==1&&s&&this.updateGrid(),o=new Set,t=0;t(h=e.getEstimatedSize()*this.gravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*n,t.gravitationForceY=-this.gravityConstant*o):(s>(h=e.getEstimatedSize()*this.compoundGravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*n*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*o*this.compoundGravityConstant)},h.prototype.isConverged=function(){var t,e=!1;return this.totalIterations>this.maxIterations/3&&(e=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement=a.length||l>=a[0].length))for(var c=0;ct}}]),t}();t.exports=o},function(t,e,i){"use strict";function r(){}r.svd=function(t){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=t.length,this.n=t[0].length;var e=Math.min(this.m,this.n);this.s=function(t){for(var e=[];t-- >0;)e.push(0);return e}(Math.min(this.m+1,this.n)),this.U=function t(e){if(0==e.length)return 0;for(var i=[],r=0;r0;)e.push(0);return e}(this.n),s=function(t){for(var e=[];t-- >0;)e.push(0);return e}(this.m),a=Math.min(this.m-1,this.n),h=Math.max(0,Math.min(this.n-2,this.m)),l=0;l=0;x--)if(0!==this.s[x]){for(var O=x+1;O=0;P--){if(function(t,e){return t&&e}(P0;){var W=void 0,j=void 0;for(W=_-2;W>=-1&&-1!==W;W--)if(Math.abs(o[W])<=B+V*(Math.abs(this.s[W])+Math.abs(this.s[W+1]))){o[W]=0;break}if(W===_-2)j=4;else{var q=void 0;for(q=_-1;q>=W&&q!==W;q--){var $=(q!==_?Math.abs(o[q]):0)+(q!==W+1?Math.abs(o[q-1]):0);if(Math.abs(this.s[q])<=B+V*$){this.s[q]=0;break}}q===W?j=3:q===_-1?j=1:(j=2,W=q)}switch(W++,j){case 1:var K=o[_-2];o[_-2]=0;for(var Z=_-2;Z>=W;Z--){var Q=r.hypot(this.s[Z],K),J=this.s[Z]/Q,tt=K/Q;this.s[Z]=Q,Z!==W&&(K=-tt*o[Z-1],o[Z-1]=J*o[Z-1]);for(var et=0;et=this.s[W+1]);){var _t=this.s[W];if(this.s[W]=this.s[W+1],this.s[W+1]=_t,WMath.abs(e)?(i=e/t,i=Math.abs(t)*Math.sqrt(1+i*i)):0!=e?(i=t/e,i=Math.abs(e)*Math.sqrt(1+i*i)):i=0,i},t.exports=r},function(t,e,i){"use strict";var r=function(){function t(t,e){for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:1,n=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.sequence1=e,this.sequence2=i,this.match_score=r,this.mismatch_penalty=n,this.gap_penalty=o,this.iMax=e.length+1,this.jMax=i.length+1,this.grid=new Array(this.iMax);for(var s=0;s=0;i--){var r=this.listeners[i];r.event===t&&r.callback===e&&this.listeners.splice(i,1)}},n.emit=function(t,e){for(var i=0;i{"use strict";i.d(e,{diagram:()=>dt});var r=i(34483),n=i(86825),o=i(86022),s=i(39676),a=(i(85039),i(61021)),h=i(45567),l=i(78731),c=i(90165),d=i(26527),g=i(20007),u={L:"left",R:"right",T:"top",B:"bottom"},p={L:(0,h.K2)((t=>`${t},${t/2} 0,${t} 0,0`),"L"),R:(0,h.K2)((t=>`0,${t/2} ${t},0 ${t},${t}`),"R"),T:(0,h.K2)((t=>`0,0 ${t},0 ${t/2},${t}`),"T"),B:(0,h.K2)((t=>`${t/2},0 ${t},${t} 0,${t}`),"B")},f={L:(0,h.K2)(((t,e)=>t-e+2),"L"),R:(0,h.K2)(((t,e)=>t-2),"R"),T:(0,h.K2)(((t,e)=>t-e+2),"T"),B:(0,h.K2)(((t,e)=>t-2),"B")},v=(0,h.K2)((function(t){return m(t)?"L"===t?"R":"L":"T"===t?"B":"T"}),"getOppositeArchitectureDirection"),y=(0,h.K2)((function(t){return"L"===t||"R"===t||"T"===t||"B"===t}),"isArchitectureDirection"),m=(0,h.K2)((function(t){return"L"===t||"R"===t}),"isArchitectureDirectionX"),E=(0,h.K2)((function(t){return"T"===t||"B"===t}),"isArchitectureDirectionY"),N=(0,h.K2)((function(t,e){const i=m(t)&&E(e),r=E(t)&&m(e);return i||r}),"isArchitectureDirectionXY"),T=(0,h.K2)((function(t){const e=t[0],i=t[1],r=m(e)&&E(i),n=E(e)&&m(i);return r||n}),"isArchitecturePairXY"),A=(0,h.K2)((function(t){return"LL"!==t&&"RR"!==t&&"TT"!==t&&"BB"!==t}),"isValidArchitectureDirectionPair"),w=(0,h.K2)((function(t,e){const i=`${t}${e}`;return A(i)?i:void 0}),"getArchitectureDirectionPair"),L=(0,h.K2)((function([t,e],i){const r=i[0],n=i[1];return m(r)?E(n)?[t+("L"===r?-1:1),e+("T"===n?1:-1)]:[t+("L"===r?-1:1),e]:m(n)?[t+("L"===n?1:-1),e+("T"===r?1:-1)]:[t,e+("T"===r?1:-1)]}),"shiftPositionByArchitectureDirectionPair"),I=(0,h.K2)((function(t){return"LT"===t||"TL"===t?[1,1]:"BL"===t||"LB"===t?[1,-1]:"BR"===t||"RB"===t?[-1,-1]:[-1,1]}),"getArchitectureDirectionXYFactors"),_=(0,h.K2)((function(t){return"service"===t.type}),"isArchitectureService"),C=(0,h.K2)((function(t){return"junction"===t.type}),"isArchitectureJunction"),M=(0,h.K2)((t=>t.data()),"edgeData"),x=(0,h.K2)((t=>t.data()),"nodeData"),O=h.UI.architecture,D=new s.m((()=>({nodes:{},groups:{},edges:[],registeredIds:{},config:O,dataStructures:void 0,elements:{}}))),R=(0,h.K2)((()=>{D.reset(),(0,h.IU)()}),"clear"),b=(0,h.K2)((function({id:t,icon:e,in:i,title:r,iconText:n}){if(void 0!==D.records.registeredIds[t])throw new Error(`The service id [${t}] is already in use by another ${D.records.registeredIds[t]}`);if(void 0!==i){if(t===i)throw new Error(`The service [${t}] cannot be placed within itself`);if(void 0===D.records.registeredIds[i])throw new Error(`The service [${t}]'s parent does not exist. Please make sure the parent is created before this service`);if("node"===D.records.registeredIds[i])throw new Error(`The service [${t}]'s parent is not a group`)}D.records.registeredIds[t]="node",D.records.nodes[t]={id:t,type:"service",icon:e,iconText:n,title:r,edges:[],in:i}}),"addService"),G=(0,h.K2)((()=>Object.values(D.records.nodes).filter(_)),"getServices"),F=(0,h.K2)((function({id:t,in:e}){D.records.registeredIds[t]="node",D.records.nodes[t]={id:t,type:"junction",edges:[],in:e}}),"addJunction"),S=(0,h.K2)((()=>Object.values(D.records.nodes).filter(C)),"getJunctions"),P=(0,h.K2)((()=>Object.values(D.records.nodes)),"getNodes"),U=(0,h.K2)((t=>D.records.nodes[t]),"getNode"),Y=(0,h.K2)((function({id:t,icon:e,in:i,title:r}){if(void 0!==D.records.registeredIds[t])throw new Error(`The group id [${t}] is already in use by another ${D.records.registeredIds[t]}`);if(void 0!==i){if(t===i)throw new Error(`The group [${t}] cannot be placed within itself`);if(void 0===D.records.registeredIds[i])throw new Error(`The group [${t}]'s parent does not exist. Please make sure the parent is created before this group`);if("node"===D.records.registeredIds[i])throw new Error(`The group [${t}]'s parent is not a group`)}D.records.registeredIds[t]="group",D.records.groups[t]={id:t,icon:e,title:r,in:i}}),"addGroup"),k=(0,h.K2)((()=>Object.values(D.records.groups)),"getGroups"),H=(0,h.K2)((function({lhsId:t,rhsId:e,lhsDir:i,rhsDir:r,lhsInto:n,rhsInto:o,lhsGroup:s,rhsGroup:a,title:h}){if(!y(i))throw new Error(`Invalid direction given for left hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${i}`);if(!y(r))throw new Error(`Invalid direction given for right hand side of edge ${t}--${e}. Expected (L,R,T,B) got ${r}`);if(void 0===D.records.nodes[t]&&void 0===D.records.groups[t])throw new Error(`The left-hand id [${t}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(void 0===D.records.nodes[e]&&void 0===D.records.groups[t])throw new Error(`The right-hand id [${e}] does not yet exist. Please create the service/group before declaring an edge to it.`);const l=D.records.nodes[t].in,c=D.records.nodes[e].in;if(s&&l&&c&&l==c)throw new Error(`The left-hand id [${t}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(a&&l&&c&&l==c)throw new Error(`The right-hand id [${e}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);const d={lhsId:t,lhsDir:i,lhsInto:n,lhsGroup:s,rhsId:e,rhsDir:r,rhsInto:o,rhsGroup:a,title:h};D.records.edges.push(d),D.records.nodes[t]&&D.records.nodes[e]&&(D.records.nodes[t].edges.push(D.records.edges[D.records.edges.length-1]),D.records.nodes[e].edges.push(D.records.edges[D.records.edges.length-1]))}),"addEdge"),X=(0,h.K2)((()=>D.records.edges),"getEdges"),z=(0,h.K2)((()=>{if(void 0===D.records.dataStructures){const t=Object.entries(D.records.nodes).reduce(((t,[e,i])=>(t[e]=i.edges.reduce(((t,i)=>{if(i.lhsId===e){const e=w(i.lhsDir,i.rhsDir);e&&(t[e]=i.rhsId)}else{const e=w(i.rhsDir,i.lhsDir);e&&(t[e]=i.lhsId)}return t}),{}),t)),{}),e=Object.keys(t)[0],i={[e]:1},r=Object.keys(t).reduce(((t,i)=>i===e?t:{...t,[i]:1}),{}),n=(0,h.K2)((e=>{const n={[e]:[0,0]},o=[e];for(;o.length>0;){const e=o.shift();if(e){i[e]=1,delete r[e];const s=t[e],[a,h]=n[e];Object.entries(s).forEach((([t,e])=>{i[e]||(n[e]=L([a,h],t),o.push(e))}))}}return n}),"BFS"),o=[n(e)];for(;Object.keys(r).length>0;)o.push(n(Object.keys(r)[0]));D.records.dataStructures={adjList:t,spatialMaps:o}}return D.records.dataStructures}),"getDataStructures"),V=(0,h.K2)(((t,e)=>{D.records.elements[t]=e}),"setElementForId"),B=(0,h.K2)((t=>D.records.elements[t]),"getElementById"),W={clear:R,setDiagramTitle:h.ke,getDiagramTitle:h.ab,setAccTitle:h.SV,getAccTitle:h.iN,setAccDescription:h.EI,getAccDescription:h.m7,addService:b,getServices:G,addJunction:F,getJunctions:S,getNodes:P,getNode:U,addGroup:Y,getGroups:k,addEdge:H,getEdges:X,setElementForId:V,getElementById:B,getDataStructures:z};function j(t){const e=(0,h.D7)().architecture;return e?.[t]?e[t]:O[t]}(0,h.K2)(j,"getConfigField");var q=(0,h.K2)(((t,e)=>{(0,o.S)(t,e),t.groups.map(e.addGroup),t.services.map((t=>e.addService({...t,type:"service"}))),t.junctions.map((t=>e.addJunction({...t,type:"junction"}))),t.edges.map(e.addEdge)}),"populateDb"),$={parse:(0,h.K2)((async t=>{const e=await(0,l.qg)("architecture",t);h.Rm.debug(e),q(e,W)}),"parse")},K=(0,h.K2)((t=>`\n .edge {\n stroke-width: ${t.archEdgeWidth};\n stroke: ${t.archEdgeColor};\n fill: none;\n }\n\n .arrow {\n fill: ${t.archEdgeArrowColor};\n }\n\n .node-bkg {\n fill: none;\n stroke: ${t.archGroupBorderColor};\n stroke-width: ${t.archGroupBorderWidth};\n stroke-dasharray: 8;\n }\n .node-icon-text {\n display: flex; \n align-items: center;\n }\n \n .node-icon-text > div {\n color: #fff;\n margin: 1px;\n height: fit-content;\n text-align: center;\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n }\n`),"getStyles"),Z=(0,h.K2)((t=>`${t}`),"wrapIcon"),Q={prefix:"mermaid-architecture",height:80,width:80,icons:{database:{body:Z('')},server:{body:Z('')},disk:{body:Z('')},internet:{body:Z('')},cloud:{body:Z('')},unknown:r.Gc,blank:{body:Z("")}}},J=(0,h.K2)((async function(t,e){const i=j("padding"),r=j("iconSize"),o=r/2,s=r/6,a=s/2;await Promise.all(e.edges().map((async e=>{const{source:r,sourceDir:l,sourceArrow:c,sourceGroup:d,target:g,targetDir:u,targetArrow:v,targetGroup:y,label:A}=M(e);let{x:L,y:_}=e[0].sourceEndpoint();const{x:C,y:x}=e[0].midpoint();let{x:O,y:D}=e[0].targetEndpoint();const R=i+4;if(d&&(m(l)?L+="L"===l?-R:R:_+="T"===l?-R:R+18),y&&(m(u)?O+="L"===u?-R:R:D+="T"===u?-R:R+18),d||"junction"!==W.getNode(r)?.type||(m(l)?L+="L"===l?o:-o:_+="T"===l?o:-o),y||"junction"!==W.getNode(g)?.type||(m(u)?O+="L"===u?o:-o:D+="T"===u?o:-o),e[0]._private.rscratch){const e=t.insert("g");if(e.insert("path").attr("d",`M ${L},${_} L ${C},${x} L${O},${D} `).attr("class","edge"),c){const t=m(l)?f[l](L,s):L-a,i=E(l)?f[l](_,s):_-a;e.insert("polygon").attr("points",p[l](s)).attr("transform",`translate(${t},${i})`).attr("class","arrow")}if(v){const t=m(u)?f[u](O,s):O-a,i=E(u)?f[u](D,s):D-a;e.insert("polygon").attr("points",p[u](s)).attr("transform",`translate(${t},${i})`).attr("class","arrow")}if(A){const t=N(l,u)?"XY":m(l)?"X":"Y";let i=0;i="X"===t?Math.abs(L-O):"Y"===t?Math.abs(_-D)/1.5:Math.abs(L-O)/2;const r=e.append("g");if(await(0,n.GZ)(r,A,{useHtmlLabels:!1,width:i,classes:"architecture-service-label"},(0,h.D7)()),r.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),"X"===t)r.attr("transform","translate("+C+", "+x+")");else if("Y"===t)r.attr("transform","translate("+C+", "+x+") rotate(-90)");else if("XY"===t){const t=w(l,u);if(t&&T(t)){const e=r.node().getBoundingClientRect(),[i,n]=I(t);r.attr("dominant-baseline","auto").attr("transform",`rotate(${-1*i*n*45})`);const o=r.node().getBoundingClientRect();r.attr("transform",`\n translate(${C}, ${x-e.height/2})\n translate(${i*o.width/2}, ${n*o.height/2})\n rotate(${-1*i*n*45}, 0, ${e.height/2})\n `)}}}}})))}),"drawEdges"),tt=(0,h.K2)((async function(t,e){const i=.75*j("padding"),o=j("fontSize"),s=j("iconSize")/2;await Promise.all(e.nodes().map((async e=>{const a=x(e);if("group"===a.type){const{h:l,w:c,x1:d,y1:g}=e.boundingBox();t.append("rect").attr("x",d+s).attr("y",g+s).attr("width",c).attr("height",l).attr("class","node-bkg");const u=t.append("g");let p=d,f=g;if(a.icon){const t=u.append("g");t.html(`${await(0,r.WY)(a.icon,{height:i,width:i,fallbackPrefix:Q.prefix})}`),t.attr("transform","translate("+(p+s+1)+", "+(f+s+1)+")"),p+=i,f+=o/2-1-2}if(a.label){const t=u.append("g");await(0,n.GZ)(t,a.label,{useHtmlLabels:!1,width:c,classes:"architecture-service-label"},(0,h.D7)()),t.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","start").attr("text-anchor","start"),t.attr("transform","translate("+(p+s+4)+", "+(f+s+2)+")")}}})))}),"drawGroups"),et=(0,h.K2)((async function(t,e,i){for(const o of i){const i=e.append("g"),s=j("iconSize");if(o.title){const t=i.append("g");await(0,n.GZ)(t,o.title,{useHtmlLabels:!1,width:1.5*s,classes:"architecture-service-label"},(0,h.D7)()),t.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle"),t.attr("transform","translate("+s/2+", "+s+")")}const a=i.append("g");if(o.icon)a.html(`${await(0,r.WY)(o.icon,{height:s,width:s,fallbackPrefix:Q.prefix})}`);else if(o.iconText){a.html(`${await(0,r.WY)("blank",{height:s,width:s,fallbackPrefix:Q.prefix})}`);const t=a.append("g").append("foreignObject").attr("width",s).attr("height",s).append("div").attr("class","node-icon-text").attr("style",`height: ${s}px;`).append("div").html(o.iconText),e=parseInt(window.getComputedStyle(t.node(),null).getPropertyValue("font-size").replace(/\D/g,""))??16;t.attr("style",`-webkit-line-clamp: ${Math.floor((s-2)/e)};`)}else a.append("path").attr("class","node-bkg").attr("id","node-"+o.id).attr("d",`M0 ${s} v${-s} q0,-5 5,-5 h${s} q5,0 5,5 v${s} H0 Z`);i.attr("class","architecture-service");const{width:l,height:c}=i._groups[0][0].getBBox();o.width=l,o.height=c,t.setElementForId(o.id,i)}return 0}),"drawServices"),it=(0,h.K2)((function(t,e,i){i.forEach((i=>{const r=e.append("g"),n=j("iconSize");r.append("g").append("rect").attr("id","node-"+i.id).attr("fill-opacity","0").attr("width",n).attr("height",n),r.attr("class","architecture-junction");const{width:o,height:s}=r._groups[0][0].getBBox();r.width=o,r.height=s,t.setElementForId(i.id,r)}))}),"drawJunctions");function rt(t,e){t.forEach((t=>{e.add({group:"nodes",data:{type:"service",id:t.id,icon:t.icon,label:t.title,parent:t.in,width:j("iconSize"),height:j("iconSize")},classes:"node-service"})}))}function nt(t,e){t.forEach((t=>{e.add({group:"nodes",data:{type:"junction",id:t.id,parent:t.in,width:j("iconSize"),height:j("iconSize")},classes:"node-junction"})}))}function ot(t,e){e.nodes().map((e=>{const i=x(e);if("group"===i.type)return;i.x=e.position().x,i.y=e.position().y;t.getElementById(i.id).attr("transform","translate("+(i.x||0)+","+(i.y||0)+")")}))}function st(t,e){t.forEach((t=>{e.add({group:"nodes",data:{type:"group",id:t.id,icon:t.icon,label:t.title,parent:t.in},classes:"node-group"})}))}function at(t,e){t.forEach((t=>{const{lhsId:i,rhsId:r,lhsInto:n,lhsGroup:o,rhsInto:s,lhsDir:a,rhsDir:h,rhsGroup:l,title:c}=t,d=N(t.lhsDir,t.rhsDir)?"segments":"straight",g={id:`${i}-${r}`,label:c,source:i,sourceDir:a,sourceArrow:n,sourceGroup:o,sourceEndpoint:"L"===a?"0 50%":"R"===a?"100% 50%":"T"===a?"50% 0":"50% 100%",target:r,targetDir:h,targetArrow:s,targetGroup:l,targetEndpoint:"L"===h?"0 50%":"R"===h?"100% 50%":"T"===h?"50% 0":"50% 100%"};e.add({group:"edges",data:g,classes:d})}))}function ht(t){const e=t.map((t=>{const e={},i={};return Object.entries(t).forEach((([t,[r,n]])=>{e[n]||(e[n]=[]),i[r]||(i[r]=[]),e[n].push(t),i[r].push(t)})),{horiz:Object.values(e).filter((t=>t.length>1)),vert:Object.values(i).filter((t=>t.length>1))}})),[i,r]=e.reduce((([t,e],{horiz:i,vert:r})=>[[...t,...i],[...e,...r]]),[[],[]]);return{horizontal:i,vertical:r}}function lt(t){const e=[],i=(0,h.K2)((t=>`${t[0]},${t[1]}`),"posToStr"),r=(0,h.K2)((t=>t.split(",").map((t=>parseInt(t)))),"strToPos");return t.forEach((t=>{const n=Object.fromEntries(Object.entries(t).map((([t,e])=>[i(e),t]))),o=[i([0,0])],s={},a={L:[-1,0],R:[1,0],T:[0,1],B:[0,-1]};for(;o.length>0;){const t=o.shift();if(t){s[t]=1;const h=n[t];if(h){const l=r(t);Object.entries(a).forEach((([t,r])=>{const a=i([l[0]+r[0],l[1]+r[1]]),c=n[a];c&&!s[a]&&(o.push(a),e.push({[u[t]]:c,[u[v(t)]]:h,gap:1.5*j("iconSize")}))}))}}}})),e}function ct(t,e,i,r,{spatialMaps:n}){return new Promise((o=>{const s=(0,g.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),a=(0,c.A)({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"straight",label:"data(label)","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"edge.segments",style:{"curve-style":"segments","segment-weights":"0","segment-distances":[.5],"edge-distances":"endpoints","source-endpoint":"data(sourceEndpoint)","target-endpoint":"data(targetEndpoint)"}},{selector:"node",style:{"compound-sizing-wrt-labels":"include"}},{selector:"node[label]",style:{"text-valign":"bottom","text-halign":"center","font-size":`${j("fontSize")}px`}},{selector:".node-service",style:{label:"data(label)",width:"data(width)",height:"data(height)"}},{selector:".node-junction",style:{width:"data(width)",height:"data(height)"}},{selector:".node-group",style:{padding:`${j("padding")}px`}}]});s.remove(),st(i,a),rt(t,a),nt(e,a),at(r,a);const l=ht(n),d=lt(n),u=a.layout({name:"fcose",quality:"proof",styleEnabled:!1,animate:!1,nodeDimensionsIncludeLabels:!1,idealEdgeLength(t){const[e,i]=t.connectedNodes(),{parent:r}=x(e),{parent:n}=x(i);return r===n?1.5*j("iconSize"):.5*j("iconSize")},edgeElasticity(t){const[e,i]=t.connectedNodes(),{parent:r}=x(e),{parent:n}=x(i);return r===n?.45:.001},alignmentConstraint:l,relativePlacementConstraint:d});u.one("layoutstop",(()=>{function t(t,e,i,r){let n,o;const{x:s,y:a}=t,{x:h,y:l}=e;o=(r-a+(s-i)*(a-l)/(s-h))/Math.sqrt(1+Math.pow((a-l)/(s-h),2)),n=Math.sqrt(Math.pow(r-a,2)+Math.pow(i-s,2)-Math.pow(o,2));n/=Math.sqrt(Math.pow(h-s,2)+Math.pow(l-a,2));let c=(h-s)*(r-a)-(l-a)*(i-s);switch(!0){case c>=0:c=1;break;case c<0:c=-1}let d=(h-s)*(i-s)+(l-a)*(r-a);switch(!0){case d>=0:d=1;break;case d<0:d=-1}return o=Math.abs(o)*c,n*=d,{distances:o,weights:n}}(0,h.K2)(t,"getSegmentWeights"),a.startBatch();for(const e of Object.values(a.edges()))if(e.data?.()){const{x:i,y:r}=e.source().position(),{x:n,y:o}=e.target().position();if(i!==n&&r!==o){const i=e.sourceEndpoint(),r=e.targetEndpoint(),{sourceDir:n}=M(e),[o,s]=E(n)?[i.x,r.y]:[r.x,i.y],{weights:a,distances:h}=t(i,r,o,s);e.style("segment-distances",h),e.style("segment-weights",a)}}a.endBatch(),u.run()})),u.run(),a.ready((t=>{h.Rm.info("Ready",t),o(a)}))}))}(0,r.pC)([{name:Q.prefix,icons:Q}]),c.A.use(d),(0,h.K2)(rt,"addServices"),(0,h.K2)(nt,"addJunctions"),(0,h.K2)(ot,"positionNodes"),(0,h.K2)(st,"addGroups"),(0,h.K2)(at,"addEdges"),(0,h.K2)(ht,"getAlignments"),(0,h.K2)(lt,"getRelativeConstraints"),(0,h.K2)(ct,"layoutArchitecture");var dt={parser:$,db:W,renderer:{draw:(0,h.K2)((async(t,e,i,r)=>{const n=r.db,o=n.getServices(),s=n.getJunctions(),l=n.getGroups(),c=n.getEdges(),d=n.getDataStructures(),g=(0,a.D)(e),u=g.append("g");u.attr("class","architecture-edges");const p=g.append("g");p.attr("class","architecture-services");const f=g.append("g");f.attr("class","architecture-groups"),await et(n,p,o),it(n,p,s);const v=await ct(o,s,l,c,d);await J(u,v),await tt(f,v),ot(n,v),(0,h.ot)(void 0,g,j("padding"),j("useMaxWidth"))}),"draw")},styles:K}},86022:(t,e,i)=>{"use strict";function r(t,e){t.accDescr&&e.setAccDescription?.(t.accDescr),t.accTitle&&e.setAccTitle?.(t.accTitle),t.title&&e.setDiagramTitle?.(t.title)}i.d(e,{S:()=>r}),(0,i(45567).K2)(r,"populateCommonDb")},39676:(t,e,i)=>{"use strict";i.d(e,{m:()=>n});var r=i(45567),n=class{constructor(t){this.init=t,this.records=this.init()}static{(0,r.K2)(this,"ImperativeState")}reset(){this.records=this.init()}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2334.619d7d41.js b/pr-preview/pr-976/assets/js/2334.619d7d41.js new file mode 100644 index 0000000000..02c66d8409 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2334.619d7d41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2334],{62334:(e,n,t)=>{t.d(n,{Zp:()=>Rn});var r=t(8058),o=t(28894),i=0;const u=function(e){var n=++i;return(0,o.A)(e)+n};var a=t(39142),s=t(34098),d=t(74722),c=Math.ceil,h=Math.max;const f=function(e,n,t,r){for(var o=-1,i=h(c((n-e)/(t||1)),0),u=Array(i);i--;)u[r?i:++o]=e,e+=t;return u};var v=t(6832),l=t(74342);const g=function(e){return function(n,t,r){return r&&"number"!=typeof r&&(0,v.A)(n,t,r)&&(t=r=void 0),n=(0,l.A)(n),void 0===t?(t=n,n=0):t=(0,l.A)(t),r=void 0===r?n0;--a)if(r=n[a].dequeue()){o=o.concat(_(e,n,t,r,!0));break}}return o}(t.graph,t.buckets,t.zeroIdx);return s.A(d.A(o,(function(n){return e.outEdges(n.v,n.w)})))}function _(e,n,t,o,i){var u=i?[]:void 0;return r.A(e.inEdges(o.v),(function(r){var o=e.edge(r),a=e.node(r.v);i&&u.push({v:r.v,w:r.w}),a.out-=o,E(n,t,a)})),r.A(e.outEdges(o.v),(function(r){var o=e.edge(r),i=r.w,u=e.node(i);u.in-=o,E(n,t,u)})),e.removeNode(o.v),u}function E(e,n,t){t.out?t.in?e[t.out-t.in+n].enqueue(t):e[e.length-1].enqueue(t):e[0].enqueue(t)}function x(e){var n="greedy"===e.graph().acyclicer?y(e,function(e){return function(n){return e.edge(n).weight}}(e)):function(e){var n=[],t={},o={};function i(u){Object.prototype.hasOwnProperty.call(o,u)||(o[u]=!0,t[u]=!0,r.A(e.outEdges(u),(function(e){Object.prototype.hasOwnProperty.call(t,e.w)?n.push(e):i(e.w)})),delete t[u])}return r.A(e.nodes(),i),n}(e);r.A(n,(function(n){var t=e.edge(n);e.removeEdge(n),t.forwardName=n.name,t.reversed=!0,e.setEdge(n.w,n.v,t,u("rev"))}))}var O=t(42837),k=t(99354),N=t(39188);const P=function(e,n){return(0,k.A)(e,n,(function(n,t){return(0,N.A)(e,t)}))};var j=t(76875),C=t(67525);const I=function(e){return(0,C.A)((0,j.A)(e,void 0,s.A),e+"")}((function(e,n){return null==e?{}:P(e,n)}));var L=t(23068),T=t(72559);const M=function(e,n){return e>n};var R=t(29008);const F=function(e){return e&&e.length?(0,T.A)(e,R.A,M):void 0};var D=t(26666),S=t(52528),G=t(79841),V=t(23958);const B=function(e,n){var t={};return n=(0,V.A)(n,3),(0,G.A)(e,(function(e,r,o){(0,S.A)(t,r,n(e,r,o))})),t};var q=t(69592),Y=t(86452),z=t(48585),$=t(41917);const J=function(){return $.A.Date.now()};function Z(e,n,t,r){var o;do{o=u(r)}while(e.hasNode(o));return t.dummy=n,e.setNode(o,t),o}function H(e){var n=new p.T({multigraph:e.isMultigraph()}).setGraph(e.graph());return r.A(e.nodes(),(function(t){e.children(t).length||n.setNode(t,e.node(t))})),r.A(e.edges(),(function(t){n.setEdge(t,e.edge(t))})),n}function K(e,n){var t,r,o=e.x,i=e.y,u=n.x-o,a=n.y-i,s=e.width/2,d=e.height/2;if(!u&&!a)throw new Error("Not possible to find intersection inside of the rectangle");return Math.abs(a)*s>Math.abs(u)*d?(a<0&&(d=-d),t=d*u/a,r=d):(u<0&&(s=-s),t=s,r=s*a/u),{x:o+t,y:i+r}}function Q(e){var n=d.A(g(W(e)+1),(function(){return[]}));return r.A(e.nodes(),(function(t){var r=e.node(t),o=r.rank;q.A(o)||(n[o][r.order]=t)})),n}function U(e,n,t,r){var o={width:0,height:0};return arguments.length>=4&&(o.rank=t,o.order=r),Z(e,"border",o,n)}function W(e){return F(d.A(e.nodes(),(function(n){var t=e.node(n).rank;if(!q.A(t))return t})))}function X(e,n){var t=J();try{return n()}finally{console.log(e+" time: "+(J()-t)+"ms")}}function ee(e,n){return n()}function ne(e,n,t,r,o,i){var u={width:0,height:0,rank:i,borderType:n},a=o[n][i-1],s=Z(e,"border",u,t);o[n][i]=s,e.setParent(s,r),a&&e.setEdge(a,s,{weight:1})}function te(e){var n=e.graph().rankdir.toLowerCase();"bt"!==n&&"rl"!==n||function(e){r.A(e.nodes(),(function(n){ie(e.node(n))})),r.A(e.edges(),(function(n){var t=e.edge(n);r.A(t.points,ie),Object.prototype.hasOwnProperty.call(t,"y")&&ie(t)}))}(e),"lr"!==n&&"rl"!==n||(!function(e){r.A(e.nodes(),(function(n){ue(e.node(n))})),r.A(e.edges(),(function(n){var t=e.edge(n);r.A(t.points,ue),Object.prototype.hasOwnProperty.call(t,"x")&&ue(t)}))}(e),re(e))}function re(e){r.A(e.nodes(),(function(n){oe(e.node(n))})),r.A(e.edges(),(function(n){oe(e.edge(n))}))}function oe(e){var n=e.width;e.width=e.height,e.height=n}function ie(e){e.y=-e.y}function ue(e){var n=e.x;e.x=e.y,e.y=n}function ae(e){e.graph().dummyChains=[],r.A(e.edges(),(function(n){!function(e,n){var t=n.v,r=e.node(t).rank,o=n.w,i=e.node(o).rank,u=n.name,a=e.edge(n),s=a.labelRank;if(i===r+1)return;e.removeEdge(n);var d,c,h=void 0;for(c=0,++r;ru.lim&&(a=u,s=!0);var d=Ae.A(n.edges(),(function(n){return s===Be(e,e.node(n.v),a)&&s!==Be(e,e.node(n.w),a)}));return de(d,(function(e){return he(n,e)}))}function Ve(e,n,t,o){var i=t.v,u=t.w;e.removeEdge(i,u),e.setEdge(o.v,o.w,{}),Fe(e),Me(e,n),function(e,n){var t=pe.A(e.nodes(),(function(e){return!n.node(e).parent})),o=function(e,n){return Ie(e,n,"pre")}(e,t);o=o.slice(1),r.A(o,(function(t){var r=e.node(t).parent,o=n.edge(t,r),i=!1;o||(o=n.edge(r,t),i=!0),n.node(t).rank=n.node(r).rank+(i?o.minlen:-o.minlen)}))}(e,n)}function Be(e,n,t){return t.low<=n.lim&&n.lim<=t.lim}function qe(e){switch(e.graph().ranker){case"network-simplex":default:ze(e);break;case"tight-tree":!function(e){ce(e),fe(e)}(e);break;case"longest-path":Ye(e)}}Te.initLowLimValues=Fe,Te.initCutValues=Me,Te.calcCutValue=Re,Te.leaveEdge=Se,Te.enterEdge=Ge,Te.exchangeEdges=Ve;var Ye=ce;function ze(e){Te(e)}var $e=t(38207),Je=t(89463);function Ze(e){var n=Z(e,"root",{},"_root"),t=function(e){var n={};function t(o,i){var u=e.children(o);u&&u.length&&r.A(u,(function(e){t(e,i+1)})),n[o]=i}return r.A(e.children(),(function(e){t(e,1)})),n}(e),o=F($e.A(t))-1,i=2*o+1;e.graph().nestingRoot=n,r.A(e.edges(),(function(n){e.edge(n).minlen*=i}));var u=function(e){return Je.A(e.edges(),(function(n,t){return n+e.edge(t).weight}),0)}(e)+1;r.A(e.children(),(function(r){He(e,n,i,u,o,t,r)})),e.graph().nodeRankFactor=i}function He(e,n,t,o,i,u,a){var s=e.children(a);if(s.length){var d=U(e,"_bt"),c=U(e,"_bb"),h=e.node(a);e.setParent(d,a),h.borderTop=d,e.setParent(c,a),h.borderBottom=c,r.A(s,(function(r){He(e,n,t,o,i,u,r);var s=e.node(r),h=s.borderTop?s.borderTop:r,f=s.borderBottom?s.borderBottom:r,v=s.borderTop?o:2*o,l=h!==f?1:i-u[a]+1;e.setEdge(d,h,{weight:v,minlen:l,nestingEdge:!0}),e.setEdge(f,c,{weight:v,minlen:l,nestingEdge:!0})})),e.parent(a)||e.setEdge(n,d,{weight:0,minlen:i+u[a]})}else a!==n&&e.setEdge(n,a,{weight:0,minlen:t})}var Ke=t(68675);const Qe=function(e){return(0,Ke.A)(e,5)};function Ue(e,n,t){var o=function(e){var n;for(;e.hasNode(n=u("_root")););return n}(e),i=new p.T({compound:!0}).setGraph({root:o}).setDefaultNodeLabel((function(n){return e.node(n)}));return r.A(e.nodes(),(function(u){var a=e.node(u),s=e.parent(u);(a.rank===n||a.minRank<=n&&n<=a.maxRank)&&(i.setNode(u),i.setParent(u,s||o),r.A(e[t](u),(function(n){var t=n.v===u?n.w:n.v,r=i.edge(t,u),o=q.A(r)?0:r.weight;i.setEdge(t,u,{weight:e.edge(n).weight+o})})),Object.prototype.hasOwnProperty.call(a,"minRank")&&i.setNode(u,{borderLeft:a.borderLeft[n],borderRight:a.borderRight[n]}))})),i}var We=t(52851);const Xe=function(e,n,t){for(var r=-1,o=e.length,i=n.length,u={};++rn||i&&u&&s&&!a&&!d||r&&u&&s||!t&&s||!o)return 1;if(!r&&!i&&!d&&e=a?s:s*("desc"==t[r]?-1:1)}return e.index-n.index};const hn=function(e,n,t){n=n.length?(0,tn.A)(n,(function(e){return(0,Ce.A)(e)?function(n){return(0,rn.A)(n,1===e.length?e[0]:e)}:e})):[R.A];var r=-1;n=(0,tn.A)(n,(0,an.A)(V.A));var o=(0,on.A)(e,(function(e,t,o){return{criteria:(0,tn.A)(n,(function(n){return n(e)})),index:++r,value:e}}));return un(o,(function(e,n){return cn(e,n,t)}))};const fn=(0,t(24326).A)((function(e,n){if(null==e)return[];var t=n.length;return t>1&&(0,v.A)(e,n[0],n[1])?n=[]:t>2&&(0,v.A)(n[0],n[1],n[2])&&(n=[n[0]]),hn(e,(0,nn.A)(n,1),[])}));function vn(e,n){for(var t=0,r=1;r0;)n%2&&(t+=c[n+1]),c[n=n-1>>1]+=e.weight;h+=e.weight*t}))),h}function gn(e,n){var t={};return r.A(e,(function(e,n){var r=t[e.v]={indegree:0,in:[],out:[],vs:[e.v],i:n};q.A(e.barycenter)||(r.barycenter=e.barycenter,r.weight=e.weight)})),r.A(n.edges(),(function(e){var n=t[e.v],r=t[e.w];q.A(n)||q.A(r)||(r.indegree++,n.out.push(t[e.w]))})),function(e){var n=[];function t(e){return function(n){n.merged||(q.A(n.barycenter)||q.A(e.barycenter)||n.barycenter>=e.barycenter)&&function(e,n){var t=0,r=0;e.weight&&(t+=e.barycenter*e.weight,r+=e.weight);n.weight&&(t+=n.barycenter*n.weight,r+=n.weight);e.vs=n.vs.concat(e.vs),e.barycenter=t/r,e.weight=r,e.i=Math.min(n.i,e.i),n.merged=!0}(e,n)}}function o(n){return function(t){t.in.push(n),0==--t.indegree&&e.push(t)}}for(;e.length;){var i=e.pop();n.push(i),r.A(i.in.reverse(),t(i)),r.A(i.out,o(i))}return d.A(Ae.A(n,(function(e){return!e.merged})),(function(e){return I(e,["vs","i","barycenter","weight"])}))}(Ae.A(t,(function(e){return!e.indegree})))}function pn(e,n){var t,o=function(e,n){var t={lhs:[],rhs:[]};return r.A(e,(function(e){n(e)?t.lhs.push(e):t.rhs.push(e)})),t}(e,(function(e){return Object.prototype.hasOwnProperty.call(e,"barycenter")})),i=o.lhs,u=fn(o.rhs,(function(e){return-e.i})),a=[],d=0,c=0,h=0;i.sort((t=!!n,function(e,n){return e.barycentern.barycenter?1:t?n.i-e.i:e.i-n.i})),h=An(a,u,h),r.A(i,(function(e){h+=e.vs.length,a.push(e.vs),d+=e.barycenter*e.weight,c+=e.weight,h=An(a,u,h)}));var f={vs:s.A(a)};return c&&(f.barycenter=d/c,f.weight=c),f}function An(e,n,t){for(var r;n.length&&(r=D.A(n)).i<=t;)n.pop(),e.push(r.vs),t++;return t}function wn(e,n,t,o){var i=e.children(n),u=e.node(n),a=u?u.borderLeft:void 0,c=u?u.borderRight:void 0,h={};a&&(i=Ae.A(i,(function(e){return e!==a&&e!==c})));var f=function(e,n){return d.A(n,(function(n){var t=e.inEdges(n);if(t.length){var r=Je.A(t,(function(n,t){var r=e.edge(t),o=e.node(t.v);return{sum:n.sum+r.weight*o.order,weight:n.weight+r.weight}}),{sum:0,weight:0});return{v:n,barycenter:r.sum/r.weight,weight:r.weight}}return{v:n}}))}(e,i);r.A(f,(function(n){if(e.children(n.v).length){var r=wn(e,n.v,t,o);h[n.v]=r,Object.prototype.hasOwnProperty.call(r,"barycenter")&&(i=n,u=r,q.A(i.barycenter)?(i.barycenter=u.barycenter,i.weight=u.weight):(i.barycenter=(i.barycenter*i.weight+u.barycenter*u.weight)/(i.weight+u.weight),i.weight+=u.weight))}var i,u}));var v=gn(f,t);!function(e,n){r.A(e,(function(e){e.vs=s.A(e.vs.map((function(e){return n[e]?n[e].vs:e})))}))}(v,h);var l=pn(v,o);if(a&&(l.vs=s.A([a,l.vs,c]),e.predecessors(a).length)){var g=e.node(e.predecessors(a)[0]),p=e.node(e.predecessors(c)[0]);Object.prototype.hasOwnProperty.call(l,"barycenter")||(l.barycenter=0,l.weight=0),l.barycenter=(l.barycenter*l.weight+g.order+p.order)/(l.weight+2),l.weight+=2}return l}function bn(e){var n=W(e),t=mn(e,g(1,n+1),"inEdges"),o=mn(e,g(n-1,-1,-1),"outEdges"),i=function(e){var n={},t=Ae.A(e.nodes(),(function(n){return!e.children(n).length})),o=F(d.A(t,(function(n){return e.node(n).rank}))),i=d.A(g(o+1),(function(){return[]})),u=fn(t,(function(n){return e.node(n).rank}));return r.A(u,(function t(o){if(!z.A(n,o)){n[o]=!0;var u=e.node(o);i[u.rank].push(o),r.A(e.successors(o),t)}})),i}(e);_n(e,i);for(var u,a=Number.POSITIVE_INFINITY,s=0,c=0;c<4;++s,++c){yn(s%2?t:o,s%4>=2);var h=vn(e,i=Q(e));hs||d>n[o].lim));i=o,o=r;for(;(o=e.parent(o))!==i;)a.push(o);return{path:u.concat(a.reverse()),lca:i}}(e,n,o.v,o.w),u=i.path,a=i.lca,s=0,d=u[s],c=!0;t!==o.w;){if(r=e.node(t),c){for(;(d=u[s])!==a&&e.node(d).maxRankt){var r=n;n=t,t=r}var o=e[n];o||(e[n]=o={}),o[t]=!0}function In(e,n,t){if(n>t){var r=n;n=t,t=r}return!!e[n]&&Object.prototype.hasOwnProperty.call(e[n],t)}function Ln(e,n,t,o,i){var u={},a=function(e,n,t,o){var i=new p.T,u=e.graph(),a=function(e,n,t){return function(r,o,i){var u,a=r.node(o),s=r.node(i),d=0;if(d+=a.width/2,Object.prototype.hasOwnProperty.call(a,"labelpos"))switch(a.labelpos.toLowerCase()){case"l":u=-a.width/2;break;case"r":u=a.width/2}if(u&&(d+=t?u:-u),u=0,d+=(a.dummy?n:e)/2,d+=(s.dummy?n:e)/2,d+=s.width/2,Object.prototype.hasOwnProperty.call(s,"labelpos"))switch(s.labelpos.toLowerCase()){case"l":u=s.width/2;break;case"r":u=-s.width/2}return u&&(d+=t?u:-u),u=0,d}}(u.nodesep,u.edgesep,o);return r.A(n,(function(n){var o;r.A(n,(function(n){var r=t[n];if(i.setNode(r),o){var u=t[o],s=i.edge(u,r);i.setEdge(u,r,Math.max(a(e,n,o),s||0))}o=n}))})),i}(e,n,t,i),s=i?"borderLeft":"borderRight";function d(e,n){for(var t=a.nodes(),r=t.pop(),o={};r;)o[r]?e(r):(o[r]=!0,t.push(r),t=t.concat(n(r))),r=t.pop()}return d((function(e){u[e]=a.inEdges(e).reduce((function(e,n){return Math.max(e,u[n.v]+a.edge(n))}),0)}),a.predecessors.bind(a)),d((function(n){var t=a.outEdges(n).reduce((function(e,n){return Math.min(e,u[n.w]-a.edge(n))}),Number.POSITIVE_INFINITY),r=e.node(n);t!==Number.POSITIVE_INFINITY&&r.borderType!==s&&(u[n]=Math.max(u[n],t))}),a.successors.bind(a)),r.A(o,(function(e){u[e]=u[t[e]]})),u}function Tn(e){var n,t=Q(e),o=O.A(jn(e,t),function(e,n){var t={};function o(n,o,i,u,a){var s;r.A(g(o,i),(function(o){s=n[o],e.node(s).dummy&&r.A(e.predecessors(s),(function(n){var r=e.node(n);r.dummy&&(r.ordera)&&Cn(t,n,s)}))}))}return Je.A(n,(function(n,t){var i,u=-1,a=0;return r.A(t,(function(r,s){if("border"===e.node(r).dummy){var d=e.predecessors(r);d.length&&(i=e.node(d[0]).order,o(t,a,s,u,i),a=s,u=i)}o(t,a,t.length,i,n.length)})),t})),t}(e,t)),i={};r.A(["u","d"],(function(u){n="u"===u?t:$e.A(t).reverse(),r.A(["l","r"],(function(t){"r"===t&&(n=d.A(n,(function(e){return $e.A(e).reverse()})));var a=("u"===u?e.predecessors:e.successors).bind(e),s=function(e,n,t,o){var i={},u={},a={};return r.A(n,(function(e){r.A(e,(function(e,n){i[e]=e,u[e]=e,a[e]=n}))})),r.A(n,(function(e){var n=-1;r.A(e,(function(e){var r=o(e);if(r.length){r=fn(r,(function(e){return a[e]}));for(var s=(r.length-1)/2,d=Math.floor(s),c=Math.ceil(s);d<=c;++d){var h=r[d];u[e]===e&&n{var n=t(" buildLayoutGraph",(()=>function(e){var n=new p.T({multigraph:!0,compound:!0}),t=$n(e.graph());return n.setGraph(O.A({},Dn,zn(t,Fn),I(t,Sn))),r.A(e.nodes(),(function(t){var r=$n(e.node(t));n.setNode(t,L.A(zn(r,Gn),Vn)),n.setParent(t,e.parent(t))})),r.A(e.edges(),(function(t){var r=$n(e.edge(t));n.setEdge(t,O.A({},qn,zn(r,Bn),I(r,Yn)))})),n}(e)));t(" runLayout",(()=>function(e,n){n(" makeSpaceForEdgeLabels",(()=>function(e){var n=e.graph();n.ranksep/=2,r.A(e.edges(),(function(t){var r=e.edge(t);r.minlen*=2,"c"!==r.labelpos.toLowerCase()&&("TB"===n.rankdir||"BT"===n.rankdir?r.width+=r.labeloffset:r.height+=r.labeloffset)}))}(e))),n(" removeSelfEdges",(()=>function(e){r.A(e.edges(),(function(n){if(n.v===n.w){var t=e.node(n.v);t.selfEdges||(t.selfEdges=[]),t.selfEdges.push({e:n,label:e.edge(n)}),e.removeEdge(n)}}))}(e))),n(" acyclic",(()=>x(e))),n(" nestingGraph.run",(()=>Ze(e))),n(" rank",(()=>qe(H(e)))),n(" injectEdgeLabelProxies",(()=>function(e){r.A(e.edges(),(function(n){var t=e.edge(n);if(t.width&&t.height){var r=e.node(n.v),o={rank:(e.node(n.w).rank-r.rank)/2+r.rank,e:n};Z(e,"edge-proxy",o,"_ep")}}))}(e))),n(" removeEmptyRanks",(()=>function(e){var n=Y.A(d.A(e.nodes(),(function(n){return e.node(n).rank}))),t=[];r.A(e.nodes(),(function(r){var o=e.node(r).rank-n;t[o]||(t[o]=[]),t[o].push(r)}));var o=0,i=e.graph().nodeRankFactor;r.A(t,(function(n,t){q.A(n)&&t%i!=0?--o:o&&r.A(n,(function(n){e.node(n).rank+=o}))}))}(e))),n(" nestingGraph.cleanup",(()=>function(e){var n=e.graph();e.removeNode(n.nestingRoot),delete n.nestingRoot,r.A(e.edges(),(function(n){e.edge(n).nestingEdge&&e.removeEdge(n)}))}(e))),n(" normalizeRanks",(()=>function(e){var n=Y.A(d.A(e.nodes(),(function(n){return e.node(n).rank})));r.A(e.nodes(),(function(t){var r=e.node(t);z.A(r,"rank")&&(r.rank-=n)}))}(e))),n(" assignRankMinMax",(()=>function(e){var n=0;r.A(e.nodes(),(function(t){var r=e.node(t);r.borderTop&&(r.minRank=e.node(r.borderTop).rank,r.maxRank=e.node(r.borderBottom).rank,n=F(n,r.maxRank))})),e.graph().maxRank=n}(e))),n(" removeEdgeLabelProxies",(()=>function(e){r.A(e.nodes(),(function(n){var t=e.node(n);"edge-proxy"===t.dummy&&(e.edge(t.e).labelRank=t.rank,e.removeNode(n))}))}(e))),n(" normalize.run",(()=>ae(e))),n(" parentDummyChains",(()=>En(e))),n(" addBorderSegments",(()=>function(e){r.A(e.children(),(function n(t){var o=e.children(t),i=e.node(t);if(o.length&&r.A(o,n),Object.prototype.hasOwnProperty.call(i,"minRank")){i.borderLeft=[],i.borderRight=[];for(var u=i.minRank,a=i.maxRank+1;ubn(e))),n(" insertSelfEdges",(()=>function(e){var n=Q(e);r.A(n,(function(n){var t=0;r.A(n,(function(n,o){var i=e.node(n);i.order=o+t,r.A(i.selfEdges,(function(n){Z(e,"selfedge",{width:n.label.width,height:n.label.height,rank:i.rank,order:o+ ++t,e:n.e,label:n.label},"_se")})),delete i.selfEdges}))}))}(e))),n(" adjustCoordinateSystem",(()=>function(e){var n=e.graph().rankdir.toLowerCase();"lr"!==n&&"rl"!==n||re(e)}(e))),n(" position",(()=>Mn(e))),n(" positionSelfEdges",(()=>function(e){r.A(e.nodes(),(function(n){var t=e.node(n);if("selfedge"===t.dummy){var r=e.node(t.e.v),o=r.x+r.width/2,i=r.y,u=t.x-o,a=r.height/2;e.setEdge(t.e,t.label),e.removeNode(n),t.label.points=[{x:o+2*u/3,y:i-a},{x:o+5*u/6,y:i-a},{x:o+u,y:i},{x:o+5*u/6,y:i+a},{x:o+2*u/3,y:i+a}],t.label.x=t.x,t.label.y=t.y}}))}(e))),n(" removeBorderNodes",(()=>function(e){r.A(e.nodes(),(function(n){if(e.children(n).length){var t=e.node(n),r=e.node(t.borderTop),o=e.node(t.borderBottom),i=e.node(D.A(t.borderLeft)),u=e.node(D.A(t.borderRight));t.width=Math.abs(u.x-i.x),t.height=Math.abs(o.y-r.y),t.x=i.x+t.width/2,t.y=r.y+t.height/2}})),r.A(e.nodes(),(function(n){"border"===e.node(n).dummy&&e.removeNode(n)}))}(e))),n(" normalize.undo",(()=>function(e){r.A(e.graph().dummyChains,(function(n){var t,r=e.node(n),o=r.edgeLabel;for(e.setEdge(r.edgeObj,o);r.dummy;)t=e.successors(n)[0],e.removeNode(n),o.points.push({x:r.x,y:r.y}),"edge-label"===r.dummy&&(o.x=r.x,o.y=r.y,o.width=r.width,o.height=r.height),n=t,r=e.node(n)}))}(e))),n(" fixupEdgeLabelCoords",(()=>function(e){r.A(e.edges(),(function(n){var t=e.edge(n);if(Object.prototype.hasOwnProperty.call(t,"x"))switch("l"!==t.labelpos&&"r"!==t.labelpos||(t.width-=t.labeloffset),t.labelpos){case"l":t.x-=t.width/2+t.labeloffset;break;case"r":t.x+=t.width/2+t.labeloffset}}))}(e))),n(" undoCoordinateSystem",(()=>te(e))),n(" translateGraph",(()=>function(e){var n=Number.POSITIVE_INFINITY,t=0,o=Number.POSITIVE_INFINITY,i=0,u=e.graph(),a=u.marginx||0,s=u.marginy||0;function d(e){var r=e.x,u=e.y,a=e.width,s=e.height;n=Math.min(n,r-a/2),t=Math.max(t,r+a/2),o=Math.min(o,u-s/2),i=Math.max(i,u+s/2)}r.A(e.nodes(),(function(n){d(e.node(n))})),r.A(e.edges(),(function(n){var t=e.edge(n);Object.prototype.hasOwnProperty.call(t,"x")&&d(t)})),n-=a,o-=s,r.A(e.nodes(),(function(t){var r=e.node(t);r.x-=n,r.y-=o})),r.A(e.edges(),(function(t){var i=e.edge(t);r.A(i.points,(function(e){e.x-=n,e.y-=o})),Object.prototype.hasOwnProperty.call(i,"x")&&(i.x-=n),Object.prototype.hasOwnProperty.call(i,"y")&&(i.y-=o)})),u.width=t-n+a,u.height=i-o+s}(e))),n(" assignNodeIntersects",(()=>function(e){r.A(e.edges(),(function(n){var t,r,o=e.edge(n),i=e.node(n.v),u=e.node(n.w);o.points?(t=o.points[0],r=o.points[o.points.length-1]):(o.points=[],t=u,r=i),o.points.unshift(K(i,t)),o.points.push(K(u,r))}))}(e))),n(" reversePoints",(()=>function(e){r.A(e.edges(),(function(n){var t=e.edge(n);t.reversed&&t.points.reverse()}))}(e))),n(" acyclic.undo",(()=>function(e){r.A(e.edges(),(function(n){var t=e.edge(n);if(t.reversed){e.removeEdge(n);var r=t.forwardName;delete t.reversed,delete t.forwardName,e.setEdge(n.w,n.v,t,r)}}))}(e)))}(n,t))),t(" updateInputGraph",(()=>function(e,n){r.A(e.nodes(),(function(t){var r=e.node(t),o=n.node(t);r&&(r.x=o.x,r.y=o.y,n.children(t).length&&(r.width=o.width,r.height=o.height))})),r.A(e.edges(),(function(t){var r=e.edge(t),o=n.edge(t);r.points=o.points,Object.prototype.hasOwnProperty.call(o,"x")&&(r.x=o.x,r.y=o.y)})),e.graph().width=n.graph().width,e.graph().height=n.graph().height}(e,n)))}))}var Fn=["nodesep","edgesep","ranksep","marginx","marginy"],Dn={ranksep:50,edgesep:20,nodesep:50,rankdir:"tb"},Sn=["acyclicer","ranker","rankdir","align"],Gn=["width","height"],Vn={width:0,height:0},Bn=["minlen","weight","width","height","labeloffset"],qn={minlen:1,weight:1,width:0,height:0,labeloffset:10,labelpos:"r"},Yn=["labelpos"];function zn(e,n){return B(I(e,n),Number)}function $n(e){var n={};return r.A(e,(function(e,t){n[t.toLowerCase()]=e})),n}},37981:(e,n,t)=>{t.d(n,{T:()=>m});var r=t(39142),o=t(89610),i=t(27422),u=t(94092),a=t(66401),s=t(8058),d=t(69592),c=t(13588),h=t(24326),f=t(99902),v=t(53533);const l=(0,h.A)((function(e){return(0,f.A)((0,c.A)(e,1,v.A,!0))}));var g=t(38207),p=t(89463),A="\0",w="\0",b="\x01";class m{constructor(e={}){this._isDirected=!Object.prototype.hasOwnProperty.call(e,"directed")||e.directed,this._isMultigraph=!!Object.prototype.hasOwnProperty.call(e,"multigraph")&&e.multigraph,this._isCompound=!!Object.prototype.hasOwnProperty.call(e,"compound")&&e.compound,this._label=void 0,this._defaultNodeLabelFn=r.A(void 0),this._defaultEdgeLabelFn=r.A(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[w]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(e){return this._label=e,this}graph(){return this._label}setDefaultNodeLabel(e){return o.A(e)||(e=r.A(e)),this._defaultNodeLabelFn=e,this}nodeCount(){return this._nodeCount}nodes(){return i.A(this._nodes)}sources(){var e=this;return u.A(this.nodes(),(function(n){return a.A(e._in[n])}))}sinks(){var e=this;return u.A(this.nodes(),(function(n){return a.A(e._out[n])}))}setNodes(e,n){var t=arguments,r=this;return s.A(e,(function(e){t.length>1?r.setNode(e,n):r.setNode(e)})),this}setNode(e,n){return Object.prototype.hasOwnProperty.call(this._nodes,e)?(arguments.length>1&&(this._nodes[e]=n),this):(this._nodes[e]=arguments.length>1?n:this._defaultNodeLabelFn(e),this._isCompound&&(this._parent[e]=w,this._children[e]={},this._children[w][e]=!0),this._in[e]={},this._preds[e]={},this._out[e]={},this._sucs[e]={},++this._nodeCount,this)}node(e){return this._nodes[e]}hasNode(e){return Object.prototype.hasOwnProperty.call(this._nodes,e)}removeNode(e){if(Object.prototype.hasOwnProperty.call(this._nodes,e)){var n=e=>this.removeEdge(this._edgeObjs[e]);delete this._nodes[e],this._isCompound&&(this._removeFromParentsChildList(e),delete this._parent[e],s.A(this.children(e),(e=>{this.setParent(e)})),delete this._children[e]),s.A(i.A(this._in[e]),n),delete this._in[e],delete this._preds[e],s.A(i.A(this._out[e]),n),delete this._out[e],delete this._sucs[e],--this._nodeCount}return this}setParent(e,n){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(d.A(n))n=w;else{for(var t=n+="";!d.A(t);t=this.parent(t))if(t===e)throw new Error("Setting "+n+" as parent of "+e+" would create a cycle");this.setNode(n)}return this.setNode(e),this._removeFromParentsChildList(e),this._parent[e]=n,this._children[n][e]=!0,this}_removeFromParentsChildList(e){delete this._children[this._parent[e]][e]}parent(e){if(this._isCompound){var n=this._parent[e];if(n!==w)return n}}children(e){if(d.A(e)&&(e=w),this._isCompound){var n=this._children[e];if(n)return i.A(n)}else{if(e===w)return this.nodes();if(this.hasNode(e))return[]}}predecessors(e){var n=this._preds[e];if(n)return i.A(n)}successors(e){var n=this._sucs[e];if(n)return i.A(n)}neighbors(e){var n=this.predecessors(e);if(n)return l(n,this.successors(e))}isLeaf(e){return 0===(this.isDirected()?this.successors(e):this.neighbors(e)).length}filterNodes(e){var n=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});n.setGraph(this.graph());var t=this;s.A(this._nodes,(function(t,r){e(r)&&n.setNode(r,t)})),s.A(this._edgeObjs,(function(e){n.hasNode(e.v)&&n.hasNode(e.w)&&n.setEdge(e,t.edge(e))}));var r={};function o(e){var i=t.parent(e);return void 0===i||n.hasNode(i)?(r[e]=i,i):i in r?r[i]:o(i)}return this._isCompound&&s.A(n.nodes(),(function(e){n.setParent(e,o(e))})),n}setDefaultEdgeLabel(e){return o.A(e)||(e=r.A(e)),this._defaultEdgeLabelFn=e,this}edgeCount(){return this._edgeCount}edges(){return g.A(this._edgeObjs)}setPath(e,n){var t=this,r=arguments;return p.A(e,(function(e,o){return r.length>1?t.setEdge(e,o,n):t.setEdge(e,o),o})),this}setEdge(){var e,n,t,r,o=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(e=i.v,n=i.w,t=i.name,2===arguments.length&&(r=arguments[1],o=!0)):(e=i,n=arguments[1],t=arguments[3],arguments.length>2&&(r=arguments[2],o=!0)),e=""+e,n=""+n,d.A(t)||(t=""+t);var u=E(this._isDirected,e,n,t);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,u))return o&&(this._edgeLabels[u]=r),this;if(!d.A(t)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(e),this.setNode(n),this._edgeLabels[u]=o?r:this._defaultEdgeLabelFn(e,n,t);var a=function(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}var a={v:o,w:i};r&&(a.name=r);return a}(this._isDirected,e,n,t);return e=a.v,n=a.w,Object.freeze(a),this._edgeObjs[u]=a,y(this._preds[n],e),y(this._sucs[e],n),this._in[n][u]=a,this._out[e][u]=a,this._edgeCount++,this}edge(e,n,t){var r=1===arguments.length?x(this._isDirected,arguments[0]):E(this._isDirected,e,n,t);return this._edgeLabels[r]}hasEdge(e,n,t){var r=1===arguments.length?x(this._isDirected,arguments[0]):E(this._isDirected,e,n,t);return Object.prototype.hasOwnProperty.call(this._edgeLabels,r)}removeEdge(e,n,t){var r=1===arguments.length?x(this._isDirected,arguments[0]):E(this._isDirected,e,n,t),o=this._edgeObjs[r];return o&&(e=o.v,n=o.w,delete this._edgeLabels[r],delete this._edgeObjs[r],_(this._preds[n],e),_(this._sucs[e],n),delete this._in[n][r],delete this._out[e][r],this._edgeCount--),this}inEdges(e,n){var t=this._in[e];if(t){var r=g.A(t);return n?u.A(r,(function(e){return e.v===n})):r}}outEdges(e,n){var t=this._out[e];if(t){var r=g.A(t);return n?u.A(r,(function(e){return e.w===n})):r}}nodeEdges(e,n){var t=this.inEdges(e,n);if(t)return t.concat(this.outEdges(e,n))}}function y(e,n){e[n]?e[n]++:e[n]=1}function _(e,n){--e[n]||delete e[n]}function E(e,n,t,r){var o=""+n,i=""+t;if(!e&&o>i){var u=o;o=i,i=u}return o+b+i+b+(d.A(r)?A:r)}function x(e,n){return E(e,n.v,n.w,n.name)}m.prototype._nodeCount=0,m.prototype._edgeCount=0},697:(e,n,t)=>{t.d(n,{T:()=>r.T});var r=t(37981)},72559:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(61882);const o=function(e,n,t){for(var o=-1,i=e.length;++o{t.d(n,{A:()=>r});const r=function(e,n){return e{t.d(n,{A:()=>i});var r=t(6240),o=t(38446);const i=function(e,n){var t=-1,i=(0,o.A)(e)?Array(e.length):[];return(0,r.A)(e,(function(e,r,o){i[++t]=n(e,r,o)})),i}},99354:(e,n,t)=>{t.d(n,{A:()=>c});var r=t(66318),o=t(52851),i=t(7819),u=t(25353),a=t(23149),s=t(30901);const d=function(e,n,t,r){if(!(0,a.A)(e))return e;for(var d=-1,c=(n=(0,i.A)(n,e)).length,h=c-1,f=e;null!=f&&++d{t.d(n,{A:()=>d});var r=t(24326),o=t(66984),i=t(6832),u=t(55615),a=Object.prototype,s=a.hasOwnProperty;const d=(0,r.A)((function(e,n){e=Object(e);var t=-1,r=n.length,d=r>2?n[2]:void 0;for(d&&(0,i.A)(n[0],n[1],d)&&(r=1);++t{t.d(n,{A:()=>c});var r=t(23958),o=t(38446),i=t(27422);const u=function(e){return function(n,t,u){var a=Object(n);if(!(0,o.A)(n)){var s=(0,r.A)(t,3);n=(0,i.A)(n),t=function(e){return s(a[e],e,a)}}var d=e(n,t,u);return d>-1?a[s?n[d]:d]:void 0}};var a=t(25707),s=t(18593),d=Math.max;const c=u((function(e,n,t){var o=null==e?0:e.length;if(!o)return-1;var i=null==t?0:(0,s.A)(t);return i<0&&(i=d(o+i,0)),(0,a.A)(e,(0,r.A)(n,3),i)}))},34098:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(13588);const o=function(e){return(null==e?0:e.length)?(0,r.A)(e,1):[]}},48585:(e,n,t)=>{t.d(n,{A:()=>u});var r=Object.prototype.hasOwnProperty;const o=function(e,n){return null!=e&&r.call(e,n)};var i=t(85054);const u=function(e,n){return null!=e&&(0,i.A)(e,n,o)}},9703:(e,n,t)=>{t.d(n,{A:()=>u});var r=t(88496),o=t(92049),i=t(53098);const u=function(e){return"string"==typeof e||!(0,o.A)(e)&&(0,i.A)(e)&&"[object String]"==(0,r.A)(e)}},26666:(e,n,t)=>{t.d(n,{A:()=>r});const r=function(e){var n=null==e?0:e.length;return n?e[n-1]:void 0}},74722:(e,n,t)=>{t.d(n,{A:()=>a});var r=t(45572),o=t(23958),i=t(52568),u=t(92049);const a=function(e,n){return((0,u.A)(e)?r.A:i.A)(e,(0,o.A)(n,3))}},86452:(e,n,t)=>{t.d(n,{A:()=>u});var r=t(72559),o=t(36224),i=t(29008);const u=function(e){return e&&e.length?(0,r.A)(e,i.A,o.A):void 0}},74342:(e,n,t)=>{t.d(n,{A:()=>g});var r=/\s/;const o=function(e){for(var n=e.length;n--&&r.test(e.charAt(n)););return n};var i=/^\s+/;const u=function(e){return e?e.slice(0,o(e)+1).replace(i,""):e};var a=t(23149),s=t(61882),d=/^[-+]0x[0-9a-f]+$/i,c=/^0b[01]+$/i,h=/^0o[0-7]+$/i,f=parseInt;const v=function(e){if("number"==typeof e)return e;if((0,s.A)(e))return NaN;if((0,a.A)(e)){var n="function"==typeof e.valueOf?e.valueOf():e;e=(0,a.A)(n)?n+"":n}if("string"!=typeof e)return 0===e?e:+e;e=u(e);var t=c.test(e);return t||h.test(e)?f(e.slice(2),t?2:8):d.test(e)?NaN:+e};var l=1/0;const g=function(e){return e?(e=v(e))===l||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},18593:(e,n,t)=>{t.d(n,{A:()=>o});var r=t(74342);const o=function(e){var n=(0,r.A)(e),t=n%1;return n==n?t?n-t:n:0}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2387.7f9ca256.js b/pr-preview/pr-976/assets/js/2387.7f9ca256.js new file mode 100644 index 0000000000..656ddac028 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2387.7f9ca256.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2387],{82387:(s,c,e)=>{e.d(c,{createGitGraphServices:()=>t.b});var t=e(82785);e(19369)}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2496d21b.1c09cf80.js b/pr-preview/pr-976/assets/js/2496d21b.1c09cf80.js new file mode 100644 index 0000000000..7e92ecb707 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2496d21b.1c09cf80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[995],{83495:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/docs/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/next/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/about/telemetry.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/next/features-limitations"}}');var r=n(74848),o=n(28453);const a={},i="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},o=s.createContext(r);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/250ffcdd.e9b01620.js b/pr-preview/pr-976/assets/js/250ffcdd.e9b01620.js new file mode 100644 index 0000000000..3f73f53d8e --- /dev/null +++ b/pr-preview/pr-976/assets/js/250ffcdd.e9b01620.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2343],{30106:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","source":"@site/versioned_docs/version-0.8/troubleshooting.md","sourceDirName":".","slug":"/troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.8/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/troubleshooting.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.8/deployment"},"next":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/0.8/components/overview"}}');var i=t(74848),s=t(28453);const a={},r="Troubleshooting",c={},d=[{value:"Logging",id:"logging",level:2},{value:"CLI",id:"cli",level:3},{value:"Coordinator and Initializer",id:"coordinator-and-initializer",level:3},{value:"Pod fails to start",id:"pod-fails-to-start",level:2},{value:"Regenerating the policies",id:"regenerating-the-policies",level:3},{value:"Pin container images",id:"pin-container-images",level:3},{value:"Validate Contrast components match",id:"validate-contrast-components-match",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section contains information on how to debug your Contrast deployment."}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"Collecting logs can be a good first step to identify problems in your\ndeployment. Both the CLI and the Contrast Coordinator as well as the Initializer\ncan be configured to emit additional logs."}),"\n",(0,i.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.p,{children:["The CLI logs can be configured with the ",(0,i.jsx)(n.code,{children:"--log-level"})," command-line flag, which\ncan be set to either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"})," or ",(0,i.jsx)(n.code,{children:"error"}),". The default is ",(0,i.jsx)(n.code,{children:"info"}),".\nSetting this to ",(0,i.jsx)(n.code,{children:"debug"})," can get more fine-grained information as to where the\nproblem lies."]}),"\n",(0,i.jsx)(n.h3,{id:"coordinator-and-initializer",children:"Coordinator and Initializer"}),"\n",(0,i.jsxs)(n.p,{children:["The logs from the Coordinator and the Initializer can be configured via the\nenvironment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"}),", ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," and\n",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"})," can be set to one of either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"}),", or\n",(0,i.jsx)(n.code,{children:"error"}),", similar to the CLI (defaults to ",(0,i.jsx)(n.code,{children:"info"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," can be set to ",(0,i.jsx)(n.code,{children:"text"})," or ",(0,i.jsx)(n.code,{children:"json"}),", determining the output\nformat (defaults to ",(0,i.jsx)(n.code,{children:"text"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," is a comma-seperated list of subsystems that should\nbe enabled for logging, which are disabled by default. Subsystems include:\n",(0,i.jsx)(n.code,{children:"snp-issuer"}),", ",(0,i.jsx)(n.code,{children:"kds-getter"}),", and ",(0,i.jsx)(n.code,{children:"snp-validator"}),". To enable all subsystems, use\n",(0,i.jsx)(n.code,{children:"*"})," as the value for this environment variable.\nWarnings and error messages from subsystems get printed regardless of whether\nthe subsystem is listed in the ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," environment variable."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"To configure debug logging with all subsystems for your Coordinator, add the\nfollowing variables to your container definition."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n containers:\n image: "ghcr.io/edgelesssys/contrast/coordinator:v0.8.1@sha256:bcd08a03096d38b350853c1dc8a595e0e8dd18e6af651bad4afd6838d842e257"\n name: coordinator\n env:\n - name: CONTRAST_LOG_LEVEL\n value: debug\n - name: CONTRAST_LOG_SUBSYSTEMS\n value: "*"\n # ...\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["While the Contrast Coordinator has a policy that allows certain configurations,\nthe Initializer and service mesh don't. When changing environment variables of other\nparts than the Coordinator, ensure to rerun ",(0,i.jsx)(n.code,{children:"contrast generate"})," to update the policy."]})}),"\n",(0,i.jsxs)(n.p,{children:["To access the logs generated by the Coordinator, you can use ",(0,i.jsx)(n.code,{children:"kubectl"})," with the\nfollowing command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl logs \n"})}),"\n",(0,i.jsx)(n.h2,{id:"pod-fails-to-start",children:"Pod fails to start"}),"\n",(0,i.jsxs)(n.p,{children:["If the Coordinator or a workload pod fails to even start, it can be helpful to\nlook at the events of the pod during the startup process using the ",(0,i.jsx)(n.code,{children:"describe"}),"\ncommand."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n events --for pod/\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'LAST SEEN TYPE REASON OBJECT MESSAGE\n32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"A common error, as in this example, is that the container creation was blocked by the\npolicy. Potential reasons are a modification of the deployment YAML without updating\nthe policies afterward, or a version mismatch between Contrast components."}),"\n",(0,i.jsx)(n.h3,{id:"regenerating-the-policies",children:"Regenerating the policies"}),"\n",(0,i.jsx)(n.p,{children:"To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated\npolicies, rerun"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast generate\n"})}),"\n",(0,i.jsx)(n.p,{children:"on your deployment. If any of the policy annotations change, re-deploy with the updated policies."}),"\n",(0,i.jsx)(n.h3,{id:"pin-container-images",children:"Pin container images"}),"\n",(0,i.jsx)(n.p,{children:"When generating the policies, Contrast will download the images specified in your deployment\nYAML and include their cryptographic identity. If the image tag is moved to another\ncontainer image after the policy has been generated, the image downloaded at deploy time\nwill differ from the one at generation time, and the policy enforcement won't allow the\ncontainer to be started in the pod VM."}),"\n",(0,i.jsxs)(n.p,{children:["To ensure the correct image is always used, pin the container image to a fixed ",(0,i.jsx)(n.code,{children:"sha256"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This way, the same image will still be pulled when the container tag (",(0,i.jsx)(n.code,{children:"22.04"}),") is moved\nto another image."]}),"\n",(0,i.jsx)(n.h3,{id:"validate-contrast-components-match",children:"Validate Contrast components match"}),"\n",(0,i.jsx)(n.p,{children:"A version mismatch between Contrast components can cause policy validation or attestation\nto fail. Each Contrast runtime is identifiable based on its (shortened) measurement value\nused to name the runtime class version."}),"\n",(0,i.jsx)(n.p,{children:"First, analyze which runtime class is currently installed in your cluster by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl get runtimeclasses\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give you output similar to the following one."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"NAME HANDLER AGE\ncontrast-cc-30bfa8706b542271ec9b7762bbb400af contrast-cc-30bfa8706b542271ec9b7762bbb400af 23d\ncontrast-cc-4d70a6e266cca46dfa8e41d92874e638 contrast-cc-4d70a6e266cca46dfa8e41d92874e638 7d\ncontrast-cc-b817659e094106f61bf6c178c27153ba contrast-cc-b817659e094106f61bf6c178c27153ba 2d19h\ncontrast-cc-beee79ca916b9e5dc59602788cbfb097 contrast-cc-beee79ca916b9e5dc59602788cbfb097 121m\nkata-cc-isolation kata-cc 45d\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided\nby the AKS CoCo preview, which isn't used by Contrast)."}),"\n",(0,i.jsx)(n.p,{children:"Next, check if the pod that won't start has the correct runtime class configured, and the\nCoordinator uses the exact same runtime:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n get -o=jsonpath='{.spec.runtimeClassName}' pod/\nkubectl -n get -o=jsonpath='{.spec.runtimeClassName}' pod/\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output should list the runtime class the pod is using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast-cc-beee79ca916b9e5dc59602788cbfb097\ncontrast-cc-beee79ca916b9e5dc59602788cbfb097\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Version information about the currently used CLI can be obtained via the ",(0,i.jsx)(n.code,{children:"version"})," flag:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast --version\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast version v0.X.0\n\n runtime handler: contrast-cc-beee79ca916b9e5dc59602788cbfb097\n launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35\n genpolicy version: 3.2.0.azl1.genpolicy0\n image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...\n ghcr.io/edgelesssys/contrast/initializer@sha256:...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/259f95a2.0c3a0ee9.js b/pr-preview/pr-976/assets/js/259f95a2.0c3a0ee9.js new file mode 100644 index 0000000000..04366167e1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/259f95a2.0c3a0ee9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8630],{83337:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"1.1","label":"1.1","banner":null,"badge":true,"noIndex":false,"className":"docs-version-1.1","isLast":true,"docsSidebars":{"docs":[{"type":"link","label":"What is Contrast?","href":"/contrast/pr-preview/pr-976/","docId":"intro","unlisted":false},{"type":"category","label":"Basics","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false},{"type":"link","label":"Bare metal setup","href":"/contrast/pr-preview/pr-976/getting-started/bare-metal","docId":"getting-started/bare-metal","unlisted":false}],"collapsible":true},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/deployment","docId":"deployment","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/contrast/pr-preview/pr-976/troubleshooting","docId":"troubleshooting","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Overview","href":"/contrast/pr-preview/pr-976/components/overview","docId":"components/overview","unlisted":false},{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Secrets & recovery","href":"/contrast/pr-preview/pr-976/architecture/secrets","docId":"architecture/secrets","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Security considerations","href":"/contrast/pr-preview/pr-976/architecture/security-considerations","docId":"architecture/security-considerations","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true}]},"docs":{"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"architecture/secrets":{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","sidebar":"docs"},"architecture/security-considerations":{"id":"architecture/security-considerations","title":"Security Considerations","description":"Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits).","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/overview":{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/bare-metal":{"id":"getting-started/bare-metal","title":"Prepare a bare-metal instance","description":"Hardware and firmware setup","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"troubleshooting":{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/26742c3b.ead769cd.js b/pr-preview/pr-976/assets/js/26742c3b.ead769cd.js new file mode 100644 index 0000000000..0d17e6cf01 --- /dev/null +++ b/pr-preview/pr-976/assets/js/26742c3b.ead769cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3108],{45694:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","source":"@site/versioned_docs/version-0.9/architecture/secrets.md","sourceDirName":"architecture","slug":"/architecture/secrets","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/secrets","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/architecture/secrets.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/attestation"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/certificates"}}');var i=r(74848),n=r(28453);const o={},a="Secrets & recovery",c={},d=[{value:"Persistence",id:"persistence",level:2},{value:"Recovery",id:"recovery",level:2}];function h(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"secrets--recovery",children:"Secrets & recovery"})}),"\n",(0,i.jsx)(t.p,{children:"When the Coordinator is configured with the initial manifest, it generates a random secret seed.\nFrom this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history.\nThis derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state."}),"\n",(0,i.jsxs)(t.p,{children:["The secret seed is returned to the user on the first call to ",(0,i.jsx)(t.code,{children:"contrast set"}),", encrypted with the user's public seed share owner key.\nIf no seed share owner key is provided, a key is generated and stored in the working directory."]}),"\n",(0,i.jsx)(t.h2,{id:"persistence",children:"Persistence"}),"\n",(0,i.jsxs)(t.p,{children:["The Coordinator runs as a ",(0,i.jsx)(t.code,{children:"StatefulSet"})," with a dynamically provisioned persistent volume.\nThis volume stores the manifest history and the associated runtime policies.\nThe manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads.\nHowever, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users.\nThus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed."]}),"\n",(0,i.jsx)(t.h2,{id:"recovery",children:"Recovery"}),"\n",(0,i.jsxs)(t.p,{children:["When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests.\nIt needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures.\nThis procedure is called recovery and is initiated by the workload owner.\nThe CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the ",(0,i.jsx)(t.code,{children:"Recover"})," method.\nThe Coordinator recovers its key material and verifies the manifest history signature."]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var s=r(96540);const i={},n=s.createContext(i);function o(e){const t=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/27004ef7.ee187533.js b/pr-preview/pr-976/assets/js/27004ef7.ee187533.js new file mode 100644 index 0000000000..ac751e0871 --- /dev/null +++ b/pr-preview/pr-976/assets/js/27004ef7.ee187533.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2154],{23003:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/versioned_docs/version-1.1/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/features-limitations.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/architecture/observability"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/about/telemetry"}}');var r=n(74848),s=n(28453);const o={},a="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2},{value:"Automatic recovery and high availability",id:"automatic-recovery-and-high-availability",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,r.jsx)(t.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,r.jsx)(t.h2,{id:"availability",children:"Availability"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Bare-metal support"}),": Support for running ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/getting-started/bare-metal",children:"Contrast on bare-metal Kubernetes"})," is available for AMD SEV-SNP and Intel TDX."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Persistent volumes"}),": Contrast only supports volumes with ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode",children:(0,r.jsx)(t.code,{children:"volumeMode: Block"})}),". These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Port forwarding"}),": This feature ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,r.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,r.jsx)(t.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,r.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,r.jsx)(t.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsx)(t.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,r.jsx)(t.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"automatic-recovery-and-high-availability",children:"Automatic recovery and high availability"}),"\n",(0,r.jsx)(t.p,{children:"The Contrast Coordinator is a singleton and can't be scaled to more than one instance.\nWhen this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually.\nIn a future release, we plan to support distributed Coordinator instances that can recover automatically."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const r={},s=i.createContext(r);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/270470f6.2a97a5fd.js b/pr-preview/pr-976/assets/js/270470f6.2a97a5fd.js new file mode 100644 index 0000000000..3a8befe4de --- /dev/null +++ b/pr-preview/pr-976/assets/js/270470f6.2a97a5fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8671],{67669:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-1.0/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/1.0/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/components/service-mesh.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/1.0/components/policies"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/attestation"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"CONTRAST_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"CONTRAST_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"##false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:""})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"##true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: CONTRAST_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v1.0.0@sha256:2aa3a6711ed8dee36a8dcdae63dd10b9fd5bb9aac6dba688ed1be8ab1fbb310e"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-secrets\n mountPath: /contrast\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"#:#:"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:""}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2763.b71509e9.js b/pr-preview/pr-976/assets/js/2763.b71509e9.js new file mode 100644 index 0000000000..d9bf880c68 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2763.b71509e9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2763],{86022:(e,t,a)=>{function i(e,t){e.accDescr&&t.setAccDescription?.(e.accDescr),e.accTitle&&t.setAccTitle?.(e.accTitle),e.title&&t.setDiagramTitle?.(e.title)}a.d(t,{S:()=>i}),(0,a(45567).K2)(i,"populateCommonDb")},62763:(e,t,a)=>{a.d(t,{diagram:()=>b});var i=a(86022),n=a(85039),r=a(61021),l=a(45567),s=a(78731),o=a(20007),c=l.UI.pie,p={sections:new Map,showData:!1,config:c},d=p.sections,g=p.showData,u=structuredClone(c),h=(0,l.K2)((()=>structuredClone(u)),"getConfig"),m=(0,l.K2)((()=>{d=new Map,g=p.showData,(0,l.IU)()}),"clear"),f=(0,l.K2)((({label:e,value:t})=>{d.has(e)||(d.set(e,t),l.Rm.debug(`added new section: ${e}, with value: ${t}`))}),"addSection"),S=(0,l.K2)((()=>d),"getSections"),x=(0,l.K2)((e=>{g=e}),"setShowData"),w=(0,l.K2)((()=>g),"getShowData"),D={getConfig:h,clear:m,setDiagramTitle:l.ke,getDiagramTitle:l.ab,setAccTitle:l.SV,getAccTitle:l.iN,setAccDescription:l.EI,getAccDescription:l.m7,addSection:f,getSections:S,setShowData:x,getShowData:w},T=(0,l.K2)(((e,t)=>{(0,i.S)(e,t),t.setShowData(e.showData),e.sections.map(t.addSection)}),"populateDb"),$={parse:(0,l.K2)((async e=>{const t=await(0,s.qg)("pie",e);l.Rm.debug(t),T(t,D)}),"parse")},y=(0,l.K2)((e=>`\n .pieCircle{\n stroke: ${e.pieStrokeColor};\n stroke-width : ${e.pieStrokeWidth};\n opacity : ${e.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${e.pieOuterStrokeColor};\n stroke-width: ${e.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${e.pieTitleTextSize};\n fill: ${e.pieTitleTextColor};\n font-family: ${e.fontFamily};\n }\n .slice {\n font-family: ${e.fontFamily};\n fill: ${e.pieSectionTextColor};\n font-size:${e.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${e.pieLegendTextColor};\n font-family: ${e.fontFamily};\n font-size: ${e.pieLegendTextSize};\n }\n`),"getStyles"),C=(0,l.K2)((e=>{const t=[...e.entries()].map((e=>({label:e[0],value:e[1]}))).sort(((e,t)=>t.value-e.value));return(0,o.rLf)().value((e=>e.value))(t)}),"createPieArcs"),b={parser:$,db:D,renderer:{draw:(0,l.K2)(((e,t,a,i)=>{l.Rm.debug("rendering pie chart\n"+e);const s=i.db,c=(0,l.D7)(),p=(0,n.$t)(s.getConfig(),c.pie),d=18,g=450,u=g,h=(0,r.D)(t),m=h.append("g");m.attr("transform","translate(225,225)");const{themeVariables:f}=c;let[S]=(0,n.I5)(f.pieOuterStrokeWidth);S??=2;const x=p.textPosition,w=Math.min(u,g)/2-40,D=(0,o.JLW)().innerRadius(0).outerRadius(w),T=(0,o.JLW)().innerRadius(w*x).outerRadius(w*x);m.append("circle").attr("cx",0).attr("cy",0).attr("r",w+S/2).attr("class","pieOuterCircle");const $=s.getSections(),y=C($),b=[f.pie1,f.pie2,f.pie3,f.pie4,f.pie5,f.pie6,f.pie7,f.pie8,f.pie9,f.pie10,f.pie11,f.pie12],k=(0,o.UMr)(b);m.selectAll("mySlices").data(y).enter().append("path").attr("d",D).attr("fill",(e=>k(e.data.label))).attr("class","pieCircle");let K=0;$.forEach((e=>{K+=e})),m.selectAll("mySlices").data(y).enter().append("text").text((e=>(e.data.value/K*100).toFixed(0)+"%")).attr("transform",(e=>"translate("+T.centroid(e)+")")).style("text-anchor","middle").attr("class","slice"),m.append("text").text(s.getDiagramTitle()).attr("x",0).attr("y",-200).attr("class","pieTitleText");const v=m.selectAll(".legend").data(k.domain()).enter().append("g").attr("class","legend").attr("transform",((e,t)=>"translate(216,"+(22*t-22*k.domain().length/2)+")"));v.append("rect").attr("width",d).attr("height",d).style("fill",k).style("stroke",k),v.data(y).append("text").attr("x",22).attr("y",14).text((e=>{const{label:t,value:a}=e.data;return s.getShowData()?`${t} [${a}]`:t}));const A=512+Math.max(...v.selectAll("text").nodes().map((e=>e?.getBoundingClientRect().width??0)));h.attr("viewBox",`0 0 ${A} 450`),(0,l.a$)(h,g,A,p.useMaxWidth)}),"draw")},styles:y}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/27a940ba.2b4c52be.js b/pr-preview/pr-976/assets/js/27a940ba.2b4c52be.js new file mode 100644 index 0000000000..bf54b48035 --- /dev/null +++ b/pr-preview/pr-976/assets/js/27a940ba.2b4c52be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5279],{85360:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-1.0/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/1.0/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/components/runtime.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/1.0/components/overview"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/1.0/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"cloud-hypervisor virtual machine manager (VMM)",id:"cloud-hypervisor-virtual-machine-manager-vmm",level:3},{value:"Tardev snapshotter",id:"tardev-snapshotter",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(62966).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"cloud-hypervisor-virtual-machine-manager-vmm",children:[(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," virtual machine manager (VMM)"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})})," to create a confidential virtual machine for every pod.\nThis requires the ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," binary to be installed on every node (responsibility of the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),")."]}),"\n",(0,i.jsx)(n.h3,{id:"tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"Tardev snapshotter"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses a special ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotter"]})," (",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})}),") to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},62966:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/27d05faa.4fff9fb7.js b/pr-preview/pr-976/assets/js/27d05faa.4fff9fb7.js new file mode 100644 index 0000000000..2d9d36c84d --- /dev/null +++ b/pr-preview/pr-976/assets/js/27d05faa.4fff9fb7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7697],{12346:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-0.6/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/0.6/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/about/telemetry.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"About","permalink":"/contrast/pr-preview/pr-976/0.6/about/"}}');var r=s(74848),o=s(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const r={},o=n.createContext(r);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2a2a0c40.fc2cf12c.js b/pr-preview/pr-976/assets/js/2a2a0c40.fc2cf12c.js new file mode 100644 index 0000000000..1c9784cda9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2a2a0c40.fc2cf12c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7292],{48672:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/docs/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/next/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/getting-started/install.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/next/basics/features"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup"}}');var r=n(74848),a=n(28453);const o={},l="Installation",c={},i=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>o,x:()=>l});var s=n(96540);const r={},a=s.createContext(r);function o(t){const e=s.useContext(a);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function l(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),s.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2dbe31cc.19015d41.js b/pr-preview/pr-976/assets/js/2dbe31cc.19015d41.js new file mode 100644 index 0000000000..8283c9a661 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2dbe31cc.19015d41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2700],{18856:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-0.7/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/0.7/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/components/service-mesh.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.7/components/policies"},"next":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"EDG_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"EDG_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"EDG_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"##false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:""})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"##true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: EDG_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.7.3@sha256:e297e9db93744445608f229d44479359313bc187a7f31e1a9c3c9b1d5407b5f6"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-tls-certs\n mountPath: /tls-config\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"#:#:"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:""}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2df6ad32.0df42417.js b/pr-preview/pr-976/assets/js/2df6ad32.0df42417.js new file mode 100644 index 0000000000..4c6fe7cffe --- /dev/null +++ b/pr-preview/pr-976/assets/js/2df6ad32.0df42417.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1597],{92258:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-1.0/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/1.0/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/deployment.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/1.0/examples/emojivoto"},"next":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/1.0/troubleshooting"}}');var o=t(74848),s=t(28453);const i={},a="Workload deployment",c={},l=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2},{value:"Recover the Coordinator",id:"recover-the-coordinator",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:t,Tabs:r}=n;return t||p("TabItem",!0),r||p("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,o.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,o.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,o.jsxs)(n.p,{children:["Contrast depends on a ",(0,o.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:["custom Kubernetes ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," (",(0,o.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,o.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/runtime.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/coordinator.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,o.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,o.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,o.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,o.jsxs)(r,{groupId:"yaml-source",children:[(0,o.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"helm",label:"helm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"copy",label:"copy",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,o.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,o.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,o.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,o.jsxs)(n.p,{children:["In the initialization process, the ",(0,o.jsx)(n.code,{children:"contrast-secrets"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,o.jsxs)(r,{groupId:"tls",children:[(0,o.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,o.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,o.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,o.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,o.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,o.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,o.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,o.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,o.jsxs)(n.p,{children:["During the ",(0,o.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,o.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,o.jsxs)(t,{value:"go",label:"Go integration",children:[(0,o.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,o.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,o.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,o.jsxs)(r,{groupId:"golang-tls-setup",children:[(0,o.jsx)(t,{value:"client",label:"Client",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,o.jsx)(t,{value:"server",label:"Server",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,o.jsxs)(n.p,{children:["Run the ",(0,o.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,o.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp resources/\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,o.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,o.jsxs)(r,{groupId:"injection",children:[(0,o.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,o.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,o.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,o.jsx)(n.code,{children:"generate"})," command."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp --skip-initializer resources/\n"})})]}),(0,o.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,o.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,o.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,o.jsx)(n.code,{children:"contrast-secrets"})," ",(0,o.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:v1.0.0@sha256:a86b8637016aff07fe157f6334f58033707f2d657263e956f195a5254e1ee9b5"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /contrast\n name: contrast-secrets\n volumes:\n - emptyDir: {}\n name: contrast-secrets\n'})}),"\n",(0,o.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,o.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,o.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,o.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,o.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,o.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,o.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,o.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,o.jsx)(n.p,{children:"This will use the reference values from the manifest file to attest the Coordinator.\nAfter this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,o.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,o.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,o.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the\nservice mesh root certificate and the history of manifests into the ",(0,o.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies\nreferenced in the active manifest are also written to the directory. The verification will fail if the active\nmanifest at the Coordinator doesn't match the manifest passed to the CLI."]}),"\n",(0,o.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,o.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,o.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,o.jsx)(n.h2,{id:"recover-the-coordinator",children:"Recover the Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material.\nFor demonstration purposes, you can simulate this scenario by deleting the Coordinator pod."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl delete pod -l app.kubernetes.io/name=coordinator\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet.\nYou can confirm this by running ",(0,o.jsx)(n.code,{children:"verify"})," again, or you can restart a workload pod, which should stay in the initialization phase.\nHowever, the secret seed in your working directory is sufficient to recover the coordinator."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast recover -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state.\nYou can now verify the Coordinator again, which should return the same manifest you set before."}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"The recovery process invalidates the mesh CA certificate:\nexisting workloads won't be able to communicate with workloads newly spawned.\nAll workloads should be restarted after the recovery succeeded."})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function p(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/2e82b444.dd4ac86b.js b/pr-preview/pr-976/assets/js/2e82b444.dd4ac86b.js new file mode 100644 index 0000000000..60b42b42e9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/2e82b444.dd4ac86b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6232],{91313:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-0.9/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/architecture/attestation.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.9/components/service-mesh"},"next":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/secrets"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(60483).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(8926).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nOn AMD SEV-SNP the hash of the policy is then added to the attestation report via the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field by the hypervisor.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(20957).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},20957:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},8926:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},60483:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/327db732.9cf7a097.js b/pr-preview/pr-976/assets/js/327db732.9cf7a097.js new file mode 100644 index 0000000000..0c551633ed --- /dev/null +++ b/pr-preview/pr-976/assets/js/327db732.9cf7a097.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1751],{59414:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>r,toc:()=>p});const r=JSON.parse('{"id":"getting-started/first-steps","title":"first-steps","description":"","source":"@site/versioned_docs/version-0.5/getting-started/first-steps.md","sourceDirName":"getting-started","slug":"/getting-started/first-steps","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/getting-started/first-steps.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup"},"next":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.5/examples/"}}');var n=s(74848),o=s(28453);const i={},a=void 0,c={},p=[];function d(t){return(0,n.jsx)(n.Fragment,{})}function u(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(d,{...t})}):d()}},28453:(t,e,s)=>{s.d(e,{R:()=>i,x:()=>a});var r=s(96540);const n={},o=r.createContext(n);function i(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(n):t.components||n:i(t.components),r.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/327e592d.77873d5f.js b/pr-preview/pr-976/assets/js/327e592d.77873d5f.js new file mode 100644 index 0000000000..2ade08092a --- /dev/null +++ b/pr-preview/pr-976/assets/js/327e592d.77873d5f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[388],{17160:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-0.9/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/0.9/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/basics/security-benefits.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.9/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(17317).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(27109).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},27109:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},17317:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3364.d54f19c0.js b/pr-preview/pr-976/assets/js/3364.d54f19c0.js new file mode 100644 index 0000000000..c51ca697a9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/3364.d54f19c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3364],{73364:(t,e,i)=>{i.d(e,{diagram:()=>v});var a=i(45567),n=i(20007),s=function(){var t=(0,a.K2)((function(t,e,i,a){for(i=i||{},a=t.length;a--;i[t[a]]=e);return i}),"o"),e=[1,3],i=[1,4],n=[1,5],s=[1,6],r=[1,7],o=[1,4,5,10,12,13,14,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],l=[1,4,5,10,12,13,14,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],h=[55,56,57],c=[2,36],d=[1,37],u=[1,36],x=[1,38],g=[1,35],f=[1,43],p=[1,41],y=[1,14],T=[1,23],m=[1,18],q=[1,19],A=[1,20],_=[1,21],b=[1,22],S=[1,24],k=[1,25],F=[1,26],P=[1,27],C=[1,28],L=[1,29],v=[1,32],I=[1,33],E=[1,34],D=[1,39],z=[1,40],w=[1,42],K=[1,44],U=[1,62],N=[1,61],R=[4,5,8,10,12,13,14,18,44,47,49,55,56,57,63,64,65,66,67],B=[1,65],W=[1,66],$=[1,67],Q=[1,68],O=[1,69],X=[1,70],H=[1,71],M=[1,72],Y=[1,73],j=[1,74],G=[1,75],V=[1,76],Z=[4,5,6,7,8,9,10,11,12,13,14,15,18],J=[1,90],tt=[1,91],et=[1,92],it=[1,99],at=[1,93],nt=[1,96],st=[1,94],rt=[1,95],ot=[1,97],lt=[1,98],ht=[1,102],ct=[10,55,56,57],dt=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],ut={trace:(0,a.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:(0,a.K2)((function(t,e,i,a,n,s,r){var o=s.length-1;switch(n){case 23:case 68:this.$=s[o];break;case 24:case 69:this.$=s[o-1]+""+s[o];break;case 26:this.$=s[o-1]+s[o];break;case 27:this.$=[s[o].trim()];break;case 28:s[o-2].push(s[o].trim()),this.$=s[o-2];break;case 29:this.$=s[o-4],a.addClass(s[o-2],s[o]);break;case 37:this.$=[];break;case 42:this.$=s[o].trim(),a.setDiagramTitle(this.$);break;case 43:this.$=s[o].trim(),a.setAccTitle(this.$);break;case 44:case 45:this.$=s[o].trim(),a.setAccDescription(this.$);break;case 46:a.addSection(s[o].substr(8)),this.$=s[o].substr(8);break;case 47:a.addPoint(s[o-3],"",s[o-1],s[o],[]);break;case 48:a.addPoint(s[o-4],s[o-3],s[o-1],s[o],[]);break;case 49:a.addPoint(s[o-4],"",s[o-2],s[o-1],s[o]);break;case 50:a.addPoint(s[o-5],s[o-4],s[o-2],s[o-1],s[o]);break;case 51:a.setXAxisLeftText(s[o-2]),a.setXAxisRightText(s[o]);break;case 52:s[o-1].text+=" \u27f6 ",a.setXAxisLeftText(s[o-1]);break;case 53:a.setXAxisLeftText(s[o]);break;case 54:a.setYAxisBottomText(s[o-2]),a.setYAxisTopText(s[o]);break;case 55:s[o-1].text+=" \u27f6 ",a.setYAxisBottomText(s[o-1]);break;case 56:a.setYAxisBottomText(s[o]);break;case 57:a.setQuadrant1Text(s[o]);break;case 58:a.setQuadrant2Text(s[o]);break;case 59:a.setQuadrant3Text(s[o]);break;case 60:a.setQuadrant4Text(s[o]);break;case 64:case 66:this.$={text:s[o],type:"text"};break;case 65:this.$={text:s[o-1].text+""+s[o],type:s[o-1].type};break;case 67:this.$={text:s[o],type:"markdown"}}}),"anonymous"),table:[{18:e,26:1,27:2,28:i,55:n,56:s,57:r},{1:[3]},{18:e,26:8,27:2,28:i,55:n,56:s,57:r},{18:e,26:9,27:2,28:i,55:n,56:s,57:r},t(o,[2,33],{29:10}),t(l,[2,61]),t(l,[2,62]),t(l,[2,63]),{1:[2,30]},{1:[2,31]},t(h,c,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:d,5:u,10:x,12:g,13:f,14:p,18:y,25:T,35:m,37:q,39:A,41:_,42:b,48:S,50:k,51:F,52:P,53:C,54:L,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(o,[2,34]),{27:45,55:n,56:s,57:r},t(h,[2,37]),t(h,c,{24:13,32:15,33:16,34:17,43:30,58:31,31:46,4:d,5:u,10:x,12:g,13:f,14:p,18:y,25:T,35:m,37:q,39:A,41:_,42:b,48:S,50:k,51:F,52:P,53:C,54:L,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(h,[2,39]),t(h,[2,40]),t(h,[2,41]),{36:[1,47]},{38:[1,48]},{40:[1,49]},t(h,[2,45]),t(h,[2,46]),{18:[1,50]},{4:d,5:u,10:x,12:g,13:f,14:p,43:51,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:52,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:53,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:54,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:55,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,10:x,12:g,13:f,14:p,43:56,58:31,60:v,61:I,63:E,64:D,65:z,66:w,67:K},{4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,44:[1,57],47:[1,58],58:60,59:59,63:E,64:D,65:z,66:w,67:K},t(R,[2,64]),t(R,[2,66]),t(R,[2,67]),t(R,[2,70]),t(R,[2,71]),t(R,[2,72]),t(R,[2,73]),t(R,[2,74]),t(R,[2,75]),t(R,[2,76]),t(R,[2,77]),t(R,[2,78]),t(R,[2,79]),t(R,[2,80]),t(o,[2,35]),t(h,[2,38]),t(h,[2,42]),t(h,[2,43]),t(h,[2,44]),{3:64,4:B,5:W,6:$,7:Q,8:O,9:X,10:H,11:M,12:Y,13:j,14:G,15:V,21:63},t(h,[2,53],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,49:[1,77],63:E,64:D,65:z,66:w,67:K}),t(h,[2,56],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,49:[1,78],63:E,64:D,65:z,66:w,67:K}),t(h,[2,57],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,58],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,59],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,60],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),{45:[1,79]},{44:[1,80]},t(R,[2,65]),t(R,[2,81]),t(R,[2,82]),t(R,[2,83]),{3:82,4:B,5:W,6:$,7:Q,8:O,9:X,10:H,11:M,12:Y,13:j,14:G,15:V,18:[1,81]},t(Z,[2,23]),t(Z,[2,1]),t(Z,[2,2]),t(Z,[2,3]),t(Z,[2,4]),t(Z,[2,5]),t(Z,[2,6]),t(Z,[2,7]),t(Z,[2,8]),t(Z,[2,9]),t(Z,[2,10]),t(Z,[2,11]),t(Z,[2,12]),t(h,[2,52],{58:31,43:83,4:d,5:u,10:x,12:g,13:f,14:p,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),t(h,[2,55],{58:31,43:84,4:d,5:u,10:x,12:g,13:f,14:p,60:v,61:I,63:E,64:D,65:z,66:w,67:K}),{46:[1,85]},{45:[1,86]},{4:J,5:tt,6:et,8:it,11:at,13:nt,16:89,17:st,18:rt,19:ot,20:lt,22:88,23:87},t(Z,[2,24]),t(h,[2,51],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,54],{59:59,58:60,4:d,5:u,8:U,10:x,12:g,13:f,14:p,18:N,63:E,64:D,65:z,66:w,67:K}),t(h,[2,47],{22:88,16:89,23:100,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),{46:[1,101]},t(h,[2,29],{10:ht}),t(ct,[2,27],{16:103,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),t(dt,[2,25]),t(dt,[2,13]),t(dt,[2,14]),t(dt,[2,15]),t(dt,[2,16]),t(dt,[2,17]),t(dt,[2,18]),t(dt,[2,19]),t(dt,[2,20]),t(dt,[2,21]),t(dt,[2,22]),t(h,[2,49],{10:ht}),t(h,[2,48],{22:88,16:89,23:104,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt}),{4:J,5:tt,6:et,8:it,11:at,13:nt,16:89,17:st,18:rt,19:ot,20:lt,22:105},t(dt,[2,26]),t(h,[2,50],{10:ht}),t(ct,[2,28],{16:103,4:J,5:tt,6:et,8:it,11:at,13:nt,17:st,18:rt,19:ot,20:lt})],defaultActions:{8:[2,30],9:[2,31]},parseError:(0,a.K2)((function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)}),"parseError"),parse:(0,a.K2)((function(t){var e=this,i=[0],n=[],s=[null],r=[],o=this.table,l="",h=0,c=0,d=0,u=r.slice.call(arguments,1),x=Object.create(this.lexer),g={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(g.yy[f]=this.yy[f]);x.setInput(t,g.yy),g.yy.lexer=x,g.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var p=x.yylloc;r.push(p);var y=x.options&&x.options.ranges;function T(){var t;return"number"!=typeof(t=n.pop()||x.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof g.yy.parseError?this.parseError=g.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,a.K2)((function(t){i.length=i.length-2*t,s.length=s.length-t,r.length=r.length-t}),"popStack"),(0,a.K2)(T,"lex");for(var m,q,A,_,b,S,k,F,P,C={};;){if(A=i[i.length-1],this.defaultActions[A]?_=this.defaultActions[A]:(null==m&&(m=T()),_=o[A]&&o[A][m]),void 0===_||!_.length||!_[0]){var L="";for(S in P=[],o[A])this.terminals_[S]&&S>2&&P.push("'"+this.terminals_[S]+"'");L=x.showPosition?"Parse error on line "+(h+1)+":\n"+x.showPosition()+"\nExpecting "+P.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(h+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(L,{text:x.match,token:this.terminals_[m]||m,line:x.yylineno,loc:p,expected:P})}if(_[0]instanceof Array&&_.length>1)throw new Error("Parse Error: multiple actions possible at state: "+A+", token: "+m);switch(_[0]){case 1:i.push(m),s.push(x.yytext),r.push(x.yylloc),i.push(_[1]),m=null,q?(m=q,q=null):(c=x.yyleng,l=x.yytext,h=x.yylineno,p=x.yylloc,d>0&&d--);break;case 2:if(k=this.productions_[_[1]][1],C.$=s[s.length-k],C._$={first_line:r[r.length-(k||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(k||1)].first_column,last_column:r[r.length-1].last_column},y&&(C._$.range=[r[r.length-(k||1)].range[0],r[r.length-1].range[1]]),void 0!==(b=this.performAction.apply(C,[l,c,h,g.yy,_[1],s,r].concat(u))))return b;k&&(i=i.slice(0,-1*k*2),s=s.slice(0,-1*k),r=r.slice(0,-1*k)),i.push(this.productions_[_[1]][0]),s.push(C.$),r.push(C._$),F=o[i[i.length-2]][i[i.length-1]],i.push(F);break;case 3:return!0}}return!0}),"parse")},xt=function(){return{EOF:1,parseError:(0,a.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,a.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,a.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,a.K2)((function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===a.length?this.yylloc.first_column:0)+a[a.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,a.K2)((function(){return this._more=!0,this}),"more"),reject:(0,a.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,a.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,a.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,a.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,a.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,a.K2)((function(t,e){var i,a,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in n)this[s]=n[s];return!1}return!1}),"test_match"),next:(0,a.K2)((function(){if(this.done)return this.EOF;var t,e,i,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),s=0;se[0].length)){if(e=i,a=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,n[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,a.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,a.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,a.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,a.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,a.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,a.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,a.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,a.K2)((function(t,e,i,a){switch(i){case 0:case 1:case 3:break;case 2:return 55;case 4:return this.begin("title"),35;case 5:return this.popState(),"title_value";case 6:return this.begin("acc_title"),37;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),39;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 23:case 25:case 31:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:return 48;case 14:return 50;case 15:return 49;case 16:return 51;case 17:return 52;case 18:return 53;case 19:return 54;case 20:return 25;case 21:this.begin("md_string");break;case 22:return"MD_STR";case 24:this.begin("string");break;case 26:return"STR";case 27:this.begin("class_name");break;case 28:return this.popState(),47;case 29:return this.begin("point_start"),44;case 30:return this.begin("point_x"),45;case 32:this.popState(),this.begin("point_y");break;case 33:return this.popState(),46;case 34:return 28;case 35:return 4;case 36:return 11;case 37:return 64;case 38:return 10;case 39:case 40:return 65;case 41:return 14;case 42:return 13;case 43:return 67;case 44:return 66;case 45:return 12;case 46:return 8;case 47:return 5;case 48:return 18;case 49:return 56;case 50:return 63;case 51:return 57}}),"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?: *x-axis *)/i,/^(?: *y-axis *)/i,/^(?: *--+> *)/i,/^(?: *quadrant-1 *)/i,/^(?: *quadrant-2 *)/i,/^(?: *quadrant-3 *)/i,/^(?: *quadrant-4 *)/i,/^(?:classDef\b)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?::::)/i,/^(?:^\w+)/i,/^(?:\s*:\s*\[\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?:\s*\] *)/i,/^(?:\s*,\s*)/i,/^(?:(1)|(0(.\d+)?))/i,/^(?: *quadrantChart *)/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s)/i,/^(?:;)/i,/^(?:[!"#$%&'*+,-.`?\\_/])/i,/^(?:$)/i],conditions:{class_name:{rules:[28],inclusive:!1},point_y:{rules:[33],inclusive:!1},point_x:{rules:[32],inclusive:!1},point_start:{rules:[30,31],inclusive:!1},acc_descr_multiline:{rules:[11,12],inclusive:!1},acc_descr:{rules:[9],inclusive:!1},acc_title:{rules:[7],inclusive:!1},title:{rules:[5],inclusive:!1},md_string:{rules:[22,23],inclusive:!1},string:{rules:[25,26],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,6,8,10,13,14,15,16,17,18,19,20,21,24,27,29,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],inclusive:!0}}}}();function gt(){this.yy={}}return ut.lexer=xt,(0,a.K2)(gt,"Parser"),gt.prototype=ut,ut.Parser=gt,new gt}();s.parser=s;var r=s,o=(0,a.P$)(),l=class{constructor(){this.classes=new Map,this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData()}static{(0,a.K2)(this,"QuadrantBuilder")}getDefaultData(){return{titleText:"",quadrant1Text:"",quadrant2Text:"",quadrant3Text:"",quadrant4Text:"",xAxisLeftText:"",xAxisRightText:"",yAxisBottomText:"",yAxisTopText:"",points:[]}}getDefaultConfig(){return{showXAxis:!0,showYAxis:!0,showTitle:!0,chartHeight:a.UI.quadrantChart?.chartWidth||500,chartWidth:a.UI.quadrantChart?.chartHeight||500,titlePadding:a.UI.quadrantChart?.titlePadding||10,titleFontSize:a.UI.quadrantChart?.titleFontSize||20,quadrantPadding:a.UI.quadrantChart?.quadrantPadding||5,xAxisLabelPadding:a.UI.quadrantChart?.xAxisLabelPadding||5,yAxisLabelPadding:a.UI.quadrantChart?.yAxisLabelPadding||5,xAxisLabelFontSize:a.UI.quadrantChart?.xAxisLabelFontSize||16,yAxisLabelFontSize:a.UI.quadrantChart?.yAxisLabelFontSize||16,quadrantLabelFontSize:a.UI.quadrantChart?.quadrantLabelFontSize||16,quadrantTextTopPadding:a.UI.quadrantChart?.quadrantTextTopPadding||5,pointTextPadding:a.UI.quadrantChart?.pointTextPadding||5,pointLabelFontSize:a.UI.quadrantChart?.pointLabelFontSize||12,pointRadius:a.UI.quadrantChart?.pointRadius||5,xAxisPosition:a.UI.quadrantChart?.xAxisPosition||"top",yAxisPosition:a.UI.quadrantChart?.yAxisPosition||"left",quadrantInternalBorderStrokeWidth:a.UI.quadrantChart?.quadrantInternalBorderStrokeWidth||1,quadrantExternalBorderStrokeWidth:a.UI.quadrantChart?.quadrantExternalBorderStrokeWidth||2}}getDefaultThemeConfig(){return{quadrant1Fill:o.quadrant1Fill,quadrant2Fill:o.quadrant2Fill,quadrant3Fill:o.quadrant3Fill,quadrant4Fill:o.quadrant4Fill,quadrant1TextFill:o.quadrant1TextFill,quadrant2TextFill:o.quadrant2TextFill,quadrant3TextFill:o.quadrant3TextFill,quadrant4TextFill:o.quadrant4TextFill,quadrantPointFill:o.quadrantPointFill,quadrantPointTextFill:o.quadrantPointTextFill,quadrantXAxisTextFill:o.quadrantXAxisTextFill,quadrantYAxisTextFill:o.quadrantYAxisTextFill,quadrantTitleFill:o.quadrantTitleFill,quadrantInternalBorderStrokeFill:o.quadrantInternalBorderStrokeFill,quadrantExternalBorderStrokeFill:o.quadrantExternalBorderStrokeFill}}clear(){this.config=this.getDefaultConfig(),this.themeConfig=this.getDefaultThemeConfig(),this.data=this.getDefaultData(),this.classes=new Map,a.Rm.info("clear called")}setData(t){this.data={...this.data,...t}}addPoints(t){this.data.points=[...t,...this.data.points]}addClass(t,e){this.classes.set(t,e)}setConfig(t){a.Rm.trace("setConfig called with: ",t),this.config={...this.config,...t}}setThemeConfig(t){a.Rm.trace("setThemeConfig called with: ",t),this.themeConfig={...this.themeConfig,...t}}calculateSpace(t,e,i,a){const n=2*this.config.xAxisLabelPadding+this.config.xAxisLabelFontSize,s={top:"top"===t&&e?n:0,bottom:"bottom"===t&&e?n:0},r=2*this.config.yAxisLabelPadding+this.config.yAxisLabelFontSize,o={left:"left"===this.config.yAxisPosition&&i?r:0,right:"right"===this.config.yAxisPosition&&i?r:0},l=this.config.titleFontSize+2*this.config.titlePadding,h={top:a?l:0},c=this.config.quadrantPadding+o.left,d=this.config.quadrantPadding+s.top+h.top,u=this.config.chartWidth-2*this.config.quadrantPadding-o.left-o.right,x=this.config.chartHeight-2*this.config.quadrantPadding-s.top-s.bottom-h.top;return{xAxisSpace:s,yAxisSpace:o,titleSpace:h,quadrantSpace:{quadrantLeft:c,quadrantTop:d,quadrantWidth:u,quadrantHalfWidth:u/2,quadrantHeight:x,quadrantHalfHeight:x/2}}}getAxisLabels(t,e,i,a){const{quadrantSpace:n,titleSpace:s}=a,{quadrantHalfHeight:r,quadrantHeight:o,quadrantLeft:l,quadrantHalfWidth:h,quadrantTop:c,quadrantWidth:d}=n,u=Boolean(this.data.xAxisRightText),x=Boolean(this.data.yAxisTopText),g=[];return this.data.xAxisLeftText&&e&&g.push({text:this.data.xAxisLeftText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.xAxisRightText&&e&&g.push({text:this.data.xAxisRightText,fill:this.themeConfig.quadrantXAxisTextFill,x:l+h+(u?h/2:0),y:"top"===t?this.config.xAxisLabelPadding+s.top:this.config.xAxisLabelPadding+c+o+this.config.quadrantPadding,fontSize:this.config.xAxisLabelFontSize,verticalPos:u?"center":"left",horizontalPos:"top",rotation:0}),this.data.yAxisBottomText&&i&&g.push({text:this.data.yAxisBottomText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+o-(x?r/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),this.data.yAxisTopText&&i&&g.push({text:this.data.yAxisTopText,fill:this.themeConfig.quadrantYAxisTextFill,x:"left"===this.config.yAxisPosition?this.config.yAxisLabelPadding:this.config.yAxisLabelPadding+l+d+this.config.quadrantPadding,y:c+r-(x?r/2:0),fontSize:this.config.yAxisLabelFontSize,verticalPos:x?"center":"left",horizontalPos:"top",rotation:-90}),g}getQuadrants(t){const{quadrantSpace:e}=t,{quadrantHalfHeight:i,quadrantLeft:a,quadrantHalfWidth:n,quadrantTop:s}=e,r=[{text:{text:this.data.quadrant1Text,fill:this.themeConfig.quadrant1TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:s,width:n,height:i,fill:this.themeConfig.quadrant1Fill},{text:{text:this.data.quadrant2Text,fill:this.themeConfig.quadrant2TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:s,width:n,height:i,fill:this.themeConfig.quadrant2Fill},{text:{text:this.data.quadrant3Text,fill:this.themeConfig.quadrant3TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a,y:s+i,width:n,height:i,fill:this.themeConfig.quadrant3Fill},{text:{text:this.data.quadrant4Text,fill:this.themeConfig.quadrant4TextFill,x:0,y:0,fontSize:this.config.quadrantLabelFontSize,verticalPos:"center",horizontalPos:"middle",rotation:0},x:a+n,y:s+i,width:n,height:i,fill:this.themeConfig.quadrant4Fill}];for(const o of r)o.text.x=o.x+o.width/2,0===this.data.points.length?(o.text.y=o.y+o.height/2,o.text.horizontalPos="middle"):(o.text.y=o.y+this.config.quadrantTextTopPadding,o.text.horizontalPos="top");return r}getQuadrantPoints(t){const{quadrantSpace:e}=t,{quadrantHeight:i,quadrantLeft:a,quadrantTop:s,quadrantWidth:r}=e,o=(0,n.m4Y)().domain([0,1]).range([a,r+a]),l=(0,n.m4Y)().domain([0,1]).range([i+s,s]);return this.data.points.map((t=>{const e=this.classes.get(t.className);e&&(t={...e,...t});return{x:o(t.x),y:l(t.y),fill:t.color??this.themeConfig.quadrantPointFill,radius:t.radius??this.config.pointRadius,text:{text:t.text,fill:this.themeConfig.quadrantPointTextFill,x:o(t.x),y:l(t.y)+this.config.pointTextPadding,verticalPos:"center",horizontalPos:"top",fontSize:this.config.pointLabelFontSize,rotation:0},strokeColor:t.strokeColor??this.themeConfig.quadrantPointFill,strokeWidth:t.strokeWidth??"0px"}}))}getBorders(t){const e=this.config.quadrantExternalBorderStrokeWidth/2,{quadrantSpace:i}=t,{quadrantHalfHeight:a,quadrantHeight:n,quadrantLeft:s,quadrantHalfWidth:r,quadrantTop:o,quadrantWidth:l}=i;return[{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-e,y1:o,x2:s+l+e,y2:o},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s+l,y1:o+e,x2:s+l,y2:o+n-e},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s-e,y1:o+n,x2:s+l+e,y2:o+n},{strokeFill:this.themeConfig.quadrantExternalBorderStrokeFill,strokeWidth:this.config.quadrantExternalBorderStrokeWidth,x1:s,y1:o+e,x2:s,y2:o+n-e},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+r,y1:o+e,x2:s+r,y2:o+n-e},{strokeFill:this.themeConfig.quadrantInternalBorderStrokeFill,strokeWidth:this.config.quadrantInternalBorderStrokeWidth,x1:s+e,y1:o+a,x2:s+l-e,y2:o+a}]}getTitle(t){if(t)return{text:this.data.titleText,fill:this.themeConfig.quadrantTitleFill,fontSize:this.config.titleFontSize,horizontalPos:"top",verticalPos:"center",rotation:0,y:this.config.titlePadding,x:this.config.chartWidth/2}}build(){const t=this.config.showXAxis&&!(!this.data.xAxisLeftText&&!this.data.xAxisRightText),e=this.config.showYAxis&&!(!this.data.yAxisTopText&&!this.data.yAxisBottomText),i=this.config.showTitle&&!!this.data.titleText,a=this.data.points.length>0?"bottom":this.config.xAxisPosition,n=this.calculateSpace(a,t,e,i);return{points:this.getQuadrantPoints(n),quadrants:this.getQuadrants(n),axisLabels:this.getAxisLabels(a,t,e,n),borderLines:this.getBorders(n),title:this.getTitle(i)}}},h=class extends Error{static{(0,a.K2)(this,"InvalidStyleError")}constructor(t,e,i){super(`value for ${t} ${e} is invalid, please use a valid ${i}`),this.name="InvalidStyleError"}};function c(t){return!/^#?([\dA-Fa-f]{6}|[\dA-Fa-f]{3})$/.test(t)}function d(t){return!/^\d+$/.test(t)}function u(t){return!/^\d+px$/.test(t)}(0,a.K2)(c,"validateHexCode"),(0,a.K2)(d,"validateNumber"),(0,a.K2)(u,"validateSizeInPixels");var x=(0,a.D7)();function g(t){return(0,a.jZ)(t.trim(),x)}(0,a.K2)(g,"textSanitizer");var f=new l;function p(t){f.setData({quadrant1Text:g(t.text)})}function y(t){f.setData({quadrant2Text:g(t.text)})}function T(t){f.setData({quadrant3Text:g(t.text)})}function m(t){f.setData({quadrant4Text:g(t.text)})}function q(t){f.setData({xAxisLeftText:g(t.text)})}function A(t){f.setData({xAxisRightText:g(t.text)})}function _(t){f.setData({yAxisTopText:g(t.text)})}function b(t){f.setData({yAxisBottomText:g(t.text)})}function S(t){const e={};for(const i of t){const[t,a]=i.trim().split(/\s*:\s*/);if("radius"===t){if(d(a))throw new h(t,a,"number");e.radius=parseInt(a)}else if("color"===t){if(c(a))throw new h(t,a,"hex code");e.color=a}else if("stroke-color"===t){if(c(a))throw new h(t,a,"hex code");e.strokeColor=a}else{if("stroke-width"!==t)throw new Error(`style named ${t} is not supported.`);if(u(a))throw new h(t,a,"number of pixels (eg. 10px)");e.strokeWidth=a}}return e}function k(t,e,i,a,n){const s=S(n);f.addPoints([{x:i,y:a,text:g(t.text),className:e,...s}])}function F(t,e){f.addClass(t,S(e))}function P(t){f.setConfig({chartWidth:t})}function C(t){f.setConfig({chartHeight:t})}function L(){const t=(0,a.D7)(),{themeVariables:e,quadrantChart:i}=t;return i&&f.setConfig(i),f.setThemeConfig({quadrant1Fill:e.quadrant1Fill,quadrant2Fill:e.quadrant2Fill,quadrant3Fill:e.quadrant3Fill,quadrant4Fill:e.quadrant4Fill,quadrant1TextFill:e.quadrant1TextFill,quadrant2TextFill:e.quadrant2TextFill,quadrant3TextFill:e.quadrant3TextFill,quadrant4TextFill:e.quadrant4TextFill,quadrantPointFill:e.quadrantPointFill,quadrantPointTextFill:e.quadrantPointTextFill,quadrantXAxisTextFill:e.quadrantXAxisTextFill,quadrantYAxisTextFill:e.quadrantYAxisTextFill,quadrantExternalBorderStrokeFill:e.quadrantExternalBorderStrokeFill,quadrantInternalBorderStrokeFill:e.quadrantInternalBorderStrokeFill,quadrantTitleFill:e.quadrantTitleFill}),f.setData({titleText:(0,a.ab)()}),f.build()}(0,a.K2)(p,"setQuadrant1Text"),(0,a.K2)(y,"setQuadrant2Text"),(0,a.K2)(T,"setQuadrant3Text"),(0,a.K2)(m,"setQuadrant4Text"),(0,a.K2)(q,"setXAxisLeftText"),(0,a.K2)(A,"setXAxisRightText"),(0,a.K2)(_,"setYAxisTopText"),(0,a.K2)(b,"setYAxisBottomText"),(0,a.K2)(S,"parseStyles"),(0,a.K2)(k,"addPoint"),(0,a.K2)(F,"addClass"),(0,a.K2)(P,"setWidth"),(0,a.K2)(C,"setHeight"),(0,a.K2)(L,"getQuadrantData");var v={parser:r,db:{setWidth:P,setHeight:C,setQuadrant1Text:p,setQuadrant2Text:y,setQuadrant3Text:T,setQuadrant4Text:m,setXAxisLeftText:q,setXAxisRightText:A,setYAxisTopText:_,setYAxisBottomText:b,parseStyles:S,addPoint:k,addClass:F,getQuadrantData:L,clear:(0,a.K2)((function(){f.clear(),(0,a.IU)()}),"clear"),setAccTitle:a.SV,getAccTitle:a.iN,setDiagramTitle:a.ke,getDiagramTitle:a.ab,getAccDescription:a.m7,setAccDescription:a.EI},renderer:{draw:(0,a.K2)(((t,e,i,s)=>{function r(t){return"top"===t?"hanging":"middle"}function o(t){return"left"===t?"start":"middle"}function l(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}(0,a.K2)(r,"getDominantBaseLine"),(0,a.K2)(o,"getTextAnchor"),(0,a.K2)(l,"getTransformation");const h=(0,a.D7)();a.Rm.debug("Rendering quadrant chart\n"+t);const c=h.securityLevel;let d;"sandbox"===c&&(d=(0,n.Ltv)("#i"+e));const u=("sandbox"===c?(0,n.Ltv)(d.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${e}"]`),x=u.append("g").attr("class","main"),g=h.quadrantChart?.chartWidth??500,f=h.quadrantChart?.chartHeight??500;(0,a.a$)(u,f,g,h.quadrantChart?.useMaxWidth??!0),u.attr("viewBox","0 0 "+g+" "+f),s.db.setHeight(f),s.db.setWidth(g);const p=s.db.getQuadrantData(),y=x.append("g").attr("class","quadrants"),T=x.append("g").attr("class","border"),m=x.append("g").attr("class","data-points"),q=x.append("g").attr("class","labels"),A=x.append("g").attr("class","title");p.title&&A.append("text").attr("x",0).attr("y",0).attr("fill",p.title.fill).attr("font-size",p.title.fontSize).attr("dominant-baseline",r(p.title.horizontalPos)).attr("text-anchor",o(p.title.verticalPos)).attr("transform",l(p.title)).text(p.title.text),p.borderLines&&T.selectAll("line").data(p.borderLines).enter().append("line").attr("x1",(t=>t.x1)).attr("y1",(t=>t.y1)).attr("x2",(t=>t.x2)).attr("y2",(t=>t.y2)).style("stroke",(t=>t.strokeFill)).style("stroke-width",(t=>t.strokeWidth));const _=y.selectAll("g.quadrant").data(p.quadrants).enter().append("g").attr("class","quadrant");_.append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)),_.append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>r(t.text.horizontalPos))).attr("text-anchor",(t=>o(t.text.verticalPos))).attr("transform",(t=>l(t.text))).text((t=>t.text.text));q.selectAll("g.label").data(p.axisLabels).enter().append("g").attr("class","label").append("text").attr("x",0).attr("y",0).text((t=>t.text)).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>r(t.horizontalPos))).attr("text-anchor",(t=>o(t.verticalPos))).attr("transform",(t=>l(t)));const b=m.selectAll("g.data-point").data(p.points).enter().append("g").attr("class","data-point");b.append("circle").attr("cx",(t=>t.x)).attr("cy",(t=>t.y)).attr("r",(t=>t.radius)).attr("fill",(t=>t.fill)).attr("stroke",(t=>t.strokeColor)).attr("stroke-width",(t=>t.strokeWidth)),b.append("text").attr("x",0).attr("y",0).text((t=>t.text.text)).attr("fill",(t=>t.text.fill)).attr("font-size",(t=>t.text.fontSize)).attr("dominant-baseline",(t=>r(t.text.horizontalPos))).attr("text-anchor",(t=>o(t.text.verticalPos))).attr("transform",(t=>l(t.text)))}),"draw")},styles:(0,a.K2)((()=>""),"styles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/35dd9928.876c8b6d.js b/pr-preview/pr-976/assets/js/35dd9928.876c8b6d.js new file mode 100644 index 0000000000..8412d1869a --- /dev/null +++ b/pr-preview/pr-976/assets/js/35dd9928.876c8b6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[95],{90087:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/docs/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/next/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/features-limitations.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/next/architecture/observability"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/next/about/telemetry"}}');var r=t(74848),s=t(28453);const a={},o="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2},{value:"Automatic recovery and high availability",id:"automatic-recovery-and-high-availability",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,r.jsx)(n.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,r.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,r.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Bare-metal support"}),": Support for running ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/bare-metal",children:"Contrast on bare-metal Kubernetes"})," is available for AMD SEV-SNP and Intel TDX."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Persistent volumes"}),": Contrast only supports volumes with ",(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode",children:(0,r.jsx)(n.code,{children:"volumeMode: Block"})}),". These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Port forwarding"}),": This feature ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,r.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,r.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,r.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Volume integrity checks"}),": Integrity checks don't cover any volume mounts, such as ",(0,r.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,r.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container, affect the service mesh implementation of Contrast.\nCurrently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,r.jsx)(n.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"automatic-recovery-and-high-availability",children:"Automatic recovery and high availability"}),"\n",(0,r.jsx)(n.p,{children:"The Contrast Coordinator is a singleton and can't be scaled to more than one instance.\nWhen this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually.\nIn a future release, we plan to support distributed Coordinator instances that can recover automatically."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var i=t(96540);const r={},s=i.createContext(r);function a(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3624.631ec2ee.js b/pr-preview/pr-976/assets/js/3624.631ec2ee.js new file mode 100644 index 0000000000..5ab8d6a88a --- /dev/null +++ b/pr-preview/pr-976/assets/js/3624.631ec2ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3624],{62062:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(29471);const o=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this};const c=function(t){return this.__data__.has(t)};function u(t){var n=-1,r=null==t?0:t.length;for(this.__data__=new e.A;++n{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length;++r{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length,o=0,c=[];++r{r.d(n,{A:()=>o});var e=r(60818);const o=function(t,n){return!!(null==t?0:t.length)&&(0,e.A)(t,n,0)>-1}},87809:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n,r){for(var e=-1,o=null==t?0:t.length;++e{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length,o=Array(e);++r{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=n.length,o=t.length;++r{r.d(n,{A:()=>e});const e=function(t,n){for(var r=-1,e=null==t?0:t.length;++r{r.d(n,{A:()=>Q});var e=r(11754),o=r(72641),c=r(52851),u=r(22031),a=r(27422);const i=function(t,n){return t&&(0,u.A)(n,(0,a.A)(n),t)};var f=r(55615);const A=function(t,n){return t&&(0,u.A)(n,(0,f.A)(n),t)};var s=r(80154),v=r(39759),l=r(14792);const b=function(t,n){return(0,u.A)(t,(0,l.A)(t),n)};var d=r(83511);const j=function(t,n){return(0,u.A)(t,(0,d.A)(t),n)};var p=r(19042),h=r(83973),y=r(9779),g=Object.prototype.hasOwnProperty;const w=function(t){var n=t.length,r=new t.constructor(n);return n&&"string"==typeof t[0]&&g.call(t,"index")&&(r.index=t.index,r.input=t.input),r};var _=r(90565);const O=function(t,n){var r=n?(0,_.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.byteLength)};var m=/\w*$/;const S=function(t){var n=new t.constructor(t.source,m.exec(t));return n.lastIndex=t.lastIndex,n};var k=r(241),E=k.A?k.A.prototype:void 0,x=E?E.valueOf:void 0;const I=function(t){return x?Object(x.call(t)):{}};var U=r(1801);const B=function(t,n,r){var e=t.constructor;switch(n){case"[object ArrayBuffer]":return(0,_.A)(t);case"[object Boolean]":case"[object Date]":return new e(+t);case"[object DataView]":return O(t,r);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return(0,U.A)(t,r);case"[object Map]":case"[object Set]":return new e;case"[object Number]":case"[object String]":return new e(t);case"[object RegExp]":return S(t);case"[object Symbol]":return I(t)}};var C=r(18598),D=r(92049),F=r(99912),M=r(53098);const z=function(t){return(0,M.A)(t)&&"[object Map]"==(0,y.A)(t)};var L=r(52789),P=r(64841),$=P.A&&P.A.isMap;const N=$?(0,L.A)($):z;var R=r(23149);const V=function(t){return(0,M.A)(t)&&"[object Set]"==(0,y.A)(t)};var G=P.A&&P.A.isSet;const W=G?(0,L.A)(G):V;var q="[object Arguments]",H="[object Function]",J="[object Object]",K={};K[q]=K["[object Array]"]=K["[object ArrayBuffer]"]=K["[object DataView]"]=K["[object Boolean]"]=K["[object Date]"]=K["[object Float32Array]"]=K["[object Float64Array]"]=K["[object Int8Array]"]=K["[object Int16Array]"]=K["[object Int32Array]"]=K["[object Map]"]=K["[object Number]"]=K[J]=K["[object RegExp]"]=K["[object Set]"]=K["[object String]"]=K["[object Symbol]"]=K["[object Uint8Array]"]=K["[object Uint8ClampedArray]"]=K["[object Uint16Array]"]=K["[object Uint32Array]"]=!0,K["[object Error]"]=K[H]=K["[object WeakMap]"]=!1;const Q=function t(n,r,u,l,d,g){var _,O=1&r,m=2&r,S=4&r;if(u&&(_=d?u(n,l,d,g):u(n)),void 0!==_)return _;if(!(0,R.A)(n))return n;var k=(0,D.A)(n);if(k){if(_=w(n),!O)return(0,v.A)(n,_)}else{var E=(0,y.A)(n),x=E==H||"[object GeneratorFunction]"==E;if((0,F.A)(n))return(0,s.A)(n,O);if(E==J||E==q||x&&!d){if(_=m||x?{}:(0,C.A)(n),!O)return m?j(n,A(_,n)):b(n,i(_,n))}else{if(!K[E])return d?n:{};_=B(n,E,O)}}g||(g=new e.A);var I=g.get(n);if(I)return I;g.set(n,_),W(n)?n.forEach((function(e){_.add(t(e,r,u,e,n,g))})):N(n)&&n.forEach((function(e,o){_.set(o,t(e,r,u,o,n,g))}));var U=S?m?h.A:p.A:m?f.A:a.A,M=k?void 0:U(n);return(0,o.A)(M||n,(function(e,o){M&&(e=n[o=e]),(0,c.A)(_,o,t(e,r,u,o,n,g))})),_}},6240:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(79841),o=r(38446);const c=function(t,n){return function(r,e){if(null==r)return r;if(!(0,o.A)(r))return t(r,e);for(var c=r.length,u=n?c:-1,a=Object(r);(n?u--:++u{r.d(n,{A:()=>o});var e=r(6240);const o=function(t,n){var r=[];return(0,e.A)(t,(function(t,e,o){n(t,e,o)&&r.push(t)})),r}},25707:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t,n,r,e){for(var o=t.length,c=r+(e?1:-1);e?c--:++c{r.d(n,{A:()=>f});var e=r(76912),o=r(241),c=r(52274),u=r(92049),a=o.A?o.A.isConcatSpreadable:void 0;const i=function(t){return(0,u.A)(t)||(0,c.A)(t)||!!(a&&t&&t[a])};const f=function t(n,r,o,c,u){var a=-1,f=n.length;for(o||(o=i),u||(u=[]);++a0&&o(A)?r>1?t(A,r-1,o,c,u):(0,e.A)(u,A):c||(u[u.length]=A)}return u}},79841:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(4574),o=r(27422);const c=function(t,n){return t&&(0,e.A)(t,n,o.A)}},66318:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(7819),o=r(30901);const c=function(t,n){for(var r=0,c=(n=(0,e.A)(n,t)).length;null!=t&&r{r.d(n,{A:()=>c});var e=r(76912),o=r(92049);const c=function(t,n,r){var c=n(t);return(0,o.A)(t)?c:(0,e.A)(c,r(t))}},60818:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(25707);const o=function(t){return t!=t};const c=function(t,n,r){for(var e=r-1,o=t.length;++e{r.d(n,{A:()=>J});var e=r(11754),o=r(62062),c=r(63736),u=r(64099);const a=function(t,n,r,e,a,i){var f=1&r,A=t.length,s=n.length;if(A!=s&&!(f&&s>A))return!1;var v=i.get(t),l=i.get(n);if(v&&l)return v==n&&l==t;var b=-1,d=!0,j=2&r?new o.A:void 0;for(i.set(t,n),i.set(n,t);++b{r.d(n,{A:()=>e});const e=function(t){return function(n){return null==n?void 0:n[t]}}},99902:(t,n,r)=>{r.d(n,{A:()=>s});var e=r(62062),o=r(83149),c=r(87809),u=r(64099),a=r(39857),i=r(42302),f=r(29959);const A=a.A&&1/(0,f.A)(new a.A([,-0]))[1]==1/0?function(t){return new a.A(t)}:i.A;const s=function(t,n,r){var a=-1,i=o.A,s=t.length,v=!0,l=[],b=l;if(r)v=!1,i=c.A;else if(s>=200){var d=n?null:A(t);if(d)return(0,f.A)(d);v=!1,i=u.A,b=new e.A}else b=n?[]:l;t:for(;++a{r.d(n,{A:()=>e});const e=function(t,n){return t.has(n)}},99922:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(29008);const o=function(t){return"function"==typeof t?t:e.A}},7819:(t,n,r)=>{r.d(n,{A:()=>A});var e=r(92049),o=r(86586),c=r(46632);var u=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g;const i=function(t){var n=(0,c.A)(t,(function(t){return 500===r.size&&r.clear(),t})),r=n.cache;return n}((function(t){var n=[];return 46===t.charCodeAt(0)&&n.push(""),t.replace(u,(function(t,r,e,o){n.push(e?o.replace(a,"$1"):r||t)})),n}));var f=r(28894);const A=function(t,n){return(0,e.A)(t)?t:(0,o.A)(t,n)?[t]:i((0,f.A)(t))}},19042:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(33831),o=r(14792),c=r(27422);const u=function(t){return(0,e.A)(t,c.A,o.A)}},83973:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(33831),o=r(83511),c=r(55615);const u=function(t){return(0,e.A)(t,c.A,o.A)}},14792:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(2634),o=r(13153),c=Object.prototype.propertyIsEnumerable,u=Object.getOwnPropertySymbols;const a=u?function(t){return null==t?[]:(t=Object(t),(0,e.A)(u(t),(function(n){return c.call(t,n)})))}:o.A},83511:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(76912),o=r(15647),c=r(14792),u=r(13153);const a=Object.getOwnPropertySymbols?function(t){for(var n=[];t;)(0,e.A)(n,(0,c.A)(t)),t=(0,o.A)(t);return n}:u.A},85054:(t,n,r)=>{r.d(n,{A:()=>f});var e=r(7819),o=r(52274),c=r(92049),u=r(25353),a=r(5254),i=r(30901);const f=function(t,n,r){for(var f=-1,A=(n=(0,e.A)(n,t)).length,s=!1;++f{r.d(n,{A:()=>a});var e=r(92049),o=r(61882),c=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,u=/^\w*$/;const a=function(t,n){if((0,e.A)(t))return!1;var r=typeof t;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=t&&!(0,o.A)(t))||(u.test(t)||!c.test(t)||null!=n&&t in Object(n))}},29959:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t){var n=-1,r=Array(t.size);return t.forEach((function(t){r[++n]=t})),r}},30901:(t,n,r)=>{r.d(n,{A:()=>o});var e=r(61882);const o=function(t){if("string"==typeof t||(0,e.A)(t))return t;var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},94092:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(2634),o=r(51790),c=r(23958),u=r(92049);const a=function(t,n){return((0,u.A)(t)?e.A:o.A)(t,(0,c.A)(n,3))}},8058:(t,n,r)=>{r.d(n,{A:()=>a});var e=r(72641),o=r(6240),c=r(99922),u=r(92049);const a=function(t,n){return((0,u.A)(t)?e.A:o.A)(t,(0,c.A)(n))}},39188:(t,n,r)=>{r.d(n,{A:()=>c});const e=function(t,n){return null!=t&&n in Object(t)};var o=r(85054);const c=function(t,n){return null!=t&&(0,o.A)(t,n,e)}},61882:(t,n,r)=>{r.d(n,{A:()=>c});var e=r(88496),o=r(53098);const c=function(t){return"symbol"==typeof t||(0,o.A)(t)&&"[object Symbol]"==(0,e.A)(t)}},69592:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(t){return void 0===t}},27422:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(83607),o=r(69471),c=r(38446);const u=function(t){return(0,c.A)(t)?(0,e.A)(t):(0,o.A)(t)}},42302:(t,n,r)=>{r.d(n,{A:()=>e});const e=function(){}},89463:(t,n,r)=>{r.d(n,{A:()=>i});const e=function(t,n,r,e){var o=-1,c=null==t?0:t.length;for(e&&c&&(r=t[++o]);++o{r.d(n,{A:()=>e});const e=function(){return[]}},28894:(t,n,r)=>{r.d(n,{A:()=>A});var e=r(241),o=r(45572),c=r(92049),u=r(61882),a=e.A?e.A.prototype:void 0,i=a?a.toString:void 0;const f=function t(n){if("string"==typeof n)return n;if((0,c.A)(n))return(0,o.A)(n,t)+"";if((0,u.A)(n))return i?i.call(n):"";var r=n+"";return"0"==r&&1/n==-1/0?"-0":r};const A=function(t){return null==t?"":f(t)}},38207:(t,n,r)=>{r.d(n,{A:()=>u});var e=r(45572);const o=function(t,n){return(0,e.A)(n,(function(n){return t[n]}))};var c=r(27422);const u=function(t){return null==t?[]:o(t,(0,c.A)(t))}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3683601e.e3d4185e.js b/pr-preview/pr-976/assets/js/3683601e.e3d4185e.js new file mode 100644 index 0000000000..557f01412d --- /dev/null +++ b/pr-preview/pr-976/assets/js/3683601e.e3d4185e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2987],{85863:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-0.9/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/0.9/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/deployment.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.9/examples/emojivoto"},"next":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.9/troubleshooting"}}');var o=t(74848),s=t(28453);const i={},a="Workload deployment",c={},l=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2},{value:"Recover the Coordinator",id:"recover-the-coordinator",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:t,Tabs:r}=n;return t||p("TabItem",!0),r||p("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,o.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,o.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,o.jsxs)(n.p,{children:["Contrast depends on a ",(0,o.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:["custom Kubernetes ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," (",(0,o.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,o.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/runtime.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/coordinator.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,o.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,o.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,o.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,o.jsxs)(r,{groupId:"yaml-source",children:[(0,o.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"helm",label:"helm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"copy",label:"copy",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,o.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,o.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,o.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,o.jsxs)(n.p,{children:["In the initialization process, the ",(0,o.jsx)(n.code,{children:"contrast-tls-certs"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,o.jsxs)(r,{groupId:"tls",children:[(0,o.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,o.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,o.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,o.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,o.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,o.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,o.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,o.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,o.jsxs)(n.p,{children:["During the ",(0,o.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,o.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,o.jsxs)(t,{value:"go",label:"Go integration",children:[(0,o.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,o.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,o.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,o.jsxs)(r,{groupId:"golang-tls-setup",children:[(0,o.jsx)(t,{value:"client",label:"Client",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,o.jsx)(t,{value:"server",label:"Server",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,o.jsxs)(n.p,{children:["Run the ",(0,o.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,o.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp resources/\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,o.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,o.jsxs)(r,{groupId:"injection",children:[(0,o.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,o.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,o.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,o.jsx)(n.code,{children:"generate"})," command."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp --skip-initializer resources/\n"})})]}),(0,o.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,o.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,o.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,o.jsx)(n.code,{children:"contrast-tls-certs"})," ",(0,o.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:v0.9.0@sha256:ca1ee62f9abb47224a70cb4b1a4593b3fa83481e083047ec707ded911baf134b"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /tls-config\n name: contrast-tls-certs\n volumes:\n - emptyDir: {}\n name: contrast-tls-certs\n'})}),"\n",(0,o.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,o.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,o.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,o.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,o.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,o.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,o.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,o.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,o.jsx)(n.p,{children:"This will use the reference values from the manifest file to attest the Coordinator.\nAfter this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,o.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,o.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,o.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the\nservice mesh root certificate and the history of manifests into the ",(0,o.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies\nreferenced in the active manifest are also written to the directory. The verification will fail if the active\nmanifest at the Coordinator doesn't match the manifest passed to the CLI."]}),"\n",(0,o.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,o.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,o.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,o.jsx)(n.h2,{id:"recover-the-coordinator",children:"Recover the Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material.\nFor demonstration purposes, you can simulate this scenario by deleting the Coordinator pod."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl delete pod -l app.kubernetes.io/name=coordinator\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet.\nYou can confirm this by running ",(0,o.jsx)(n.code,{children:"verify"})," again, or you can restart a workload pod, which should stay in the initialization phase.\nHowever, the secret seed in your working directory is sufficient to recover the coordinator."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast recover -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state.\nYou can now verify the Coordinator again, which should return the same manifest you set before."}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"The recovery process invalidates the mesh CA certificate:\nexisting workloads won't be able to communicate with workloads newly spawned.\nAll workloads should be restarted after the recovery succeeded."})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function p(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3840.510aef0e.js b/pr-preview/pr-976/assets/js/3840.510aef0e.js new file mode 100644 index 0000000000..dde42dd0d4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/3840.510aef0e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3840],{37981:(t,e,r)=>{r.d(e,{T:()=>w});var s=r(39142),a=r(89610),i=r(27422),n=r(94092),o=r(66401),l=r(8058),c=r(69592),d=r(13588),h=r(24326),g=r(99902),u=r(53533);const p=(0,h.A)((function(t){return(0,g.A)((0,d.A)(t,1,u.A,!0))}));var y=r(38207),b=r(89463),x="\0",f="\0",m="\x01";class w{constructor(t={}){this._isDirected=!Object.prototype.hasOwnProperty.call(t,"directed")||t.directed,this._isMultigraph=!!Object.prototype.hasOwnProperty.call(t,"multigraph")&&t.multigraph,this._isCompound=!!Object.prototype.hasOwnProperty.call(t,"compound")&&t.compound,this._label=void 0,this._defaultNodeLabelFn=s.A(void 0),this._defaultEdgeLabelFn=s.A(void 0),this._nodes={},this._isCompound&&(this._parent={},this._children={},this._children[f]={}),this._in={},this._preds={},this._out={},this._sucs={},this._edgeObjs={},this._edgeLabels={}}isDirected(){return this._isDirected}isMultigraph(){return this._isMultigraph}isCompound(){return this._isCompound}setGraph(t){return this._label=t,this}graph(){return this._label}setDefaultNodeLabel(t){return a.A(t)||(t=s.A(t)),this._defaultNodeLabelFn=t,this}nodeCount(){return this._nodeCount}nodes(){return i.A(this._nodes)}sources(){var t=this;return n.A(this.nodes(),(function(e){return o.A(t._in[e])}))}sinks(){var t=this;return n.A(this.nodes(),(function(e){return o.A(t._out[e])}))}setNodes(t,e){var r=arguments,s=this;return l.A(t,(function(t){r.length>1?s.setNode(t,e):s.setNode(t)})),this}setNode(t,e){return Object.prototype.hasOwnProperty.call(this._nodes,t)?(arguments.length>1&&(this._nodes[t]=e),this):(this._nodes[t]=arguments.length>1?e:this._defaultNodeLabelFn(t),this._isCompound&&(this._parent[t]=f,this._children[t]={},this._children[f][t]=!0),this._in[t]={},this._preds[t]={},this._out[t]={},this._sucs[t]={},++this._nodeCount,this)}node(t){return this._nodes[t]}hasNode(t){return Object.prototype.hasOwnProperty.call(this._nodes,t)}removeNode(t){if(Object.prototype.hasOwnProperty.call(this._nodes,t)){var e=t=>this.removeEdge(this._edgeObjs[t]);delete this._nodes[t],this._isCompound&&(this._removeFromParentsChildList(t),delete this._parent[t],l.A(this.children(t),(t=>{this.setParent(t)})),delete this._children[t]),l.A(i.A(this._in[t]),e),delete this._in[t],delete this._preds[t],l.A(i.A(this._out[t]),e),delete this._out[t],delete this._sucs[t],--this._nodeCount}return this}setParent(t,e){if(!this._isCompound)throw new Error("Cannot set parent in a non-compound graph");if(c.A(e))e=f;else{for(var r=e+="";!c.A(r);r=this.parent(r))if(r===t)throw new Error("Setting "+e+" as parent of "+t+" would create a cycle");this.setNode(e)}return this.setNode(t),this._removeFromParentsChildList(t),this._parent[t]=e,this._children[e][t]=!0,this}_removeFromParentsChildList(t){delete this._children[this._parent[t]][t]}parent(t){if(this._isCompound){var e=this._parent[t];if(e!==f)return e}}children(t){if(c.A(t)&&(t=f),this._isCompound){var e=this._children[t];if(e)return i.A(e)}else{if(t===f)return this.nodes();if(this.hasNode(t))return[]}}predecessors(t){var e=this._preds[t];if(e)return i.A(e)}successors(t){var e=this._sucs[t];if(e)return i.A(e)}neighbors(t){var e=this.predecessors(t);if(e)return p(e,this.successors(t))}isLeaf(t){return 0===(this.isDirected()?this.successors(t):this.neighbors(t)).length}filterNodes(t){var e=new this.constructor({directed:this._isDirected,multigraph:this._isMultigraph,compound:this._isCompound});e.setGraph(this.graph());var r=this;l.A(this._nodes,(function(r,s){t(s)&&e.setNode(s,r)})),l.A(this._edgeObjs,(function(t){e.hasNode(t.v)&&e.hasNode(t.w)&&e.setEdge(t,r.edge(t))}));var s={};function a(t){var i=r.parent(t);return void 0===i||e.hasNode(i)?(s[t]=i,i):i in s?s[i]:a(i)}return this._isCompound&&l.A(e.nodes(),(function(t){e.setParent(t,a(t))})),e}setDefaultEdgeLabel(t){return a.A(t)||(t=s.A(t)),this._defaultEdgeLabelFn=t,this}edgeCount(){return this._edgeCount}edges(){return y.A(this._edgeObjs)}setPath(t,e){var r=this,s=arguments;return b.A(t,(function(t,a){return s.length>1?r.setEdge(t,a,e):r.setEdge(t,a),a})),this}setEdge(){var t,e,r,s,a=!1,i=arguments[0];"object"==typeof i&&null!==i&&"v"in i?(t=i.v,e=i.w,r=i.name,2===arguments.length&&(s=arguments[1],a=!0)):(t=i,e=arguments[1],r=arguments[3],arguments.length>2&&(s=arguments[2],a=!0)),t=""+t,e=""+e,c.A(r)||(r=""+r);var n=k(this._isDirected,t,e,r);if(Object.prototype.hasOwnProperty.call(this._edgeLabels,n))return a&&(this._edgeLabels[n]=s),this;if(!c.A(r)&&!this._isMultigraph)throw new Error("Cannot set a named edge when isMultigraph = false");this.setNode(t),this.setNode(e),this._edgeLabels[n]=a?s:this._defaultEdgeLabelFn(t,e,r);var o=function(t,e,r,s){var a=""+e,i=""+r;if(!t&&a>i){var n=a;a=i,i=n}var o={v:a,w:i};s&&(o.name=s);return o}(this._isDirected,t,e,r);return t=o.v,e=o.w,Object.freeze(o),this._edgeObjs[n]=o,_(this._preds[e],t),_(this._sucs[t],e),this._in[e][n]=o,this._out[t][n]=o,this._edgeCount++,this}edge(t,e,r){var s=1===arguments.length?S(this._isDirected,arguments[0]):k(this._isDirected,t,e,r);return this._edgeLabels[s]}hasEdge(t,e,r){var s=1===arguments.length?S(this._isDirected,arguments[0]):k(this._isDirected,t,e,r);return Object.prototype.hasOwnProperty.call(this._edgeLabels,s)}removeEdge(t,e,r){var s=1===arguments.length?S(this._isDirected,arguments[0]):k(this._isDirected,t,e,r),a=this._edgeObjs[s];return a&&(t=a.v,e=a.w,delete this._edgeLabels[s],delete this._edgeObjs[s],L(this._preds[e],t),L(this._sucs[t],e),delete this._in[e][s],delete this._out[t][s],this._edgeCount--),this}inEdges(t,e){var r=this._in[t];if(r){var s=y.A(r);return e?n.A(s,(function(t){return t.v===e})):s}}outEdges(t,e){var r=this._out[t];if(r){var s=y.A(r);return e?n.A(s,(function(t){return t.w===e})):s}}nodeEdges(t,e){var r=this.inEdges(t,e);if(r)return r.concat(this.outEdges(t,e))}}function _(t,e){t[e]?t[e]++:t[e]=1}function L(t,e){--t[e]||delete t[e]}function k(t,e,r,s){var a=""+e,i=""+r;if(!t&&a>i){var n=a;a=i,i=n}return a+m+i+m+(c.A(s)?x:s)}function S(t,e){return k(t,e.v,e.w,e.name)}w.prototype._nodeCount=0,w.prototype._edgeCount=0},697:(t,e,r)=>{r.d(e,{T:()=>s.T});var s=r(37981)},75937:(t,e,r)=>{r.d(e,{A:()=>i});var s=r(72453),a=r(74886);const i=(t,e)=>s.A.lang.round(a.A.parse(t)[e])},50053:(t,e,r)=>{r.d(e,{A:()=>a});var s=r(68675);const a=function(t){return(0,s.A)(t,4)}},53840:(t,e,r)=>{r.d(e,{diagram:()=>fe});var s=r(52294),a=r(62392),i=r(86825),n=r(85039),o=r(45567),l=r(50053),c=r(75937),d=r(25582),h=r(20007),g=r(697),u=function(){var t=(0,o.K2)((function(t,e,r,s){for(r=r||{},s=t.length;s--;r[t[s]]=e);return r}),"o"),e=[1,7],r=[1,13],s=[1,14],a=[1,15],i=[1,19],n=[1,16],l=[1,17],c=[1,18],d=[8,30],h=[8,21,28,29,30,31,32,40,44,47],g=[1,23],u=[1,24],p=[8,15,16,21,28,29,30,31,32,40,44,47],y=[8,15,16,21,27,28,29,30,31,32,40,44,47],b=[1,49],x={trace:(0,o.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,block:31,NODE_ID:32,nodeShapeNLabel:33,dirList:34,DIR:35,NODE_DSTART:36,NODE_DEND:37,BLOCK_ARROW_START:38,BLOCK_ARROW_END:39,classDef:40,CLASSDEF_ID:41,CLASSDEF_STYLEOPTS:42,DEFAULT:43,class:44,CLASSENTITY_IDS:45,STYLECLASS:46,style:47,STYLE_ENTITY_IDS:48,STYLE_DEFINITION_DATA:49,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"block",32:"NODE_ID",35:"DIR",36:"NODE_DSTART",37:"NODE_DEND",38:"BLOCK_ARROW_START",39:"BLOCK_ARROW_END",40:"classDef",41:"CLASSDEF_ID",42:"CLASSDEF_STYLEOPTS",43:"DEFAULT",44:"class",45:"CLASSENTITY_IDS",46:"STYLECLASS",47:"style",48:"STYLE_ENTITY_IDS",49:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[34,1],[34,2],[33,3],[33,4],[23,3],[23,3],[24,3],[25,3]],performAction:(0,o.K2)((function(t,e,r,s,a,i,n){var o=i.length-1;switch(a){case 4:s.getLogger().debug("Rule: separator (NL) ");break;case 5:s.getLogger().debug("Rule: separator (Space) ");break;case 6:s.getLogger().debug("Rule: separator (EOF) ");break;case 7:s.getLogger().debug("Rule: hierarchy: ",i[o-1]),s.setHierarchy(i[o-1]);break;case 8:s.getLogger().debug("Stop NL ");break;case 9:s.getLogger().debug("Stop EOF ");break;case 10:s.getLogger().debug("Stop NL2 ");break;case 11:s.getLogger().debug("Stop EOF2 ");break;case 12:s.getLogger().debug("Rule: statement: ",i[o]),"number"==typeof i[o].length?this.$=i[o]:this.$=[i[o]];break;case 13:s.getLogger().debug("Rule: statement #2: ",i[o-1]),this.$=[i[o-1]].concat(i[o]);break;case 14:s.getLogger().debug("Rule: link: ",i[o],t),this.$={edgeTypeStr:i[o],label:""};break;case 15:s.getLogger().debug("Rule: LABEL link: ",i[o-3],i[o-1],i[o]),this.$={edgeTypeStr:i[o],label:i[o-1]};break;case 18:const e=parseInt(i[o]),r=s.generateId();this.$={id:r,type:"space",label:"",width:e,children:[]};break;case 23:s.getLogger().debug("Rule: (nodeStatement link node) ",i[o-2],i[o-1],i[o]," typestr: ",i[o-1].edgeTypeStr);const a=s.edgeStrToEdgeData(i[o-1].edgeTypeStr);this.$=[{id:i[o-2].id,label:i[o-2].label,type:i[o-2].type,directions:i[o-2].directions},{id:i[o-2].id+"-"+i[o].id,start:i[o-2].id,end:i[o].id,label:i[o-1].label,type:"edge",directions:i[o].directions,arrowTypeEnd:a,arrowTypeStart:"arrow_open"},{id:i[o].id,label:i[o].label,type:s.typeStr2Type(i[o].typeStr),directions:i[o].directions}];break;case 24:s.getLogger().debug("Rule: nodeStatement (abc88 node size) ",i[o-1],i[o]),this.$={id:i[o-1].id,label:i[o-1].label,type:s.typeStr2Type(i[o-1].typeStr),directions:i[o-1].directions,widthInColumns:parseInt(i[o],10)};break;case 25:s.getLogger().debug("Rule: nodeStatement (node) ",i[o]),this.$={id:i[o].id,label:i[o].label,type:s.typeStr2Type(i[o].typeStr),directions:i[o].directions,widthInColumns:1};break;case 26:s.getLogger().debug("APA123",this?this:"na"),s.getLogger().debug("COLUMNS: ",i[o]),this.$={type:"column-setting",columns:"auto"===i[o]?-1:parseInt(i[o])};break;case 27:s.getLogger().debug("Rule: id-block statement : ",i[o-2],i[o-1]);s.generateId();this.$={...i[o-2],type:"composite",children:i[o-1]};break;case 28:s.getLogger().debug("Rule: blockStatement : ",i[o-2],i[o-1],i[o]);const n=s.generateId();this.$={id:n,type:"composite",label:"",children:i[o-1]};break;case 29:s.getLogger().debug("Rule: node (NODE_ID separator): ",i[o]),this.$={id:i[o]};break;case 30:s.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",i[o-1],i[o]),this.$={id:i[o-1],label:i[o].label,typeStr:i[o].typeStr,directions:i[o].directions};break;case 31:s.getLogger().debug("Rule: dirList: ",i[o]),this.$=[i[o]];break;case 32:s.getLogger().debug("Rule: dirList: ",i[o-1],i[o]),this.$=[i[o-1]].concat(i[o]);break;case 33:s.getLogger().debug("Rule: nodeShapeNLabel: ",i[o-2],i[o-1],i[o]),this.$={typeStr:i[o-2]+i[o],label:i[o-1]};break;case 34:s.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",i[o-3],i[o-2]," #3:",i[o-1],i[o]),this.$={typeStr:i[o-3]+i[o],label:i[o-2],directions:i[o-1]};break;case 35:case 36:this.$={type:"classDef",id:i[o-1].trim(),css:i[o].trim()};break;case 37:this.$={type:"applyClass",id:i[o-1].trim(),styleClass:i[o].trim()};break;case 38:this.$={type:"applyStyles",id:i[o-1].trim(),stylesStr:i[o].trim()}}}),"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{11:3,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:s,31:a,32:i,40:n,44:l,47:c},{8:[1,20]},t(d,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,21:e,28:r,29:s,31:a,32:i,40:n,44:l,47:c}),t(h,[2,16],{14:22,15:g,16:u}),t(h,[2,17]),t(h,[2,18]),t(h,[2,19]),t(h,[2,20]),t(h,[2,21]),t(h,[2,22]),t(p,[2,25],{27:[1,25]}),t(h,[2,26]),{19:26,26:12,32:i},{11:27,13:4,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:s,31:a,32:i,40:n,44:l,47:c},{41:[1,28],43:[1,29]},{45:[1,30]},{48:[1,31]},t(y,[2,29],{33:32,36:[1,33],38:[1,34]}),{1:[2,7]},t(d,[2,13]),{26:35,32:i},{32:[2,14]},{17:[1,36]},t(p,[2,24]),{11:37,13:4,14:22,15:g,16:u,19:5,20:6,21:e,22:8,23:9,24:10,25:11,26:12,28:r,29:s,31:a,32:i,40:n,44:l,47:c},{30:[1,38]},{42:[1,39]},{42:[1,40]},{46:[1,41]},{49:[1,42]},t(y,[2,30]),{18:[1,43]},{18:[1,44]},t(p,[2,23]),{18:[1,45]},{30:[1,46]},t(h,[2,28]),t(h,[2,35]),t(h,[2,36]),t(h,[2,37]),t(h,[2,38]),{37:[1,47]},{34:48,35:b},{15:[1,50]},t(h,[2,27]),t(y,[2,33]),{39:[1,51]},{34:52,35:b,39:[2,31]},{32:[2,15]},t(y,[2,34]),{39:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:(0,o.K2)((function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)}),"parseError"),parse:(0,o.K2)((function(t){var e=this,r=[0],s=[],a=[null],i=[],n=this.table,l="",c=0,d=0,h=0,g=i.slice.call(arguments,1),u=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);u.setInput(t,p.yy),p.yy.lexer=u,p.yy.parser=this,void 0===u.yylloc&&(u.yylloc={});var b=u.yylloc;i.push(b);var x=u.options&&u.options.ranges;function f(){var t;return"number"!=typeof(t=s.pop()||u.lex()||1)&&(t instanceof Array&&(t=(s=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)((function(t){r.length=r.length-2*t,a.length=a.length-t,i.length=i.length-t}),"popStack"),(0,o.K2)(f,"lex");for(var m,w,_,L,k,S,v,E,D,C={};;){if(_=r[r.length-1],this.defaultActions[_]?L=this.defaultActions[_]:(null==m&&(m=f()),L=n[_]&&n[_][m]),void 0===L||!L.length||!L[0]){var R="";for(S in D=[],n[_])this.terminals_[S]&&S>2&&D.push("'"+this.terminals_[S]+"'");R=u.showPosition?"Parse error on line "+(c+1)+":\n"+u.showPosition()+"\nExpecting "+D.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(c+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(R,{text:u.match,token:this.terminals_[m]||m,line:u.yylineno,loc:b,expected:D})}if(L[0]instanceof Array&&L.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+m);switch(L[0]){case 1:r.push(m),a.push(u.yytext),i.push(u.yylloc),r.push(L[1]),m=null,w?(m=w,w=null):(d=u.yyleng,l=u.yytext,c=u.yylineno,b=u.yylloc,h>0&&h--);break;case 2:if(v=this.productions_[L[1]][1],C.$=a[a.length-v],C._$={first_line:i[i.length-(v||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(v||1)].first_column,last_column:i[i.length-1].last_column},x&&(C._$.range=[i[i.length-(v||1)].range[0],i[i.length-1].range[1]]),void 0!==(k=this.performAction.apply(C,[l,d,c,p.yy,L[1],a,i].concat(g))))return k;v&&(r=r.slice(0,-1*v*2),a=a.slice(0,-1*v),i=i.slice(0,-1*v)),r.push(this.productions_[L[1]][0]),a.push(C.$),i.push(C._$),E=n[r[r.length-2]][r[r.length-1]],r.push(E);break;case 3:return!0}}return!0}),"parse")},f=function(){return{EOF:1,parseError:(0,o.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,o.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,o.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,o.K2)((function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var a=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===s.length?this.yylloc.first_column:0)+s[s.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[a[0],a[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,o.K2)((function(){return this._more=!0,this}),"more"),reject:(0,o.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,o.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,o.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,o.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,o.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,o.K2)((function(t,e){var r,s,a;if(this.options.backtrack_lexer&&(a={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(a.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var i in a)this[i]=a[i];return!1}return!1}),"test_match"),next:(0,o.K2)((function(){if(this.done)return this.EOF;var t,e,r,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var a=this._currentRules(),i=0;ie[0].length)){if(e=r,s=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,a[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,a[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,o.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,o.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,o.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,o.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,o.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,o.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,o.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{},performAction:(0,o.K2)((function(t,e,r,s){switch(r){case 0:return 10;case 1:return t.getLogger().debug("Found space-block"),31;case 2:return t.getLogger().debug("Found nl-block"),31;case 3:return t.getLogger().debug("Found space-block"),29;case 4:t.getLogger().debug(".",e.yytext);break;case 5:t.getLogger().debug("_",e.yytext);break;case 6:return 5;case 7:return e.yytext=-1,28;case 8:return e.yytext=e.yytext.replace(/columns\s+/,""),t.getLogger().debug("COLUMNS (LEX)",e.yytext),28;case 9:case 77:case 78:case 100:this.pushState("md_string");break;case 10:return"MD_STR";case 11:case 35:case 80:this.popState();break;case 12:this.pushState("string");break;case 13:t.getLogger().debug("LEX: POPPING STR:",e.yytext),this.popState();break;case 14:return t.getLogger().debug("LEX: STR end:",e.yytext),"STR";case 15:return e.yytext=e.yytext.replace(/space\:/,""),t.getLogger().debug("SPACE NUM (LEX)",e.yytext),21;case 16:return e.yytext="1",t.getLogger().debug("COLUMNS (LEX)",e.yytext),21;case 17:return 43;case 18:return"LINKSTYLE";case 19:return"INTERPOLATE";case 20:return this.pushState("CLASSDEF"),40;case 21:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 22:return this.popState(),this.pushState("CLASSDEFID"),41;case 23:return this.popState(),42;case 24:return this.pushState("CLASS"),44;case 25:return this.popState(),this.pushState("CLASS_STYLE"),45;case 26:return this.popState(),46;case 27:return this.pushState("STYLE_STMNT"),47;case 28:return this.popState(),this.pushState("STYLE_DEFINITION"),48;case 29:return this.popState(),49;case 30:return this.pushState("acc_title"),"acc_title";case 31:return this.popState(),"acc_title_value";case 32:return this.pushState("acc_descr"),"acc_descr";case 33:return this.popState(),"acc_descr_value";case 34:this.pushState("acc_descr_multiline");break;case 36:return"acc_descr_multiline_value";case 37:return 30;case 38:case 39:case 41:case 42:case 45:return this.popState(),t.getLogger().debug("Lex: (("),"NODE_DEND";case 40:return this.popState(),t.getLogger().debug("Lex: ))"),"NODE_DEND";case 43:return this.popState(),t.getLogger().debug("Lex: (-"),"NODE_DEND";case 44:return this.popState(),t.getLogger().debug("Lex: -)"),"NODE_DEND";case 46:return this.popState(),t.getLogger().debug("Lex: ]]"),"NODE_DEND";case 47:return this.popState(),t.getLogger().debug("Lex: ("),"NODE_DEND";case 48:return this.popState(),t.getLogger().debug("Lex: ])"),"NODE_DEND";case 49:case 50:return this.popState(),t.getLogger().debug("Lex: /]"),"NODE_DEND";case 51:return this.popState(),t.getLogger().debug("Lex: )]"),"NODE_DEND";case 52:return this.popState(),t.getLogger().debug("Lex: )"),"NODE_DEND";case 53:return this.popState(),t.getLogger().debug("Lex: ]>"),"NODE_DEND";case 54:return this.popState(),t.getLogger().debug("Lex: ]"),"NODE_DEND";case 55:return t.getLogger().debug("Lexa: -)"),this.pushState("NODE"),36;case 56:return t.getLogger().debug("Lexa: (-"),this.pushState("NODE"),36;case 57:return t.getLogger().debug("Lexa: ))"),this.pushState("NODE"),36;case 58:case 60:case 61:case 62:case 65:return t.getLogger().debug("Lexa: )"),this.pushState("NODE"),36;case 59:return t.getLogger().debug("Lex: ((("),this.pushState("NODE"),36;case 63:return t.getLogger().debug("Lexc: >"),this.pushState("NODE"),36;case 64:return t.getLogger().debug("Lexa: (["),this.pushState("NODE"),36;case 66:case 67:case 68:case 69:case 70:case 71:case 72:return this.pushState("NODE"),36;case 73:return t.getLogger().debug("Lexa: ["),this.pushState("NODE"),36;case 74:return this.pushState("BLOCK_ARROW"),t.getLogger().debug("LEX ARR START"),38;case 75:return t.getLogger().debug("Lex: NODE_ID",e.yytext),32;case 76:return t.getLogger().debug("Lex: EOF",e.yytext),8;case 79:return"NODE_DESCR";case 81:t.getLogger().debug("Lex: Starting string"),this.pushState("string");break;case 82:t.getLogger().debug("LEX ARR: Starting string"),this.pushState("string");break;case 83:return t.getLogger().debug("LEX: NODE_DESCR:",e.yytext),"NODE_DESCR";case 84:t.getLogger().debug("LEX POPPING"),this.popState();break;case 85:t.getLogger().debug("Lex: =>BAE"),this.pushState("ARROW_DIR");break;case 86:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (right): dir:",e.yytext),"DIR";case 87:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (left):",e.yytext),"DIR";case 88:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (x):",e.yytext),"DIR";case 89:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (y):",e.yytext),"DIR";case 90:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (up):",e.yytext),"DIR";case 91:return e.yytext=e.yytext.replace(/^,\s*/,""),t.getLogger().debug("Lex (down):",e.yytext),"DIR";case 92:return e.yytext="]>",t.getLogger().debug("Lex (ARROW_DIR end):",e.yytext),this.popState(),this.popState(),"BLOCK_ARROW_END";case 93:return t.getLogger().debug("Lex: LINK","#"+e.yytext+"#"),15;case 94:case 95:case 96:return t.getLogger().debug("Lex: LINK",e.yytext),15;case 97:case 98:case 99:return t.getLogger().debug("Lex: START_LINK",e.yytext),this.pushState("LLABEL"),16;case 101:return t.getLogger().debug("Lex: Starting string"),this.pushState("string"),"LINK_LABEL";case 102:return this.popState(),t.getLogger().debug("Lex: LINK","#"+e.yytext+"#"),15;case 103:case 104:return this.popState(),t.getLogger().debug("Lex: LINK",e.yytext),15;case 105:return t.getLogger().debug("Lex: COLON",e.yytext),e.yytext=e.yytext.slice(1),27}}),"anonymous"),rules:[/^(?:block-beta\b)/,/^(?:block\s+)/,/^(?:block\n+)/,/^(?:block:)/,/^(?:[\s]+)/,/^(?:[\n]+)/,/^(?:((\u000D\u000A)|(\u000A)))/,/^(?:columns\s+auto\b)/,/^(?:columns\s+[\d]+)/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]*)/,/^(?:space[:]\d+)/,/^(?:space\b)/,/^(?:default\b)/,/^(?:linkStyle\b)/,/^(?:interpolate\b)/,/^(?:classDef\s+)/,/^(?:DEFAULT\s+)/,/^(?:\w+\s+)/,/^(?:[^\n]*)/,/^(?:class\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:style\s+)/,/^(?:(\w+)+((,\s*\w+)*))/,/^(?:[^\n]*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:end\b\s*)/,/^(?:\(\(\()/,/^(?:\)\)\))/,/^(?:[\)]\))/,/^(?:\}\})/,/^(?:\})/,/^(?:\(-)/,/^(?:-\))/,/^(?:\(\()/,/^(?:\]\])/,/^(?:\()/,/^(?:\]\))/,/^(?:\\\])/,/^(?:\/\])/,/^(?:\)\])/,/^(?:[\)])/,/^(?:\]>)/,/^(?:[\]])/,/^(?:-\))/,/^(?:\(-)/,/^(?:\)\))/,/^(?:\))/,/^(?:\(\(\()/,/^(?:\(\()/,/^(?:\{\{)/,/^(?:\{)/,/^(?:>)/,/^(?:\(\[)/,/^(?:\()/,/^(?:\[\[)/,/^(?:\[\|)/,/^(?:\[\()/,/^(?:\)\)\))/,/^(?:\[\\)/,/^(?:\[\/)/,/^(?:\[\\)/,/^(?:\[)/,/^(?:<\[)/,/^(?:[^\(\[\n\-\)\{\}\s\<\>:]+)/,/^(?:$)/,/^(?:["][`])/,/^(?:["][`])/,/^(?:[^`"]+)/,/^(?:[`]["])/,/^(?:["])/,/^(?:["])/,/^(?:[^"]+)/,/^(?:["])/,/^(?:\]>\s*\()/,/^(?:,?\s*right\s*)/,/^(?:,?\s*left\s*)/,/^(?:,?\s*x\s*)/,/^(?:,?\s*y\s*)/,/^(?:,?\s*up\s*)/,/^(?:,?\s*down\s*)/,/^(?:\)\s*)/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?:\s*~~[\~]+\s*)/,/^(?:\s*[xo<]?--\s*)/,/^(?:\s*[xo<]?==\s*)/,/^(?:\s*[xo<]?-\.\s*)/,/^(?:["][`])/,/^(?:["])/,/^(?:\s*[xo<]?--+[-xo>]\s*)/,/^(?:\s*[xo<]?==+[=xo>]\s*)/,/^(?:\s*[xo<]?-?\.+-[xo>]?\s*)/,/^(?::\d+)/],conditions:{STYLE_DEFINITION:{rules:[29],inclusive:!1},STYLE_STMNT:{rules:[28],inclusive:!1},CLASSDEFID:{rules:[23],inclusive:!1},CLASSDEF:{rules:[21,22],inclusive:!1},CLASS_STYLE:{rules:[26],inclusive:!1},CLASS:{rules:[25],inclusive:!1},LLABEL:{rules:[100,101,102,103,104],inclusive:!1},ARROW_DIR:{rules:[86,87,88,89,90,91,92],inclusive:!1},BLOCK_ARROW:{rules:[77,82,85],inclusive:!1},NODE:{rules:[38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,78,81],inclusive:!1},md_string:{rules:[10,11,79,80],inclusive:!1},space:{rules:[],inclusive:!1},string:{rules:[13,14,83,84],inclusive:!1},acc_descr_multiline:{rules:[35,36],inclusive:!1},acc_descr:{rules:[33],inclusive:!1},acc_title:{rules:[31],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,9,12,15,16,17,18,19,20,24,27,30,32,34,37,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,93,94,95,96,97,98,99,105],inclusive:!0}}}}();function m(){this.yy={}}return x.lexer=f,(0,o.K2)(m,"Parser"),m.prototype=x,x.Parser=m,new m}();u.parser=u;var p=u,y=new Map,b=[],x=new Map,f="color",m="fill",w=(0,o.D7)(),_=new Map,L=(0,o.K2)((t=>o.Y2.sanitizeText(t,w)),"sanitizeText"),k=(0,o.K2)((function(t,e=""){let r=_.get(t);r||(r={id:t,styles:[],textStyles:[]},_.set(t,r)),null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(RegExp(f).exec(t)){const t=e.replace(m,"bgFill").replace(f,m);r.textStyles.push(t)}r.styles.push(e)}))}),"addStyleClass"),S=(0,o.K2)((function(t,e=""){const r=y.get(t);null!=e&&(r.styles=e.split(","))}),"addStyle2Node"),v=(0,o.K2)((function(t,e){t.split(",").forEach((function(t){let r=y.get(t);if(void 0===r){const e=t.trim();r={id:e,type:"na",children:[]},y.set(e,r)}r.classes||(r.classes=[]),r.classes.push(e)}))}),"setCssClass"),E=(0,o.K2)(((t,e)=>{const r=t.flat(),s=[];for(const a of r)if(a.label&&(a.label=L(a.label)),"classDef"!==a.type)if("applyClass"!==a.type)if("applyStyles"!==a.type)if("column-setting"===a.type)e.columns=a.columns??-1;else if("edge"===a.type){const t=(x.get(a.id)??0)+1;x.set(a.id,t),a.id=t+"-"+a.id,b.push(a)}else{a.label||("composite"===a.type?a.label="":a.label=a.id);const t=y.get(a.id);if(void 0===t?y.set(a.id,a):("na"!==a.type&&(t.type=a.type),a.label!==a.id&&(t.label=a.label)),a.children&&E(a.children,a),"space"===a.type){const t=a.width??1;for(let e=0;e{o.Rm.debug("Clear called"),(0,o.IU)(),C={id:"root",type:"composite",children:[],columns:-1},y=new Map([["root",C]]),D=[],_=new Map,b=[],x=new Map}),"clear");function K(t){switch(o.Rm.debug("typeStr2Type",t),t){case"[]":return"square";case"()":return o.Rm.debug("we have a round"),"round";case"(())":return"circle";case">]":return"rect_left_inv_arrow";case"{}":return"diamond";case"{{}}":return"hexagon";case"([])":return"stadium";case"[[]]":return"subroutine";case"[()]":return"cylinder";case"((()))":return"doublecircle";case"[//]":return"lean_right";case"[\\\\]":return"lean_left";case"[/\\]":return"trapezoid";case"[\\/]":return"inv_trapezoid";case"<[]>":return"block_arrow";default:return"na"}}function N(t){return o.Rm.debug("typeStr2Type",t),"=="===t?"thick":"normal"}function T(t){switch(t.trim()){case"--x":return"arrow_cross";case"--o":return"arrow_circle";default:return"arrow_point"}}(0,o.K2)(K,"typeStr2Type"),(0,o.K2)(N,"edgeTypeStr2Type"),(0,o.K2)(T,"edgeStrToEdgeData");var $=0,A=(0,o.K2)((()=>($++,"id-"+Math.random().toString(36).substr(2,12)+"-"+$)),"generateId"),I=(0,o.K2)((t=>{C.children=t,E(t,C),D=C.children}),"setHierarchy"),O=(0,o.K2)((t=>{const e=y.get(t);return e?e.columns?e.columns:e.children?e.children.length:-1:-1}),"getColumns"),B=(0,o.K2)((()=>[...y.values()]),"getBlocksFlat"),z=(0,o.K2)((()=>D||[]),"getBlocks"),M=(0,o.K2)((()=>b),"getEdges"),P=(0,o.K2)((t=>y.get(t)),"getBlock"),Y=(0,o.K2)((t=>{y.set(t.id,t)}),"setBlock"),F=(0,o.K2)((()=>console),"getLogger"),j=(0,o.K2)((function(){return _}),"getClasses"),W={getConfig:(0,o.K2)((()=>(0,o.zj)().block),"getConfig"),typeStr2Type:K,edgeTypeStr2Type:N,edgeStrToEdgeData:T,getLogger:F,getBlocksFlat:B,getBlocks:z,getEdges:M,setHierarchy:I,getBlock:P,setBlock:Y,getColumns:O,getClasses:j,clear:R,generateId:A},X=(0,o.K2)(((t,e)=>{const r=c.A,s=r(t,"r"),a=r(t,"g"),i=r(t,"b");return d.A(s,a,i,e)}),"fade"),H=(0,o.K2)((t=>`.label {\n font-family: ${t.fontFamily};\n color: ${t.nodeTextColor||t.textColor};\n }\n .cluster-label text {\n fill: ${t.titleColor};\n }\n .cluster-label span,p {\n color: ${t.titleColor};\n }\n\n\n\n .label text,span,p {\n fill: ${t.nodeTextColor||t.textColor};\n color: ${t.nodeTextColor||t.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${X(t.edgeLabelBackground,.5)};\n // background-color:\n }\n\n .node .cluster {\n // fill: ${X(t.mainBkg,.5)};\n fill: ${X(t.clusterBkg,.5)};\n stroke: ${X(t.clusterBorder,.2)};\n box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n .cluster span,p {\n color: ${t.titleColor};\n }\n /* .cluster div {\n color: ${t.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${t.fontFamily};\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`),"getStyles"),U=(0,o.K2)(((t,e,r,s)=>{e.forEach((e=>{Z[e](t,r,s)}))}),"insertMarkers"),Z={extension:(0,o.K2)(((t,e,r)=>{o.Rm.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")}),"extension"),composition:(0,o.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")}),"composition"),aggregation:(0,o.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")}),"aggregation"),dependency:(0,o.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")}),"dependency"),lollipop:(0,o.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)}),"lollipop"),point:(0,o.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",6).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")}),"point"),circle:(0,o.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")}),"circle"),cross:(0,o.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")}),"cross"),barb:(0,o.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","strokeWidth").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}),"barb")},q=U,G=(0,o.D7)()?.block?.padding??8;function J(t,e){if(0===t||!Number.isInteger(t))throw new Error("Columns must be an integer !== 0.");if(e<0||!Number.isInteger(e))throw new Error("Position must be a non-negative integer."+e);if(t<0)return{px:e,py:0};if(1===t)return{px:0,py:e};return{px:e%t,py:Math.floor(e/t)}}(0,o.K2)(J,"calculateBlockPosition");var V=(0,o.K2)((t=>{let e=0,r=0;for(const s of t.children){const{width:a,height:i,x:n,y:l}=s.size??{width:0,height:0,x:0,y:0};o.Rm.debug("getMaxChildSize abc95 child:",s.id,"width:",a,"height:",i,"x:",n,"y:",l,s.type),"space"!==s.type&&(a>e&&(e=a/(t.widthInColumns??1)),i>r&&(r=i))}return{width:e,height:r}}),"getMaxChildSize");function Q(t,e,r=0,s=0){o.Rm.debug("setBlockSizes abc95 (start)",t.id,t?.size?.x,"block width =",t?.size,"sieblingWidth",r),t?.size?.width||(t.size={width:r,height:s,x:0,y:0});let a=0,i=0;if(t.children?.length>0){for(const r of t.children)Q(r,e);const n=V(t);a=n.width,i=n.height,o.Rm.debug("setBlockSizes abc95 maxWidth of",t.id,":s children is ",a,i);for(const e of t.children)e.size&&(o.Rm.debug(`abc95 Setting size of children of ${t.id} id=${e.id} ${a} ${i} ${JSON.stringify(e.size)}`),e.size.width=a*(e.widthInColumns??1)+G*((e.widthInColumns??1)-1),e.size.height=i,e.size.x=0,e.size.y=0,o.Rm.debug(`abc95 updating size of ${t.id} children child:${e.id} maxWidth:${a} maxHeight:${i}`));for(const r of t.children)Q(r,e,a,i);const l=t.columns??-1;let c=0;for(const e of t.children)c+=e.widthInColumns??1;let d=t.children.length;l>0&&l0?Math.min(t.children.length,l):t.children.length;if(e>0){const r=(g-e*G-G)/e;o.Rm.debug("abc95 (growing to fit) width",t.id,g,t.size?.width,r);for(const e of t.children)e.size&&(e.size.width=r)}}t.size={width:g,height:u,x:0,y:0}}o.Rm.debug("setBlockSizes abc94 (done)",t.id,t?.size?.x,t?.size?.width,t?.size?.y,t?.size?.height)}function tt(t,e){o.Rm.debug(`abc85 layout blocks (=>layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`);const r=t.columns??-1;if(o.Rm.debug("layoutBlocks columns abc95",t.id,"=>",r,t),t.children&&t.children.length>0){const s=t?.children[0]?.size?.width??0,a=t.children.length*s+(t.children.length-1)*G;o.Rm.debug("widthOfChildren 88",a,"posX");let i=0;o.Rm.debug("abc91 block?.size?.x",t.id,t?.size?.x);let n=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-G,l=0;for(const c of t.children){const s=t;if(!c.size)continue;const{width:a,height:d}=c.size,{px:h,py:g}=J(r,i);if(g!=l&&(l=g,n=t?.size?.x?t?.size?.x+(-t?.size?.width/2||0):-G,o.Rm.debug("New row in layout for block",t.id," and child ",c.id,l)),o.Rm.debug(`abc89 layout blocks (child) id: ${c.id} Pos: ${i} (px, py) ${h},${g} (${s?.size?.x},${s?.size?.y}) parent: ${s.id} width: ${a}${G}`),s.size){const t=a/2;c.size.x=n+G+t,o.Rm.debug(`abc91 layout blocks (calc) px, pyid:${c.id} startingPos=X${n} new startingPosX${c.size.x} ${t} padding=${G} width=${a} halfWidth=${t} => x:${c.size.x} y:${c.size.y} ${c.widthInColumns} (width * (child?.w || 1)) / 2 ${a*(c?.widthInColumns??1)/2}`),n=c.size.x+t,c.size.y=s.size.y-s.size.height/2+g*(d+G)+d/2+G,o.Rm.debug(`abc88 layout blocks (calc) px, pyid:${c.id}startingPosX${n}${G}${t}=>x:${c.size.x}y:${c.size.y}${c.widthInColumns}(width * (child?.w || 1)) / 2${a*(c?.widthInColumns??1)/2}`)}c.children&&tt(c,e),i+=c?.widthInColumns??1,o.Rm.debug("abc88 columnsPos",c,i)}}o.Rm.debug(`layout blocks (<==layoutBlocks) ${t.id} x: ${t?.size?.x} y: ${t?.size?.y} width: ${t?.size?.width}`)}function et(t,{minX:e,minY:r,maxX:s,maxY:a}={minX:0,minY:0,maxX:0,maxY:0}){if(t.size&&"root"!==t.id){const{x:i,y:n,width:o,height:l}=t.size;i-o/2s&&(s=i+o/2),n+l/2>a&&(a=n+l/2)}if(t.children)for(const i of t.children)({minX:e,minY:r,maxX:s,maxY:a}=et(i,{minX:e,minY:r,maxX:s,maxY:a}));return{minX:e,minY:r,maxX:s,maxY:a}}function rt(t){const e=t.getBlock("root");if(!e)return;Q(e,t,0,0),tt(e,t),o.Rm.debug("getBlocks",JSON.stringify(e,null,2));const{minX:r,minY:s,maxX:a,maxY:i}=et(e);return{x:r,y:s,width:a-r,height:i-s}}function st(t,e){e&&t.attr("style",e)}function at(t){const e=(0,h.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div"),s=t.label,a=t.isNode?"nodeLabel":"edgeLabel",i=r.append("span");return i.html(s),st(i,t.labelStyle),i.attr("class",a),st(r,t.labelStyle),r.style("display","inline-block"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}(0,o.K2)(Q,"setBlockSizes"),(0,o.K2)(tt,"layoutBlocks"),(0,o.K2)(et,"findBounds"),(0,o.K2)(rt,"layout"),(0,o.K2)(st,"applyStyle"),(0,o.K2)(at,"addHtmlLabel");var it=(0,o.K2)(((t,e,r,s)=>{let a=t||"";if("object"==typeof a&&(a=a[0]),(0,o._3)((0,o.D7)().flowchart.htmlLabels)){a=a.replace(/\\n|\n/g,"
"),o.Rm.debug("vertexText"+a);return at({isNode:s,label:(0,i.hE)((0,n.Sm)(a)),labelStyle:e.replace("fill:","color:")})}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let s=[];s="string"==typeof a?a.split(/\\n|\n|/gi):Array.isArray(a)?a:[];for(const e of s){const s=document.createElementNS("http://www.w3.org/2000/svg","tspan");s.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),s.setAttribute("dy","1em"),s.setAttribute("x","0"),r?s.setAttribute("class","title-row"):s.setAttribute("class","row"),s.textContent=e.trim(),t.appendChild(s)}return t}}),"createLabel"),nt=(0,o.K2)(((t,e,r,s,a)=>{e.arrowTypeStart&<(t,"start",e.arrowTypeStart,r,s,a),e.arrowTypeEnd&<(t,"end",e.arrowTypeEnd,r,s,a)}),"addEdgeMarkers"),ot={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},lt=(0,o.K2)(((t,e,r,s,a,i)=>{const n=ot[r];if(!n)return void o.Rm.warn(`Unknown arrow type: ${r}`);const l="start"===e?"Start":"End";t.attr(`marker-${e}`,`url(${s}#${a}_${i}-${n}${l})`)}),"addEdgeMarker"),ct={},dt={},ht=(0,o.K2)(((t,e)=>{const r=(0,o.D7)(),s=(0,o._3)(r.flowchart.htmlLabels),a="markdown"===e.labelType?(0,i.GZ)(t,e.label,{style:e.labelStyle,useHtmlLabels:s,addSvgBackground:!0},r):it(e.label,e.labelStyle),n=t.insert("g").attr("class","edgeLabel"),l=n.insert("g").attr("class","label");l.node().appendChild(a);let c,d=a.getBBox();if(s){const t=a.children[0],e=(0,h.Ltv)(a);d=t.getBoundingClientRect(),e.attr("width",d.width),e.attr("height",d.height)}if(l.attr("transform","translate("+-d.width/2+", "+-d.height/2+")"),ct[e.id]=n,e.width=d.width,e.height=d.height,e.startLabelLeft){const r=it(e.startLabelLeft,e.labelStyle),s=t.insert("g").attr("class","edgeTerminals"),a=s.insert("g").attr("class","inner");c=a.node().appendChild(r);const i=r.getBBox();a.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),dt[e.id]||(dt[e.id]={}),dt[e.id].startLeft=s,gt(c,e.startLabelLeft)}if(e.startLabelRight){const r=it(e.startLabelRight,e.labelStyle),s=t.insert("g").attr("class","edgeTerminals"),a=s.insert("g").attr("class","inner");c=s.node().appendChild(r),a.node().appendChild(r);const i=r.getBBox();a.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),dt[e.id]||(dt[e.id]={}),dt[e.id].startRight=s,gt(c,e.startLabelRight)}if(e.endLabelLeft){const r=it(e.endLabelLeft,e.labelStyle),s=t.insert("g").attr("class","edgeTerminals"),a=s.insert("g").attr("class","inner");c=a.node().appendChild(r);const i=r.getBBox();a.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),s.node().appendChild(r),dt[e.id]||(dt[e.id]={}),dt[e.id].endLeft=s,gt(c,e.endLabelLeft)}if(e.endLabelRight){const r=it(e.endLabelRight,e.labelStyle),s=t.insert("g").attr("class","edgeTerminals"),a=s.insert("g").attr("class","inner");c=a.node().appendChild(r);const i=r.getBBox();a.attr("transform","translate("+-i.width/2+", "+-i.height/2+")"),s.node().appendChild(r),dt[e.id]||(dt[e.id]={}),dt[e.id].endRight=s,gt(c,e.endLabelRight)}return a}),"insertEdgeLabel");function gt(t,e){(0,o.D7)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}(0,o.K2)(gt,"setTerminalWidth");var ut=(0,o.K2)(((t,e)=>{o.Rm.debug("Moving label abc88 ",t.id,t.label,ct[t.id],e);let r=e.updatedPath?e.updatedPath:e.originalPath;const s=(0,o.D7)(),{subGraphTitleTotalMargin:i}=(0,a.O)(s);if(t.label){const s=ct[t.id];let a=t.x,l=t.y;if(r){const s=n._K.calcLabelPosition(r);o.Rm.debug("Moving label "+t.label+" from (",a,",",l,") to (",s.x,",",s.y,") abc88"),e.updatedPath&&(a=s.x,l=s.y)}s.attr("transform",`translate(${a}, ${l+i/2})`)}if(t.startLabelLeft){const e=dt[t.id].startLeft;let s=t.x,a=t.y;if(r){const e=n._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);s=e.x,a=e.y}e.attr("transform",`translate(${s}, ${a})`)}if(t.startLabelRight){const e=dt[t.id].startRight;let s=t.x,a=t.y;if(r){const e=n._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);s=e.x,a=e.y}e.attr("transform",`translate(${s}, ${a})`)}if(t.endLabelLeft){const e=dt[t.id].endLeft;let s=t.x,a=t.y;if(r){const e=n._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);s=e.x,a=e.y}e.attr("transform",`translate(${s}, ${a})`)}if(t.endLabelRight){const e=dt[t.id].endRight;let s=t.x,a=t.y;if(r){const e=n._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);s=e.x,a=e.y}e.attr("transform",`translate(${s}, ${a})`)}}),"positionEdgeLabel"),pt=(0,o.K2)(((t,e)=>{const r=t.x,s=t.y,a=Math.abs(e.x-r),i=Math.abs(e.y-s),n=t.width/2,o=t.height/2;return a>=n||i>=o}),"outsideNode"),yt=(0,o.K2)(((t,e,r)=>{o.Rm.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const s=t.x,a=t.y,i=Math.abs(s-r.x),n=t.width/2;let l=r.xMath.abs(s-e.x)*c){let t=r.y{o.Rm.debug("abc88 cutPathAtIntersect",t,e);let r=[],s=t[0],a=!1;return t.forEach((t=>{if(pt(e,t)||a)s=t,a||r.push(t);else{const i=yt(e,s,t);let n=!1;r.forEach((t=>{n=n||t.x===i.x&&t.y===i.y})),r.some((t=>t.x===i.x&&t.y===i.y))||r.push(i),a=!0}})),r}),"cutPathAtIntersect"),xt=(0,o.K2)((function(t,e,r,a,i,n,l){let c=r.points;o.Rm.debug("abc88 InsertEdge: edge=",r,"e=",e);let d=!1;const g=n.node(e.v);var u=n.node(e.w);u?.intersect&&g?.intersect&&(c=c.slice(1,r.points.length-1),c.unshift(g.intersect(c[0])),c.push(u.intersect(c[c.length-1]))),r.toCluster&&(o.Rm.debug("to cluster abc88",a[r.toCluster]),c=bt(r.points,a[r.toCluster].node),d=!0),r.fromCluster&&(o.Rm.debug("from cluster abc88",a[r.fromCluster]),c=bt(c.reverse(),a[r.fromCluster].node).reverse(),d=!0);const p=c.filter((t=>!Number.isNaN(t.y)));let y=h.qrM;!r.curve||"graph"!==i&&"flowchart"!==i||(y=r.curve);const{x:b,y:x}=(0,s.R)(r),f=(0,h.n8j)().x(b).y(x).curve(y);let m;switch(r.thickness){case"normal":m="edge-thickness-normal";break;case"thick":case"invisible":m="edge-thickness-thick";break;default:m=""}switch(r.pattern){case"solid":m+=" edge-pattern-solid";break;case"dotted":m+=" edge-pattern-dotted";break;case"dashed":m+=" edge-pattern-dashed"}const w=t.append("path").attr("d",f(p)).attr("id",r.id).attr("class"," "+m+(r.classes?" "+r.classes:"")).attr("style",r.style);let _="";((0,o.D7)().flowchart.arrowMarkerAbsolute||(0,o.D7)().state.arrowMarkerAbsolute)&&(_=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,_=_.replace(/\(/g,"\\("),_=_.replace(/\)/g,"\\)")),nt(w,r,_,l,i);let L={};return d&&(L.updatedPath=c),L.originalPath=r.points,L}),"insertEdge"),ft=(0,o.K2)((t=>{const e=new Set;for(const r of t)switch(r){case"x":e.add("right"),e.add("left");break;case"y":e.add("up"),e.add("down");break;default:e.add(r)}return e}),"expandAndDeduplicateDirections"),mt=(0,o.K2)(((t,e,r)=>{const s=ft(t),a=e.height+2*r.padding,i=a/2,n=e.width+2*i+r.padding,o=r.padding/2;return s.has("right")&&s.has("left")&&s.has("up")&&s.has("down")?[{x:0,y:0},{x:i,y:0},{x:n/2,y:2*o},{x:n-i,y:0},{x:n,y:0},{x:n,y:-a/3},{x:n+2*o,y:-a/2},{x:n,y:-2*a/3},{x:n,y:-a},{x:n-i,y:-a},{x:n/2,y:-a-2*o},{x:i,y:-a},{x:0,y:-a},{x:0,y:-2*a/3},{x:-2*o,y:-a/2},{x:0,y:-a/3}]:s.has("right")&&s.has("left")&&s.has("up")?[{x:i,y:0},{x:n-i,y:0},{x:n,y:-a/2},{x:n-i,y:-a},{x:i,y:-a},{x:0,y:-a/2}]:s.has("right")&&s.has("left")&&s.has("down")?[{x:0,y:0},{x:i,y:-a},{x:n-i,y:-a},{x:n,y:0}]:s.has("right")&&s.has("up")&&s.has("down")?[{x:0,y:0},{x:n,y:-i},{x:n,y:-a+i},{x:0,y:-a}]:s.has("left")&&s.has("up")&&s.has("down")?[{x:n,y:0},{x:0,y:-i},{x:0,y:-a+i},{x:n,y:-a}]:s.has("right")&&s.has("left")?[{x:i,y:0},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:0},{x:n,y:-a/2},{x:n-i,y:-a},{x:n-i,y:-a+o},{x:i,y:-a+o},{x:i,y:-a},{x:0,y:-a/2}]:s.has("up")&&s.has("down")?[{x:n/2,y:0},{x:0,y:-o},{x:i,y:-o},{x:i,y:-a+o},{x:0,y:-a+o},{x:n/2,y:-a},{x:n,y:-a+o},{x:n-i,y:-a+o},{x:n-i,y:-o},{x:n,y:-o}]:s.has("right")&&s.has("up")?[{x:0,y:0},{x:n,y:-i},{x:0,y:-a}]:s.has("right")&&s.has("down")?[{x:0,y:0},{x:n,y:0},{x:0,y:-a}]:s.has("left")&&s.has("up")?[{x:n,y:0},{x:0,y:-i},{x:n,y:-a}]:s.has("left")&&s.has("down")?[{x:n,y:0},{x:0,y:0},{x:n,y:-a}]:s.has("right")?[{x:i,y:-o},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:0},{x:n,y:-a/2},{x:n-i,y:-a},{x:n-i,y:-a+o},{x:i,y:-a+o},{x:i,y:-a+o}]:s.has("left")?[{x:i,y:0},{x:i,y:-o},{x:n-i,y:-o},{x:n-i,y:-a+o},{x:i,y:-a+o},{x:i,y:-a},{x:0,y:-a/2}]:s.has("up")?[{x:i,y:-o},{x:i,y:-a+o},{x:0,y:-a+o},{x:n/2,y:-a},{x:n,y:-a+o},{x:n-i,y:-a+o},{x:n-i,y:-o}]:s.has("down")?[{x:n/2,y:0},{x:0,y:-o},{x:i,y:-o},{x:i,y:-a+o},{x:n-i,y:-a+o},{x:n-i,y:-o},{x:n,y:-o}]:[{x:0,y:0}]}),"getArrowPoints");function wt(t,e){return t.intersect(e)}(0,o.K2)(wt,"intersectNode");var _t=wt;function Lt(t,e,r,s){var a=t.x,i=t.y,n=a-s.x,o=i-s.y,l=Math.sqrt(e*e*o*o+r*r*n*n),c=Math.abs(e*r*n/l);s.x0}(0,o.K2)(Et,"intersectLine"),(0,o.K2)(Dt,"sameSign");var Ct=Et,Rt=Kt;function Kt(t,e,r){var s=t.x,a=t.y,i=[],n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){n=Math.min(n,t.x),o=Math.min(o,t.y)})):(n=Math.min(n,e.x),o=Math.min(o,e.y));for(var l=s-t.width/2-n,c=a-t.height/2-o,d=0;d1&&i.sort((function(t,e){var s=t.x-r.x,a=t.y-r.y,i=Math.sqrt(s*s+a*a),n=e.x-r.x,o=e.y-r.y,l=Math.sqrt(n*n+o*o);return i{var r,s,a=t.x,i=t.y,n=e.x-a,o=e.y-i,l=t.width/2,c=t.height/2;return Math.abs(o)*l>Math.abs(n)*c?(o<0&&(c=-c),r=0===o?0:c*n/o,s=c):(n<0&&(l=-l),r=l,s=0===n?0:l*o/n),{x:a+r,y:i+s}}),"intersectRect")},Tt=(0,o.K2)((async(t,e,r,s)=>{const a=(0,o.D7)();let l;const c=e.useHtmlLabels||(0,o._3)(a.flowchart.htmlLabels);l=r||"node default";const d=t.insert("g").attr("class",l).attr("id",e.domId||e.id),g=d.insert("g").attr("class","label").attr("style",e.labelStyle);let u;u=void 0===e.labelText?"":"string"==typeof e.labelText?e.labelText:e.labelText[0];const p=g.node();let y;y="markdown"===e.labelType?(0,i.GZ)(g,(0,o.jZ)((0,n.Sm)(u),a),{useHtmlLabels:c,width:e.width||a.flowchart.wrappingWidth,classes:"markdown-node-label"},a):p.appendChild(it((0,o.jZ)((0,n.Sm)(u),a),e.labelStyle,!1,s));let b=y.getBBox();const x=e.padding/2;if((0,o._3)(a.flowchart.htmlLabels)){const t=y.children[0],e=(0,h.Ltv)(y),r=t.getElementsByTagName("img");if(r){const t=""===u.replace(/]*>/g,"").trim();await Promise.all([...r].map((e=>new Promise((r=>{function s(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=a.fontSize?a.fontSize:window.getComputedStyle(document.body).fontSize,r=5,s=parseInt(t,10)*r+"px";e.style.minWidth=s,e.style.maxWidth=s}else e.style.width="100%";r(e)}(0,o.K2)(s,"setupImage"),setTimeout((()=>{e.complete&&s()})),e.addEventListener("error",s),e.addEventListener("load",s)})))))}b=t.getBoundingClientRect(),e.attr("width",b.width),e.attr("height",b.height)}return c?g.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"):g.attr("transform","translate(0, "+-b.height/2+")"),e.centerLabel&&g.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),g.insert("rect",":first-child"),{shapeSvg:d,bbox:b,halfPadding:x,label:g}}),"labelHelper"),$t=(0,o.K2)(((t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height}),"updateNodeBounds");function At(t,e,r,s){return t.insert("polygon",":first-child").attr("points",s.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}(0,o.K2)(At,"insertPolygonShape");var It=(0,o.K2)((async(t,e)=>{e.useHtmlLabels||(0,o.D7)().flowchart.htmlLabels||(e.centerLabel=!0);const{shapeSvg:r,bbox:s,halfPadding:a}=await Tt(t,e,"node "+e.classes,!0);o.Rm.info("Classes = ",e.classes);const i=r.insert("rect",":first-child");return i.attr("rx",e.rx).attr("ry",e.ry).attr("x",-s.width/2-a).attr("y",-s.height/2-a).attr("width",s.width+e.padding).attr("height",s.height+e.padding),$t(e,i),e.intersect=function(t){return Nt.rect(e,t)},r}),"note"),Ot=(0,o.K2)((t=>t?" "+t:""),"formatClass"),Bt=(0,o.K2)(((t,e)=>`${e||"node default"}${Ot(t.classes)} ${Ot(t.class)}`),"getClassesFromNode"),zt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding+(s.height+e.padding),i=[{x:a/2,y:0},{x:a,y:-a/2},{x:a/2,y:-a},{x:0,y:-a/2}];o.Rm.info("Question main (Circle)");const n=At(r,a,a,i);return n.attr("style",e.style),$t(e,n),e.intersect=function(t){return o.Rm.warn("Intersect called"),Nt.polygon(e,i,t)},r}),"question"),Mt=(0,o.K2)(((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),s=[{x:0,y:14},{x:14,y:0},{x:0,y:-14},{x:-14,y:0}];return r.insert("polygon",":first-child").attr("points",s.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),e.width=28,e.height=28,e.intersect=function(t){return Nt.circle(e,14,t)},r}),"choice"),Pt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.height+e.padding,i=a/4,n=s.width+2*i+e.padding,o=[{x:i,y:0},{x:n-i,y:0},{x:n,y:-a/2},{x:n-i,y:-a},{x:i,y:-a},{x:0,y:-a/2}],l=At(r,n,a,o);return l.attr("style",e.style),$t(e,l),e.intersect=function(t){return Nt.polygon(e,o,t)},r}),"hexagon"),Yt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,void 0,!0),a=s.height+2*e.padding,i=a/2,n=s.width+2*i+e.padding,o=mt(e.directions,s,e),l=At(r,n,a,o);return l.attr("style",e.style),$t(e,l),e.intersect=function(t){return Nt.polygon(e,o,t)},r}),"block_arrow"),Ft=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:-i/2,y:0},{x:a,y:0},{x:a,y:-i},{x:-i/2,y:-i},{x:0,y:-i/2}];return At(r,a,i,n).attr("style",e.style),e.width=a+i,e.height=i,e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"rect_left_inv_arrow"),jt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:-2*i/6,y:0},{x:a-i/6,y:0},{x:a+2*i/6,y:-i},{x:i/6,y:-i}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"lean_right"),Wt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:2*i/6,y:0},{x:a+i/6,y:0},{x:a-2*i/6,y:-i},{x:-i/6,y:-i}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"lean_left"),Xt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:-2*i/6,y:0},{x:a+2*i/6,y:0},{x:a-i/6,y:-i},{x:i/6,y:-i}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"trapezoid"),Ht=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:i/6,y:0},{x:a-i/6,y:0},{x:a+2*i/6,y:-i},{x:-2*i/6,y:-i}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"inv_trapezoid"),Ut=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:0,y:0},{x:a+i/2,y:0},{x:a,y:-i/2},{x:a+i/2,y:-i},{x:0,y:-i}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"rect_right_inv_arrow"),Zt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=a/2,n=i/(2.5+a/50),o=s.height+n+e.padding,l="M 0,"+n+" a "+i+","+n+" 0,0,0 "+a+" 0 a "+i+","+n+" 0,0,0 "+-a+" 0 l 0,"+o+" a "+i+","+n+" 0,0,0 "+a+" 0 l 0,"+-o,c=r.attr("label-offset-y",n).insert("path",":first-child").attr("style",e.style).attr("d",l).attr("transform","translate("+-a/2+","+-(o/2+n)+")");return $t(e,c),e.intersect=function(t){const r=Nt.rect(e,t),s=r.x-e.x;if(0!=i&&(Math.abs(s)e.height/2-n)){let a=n*n*(1-s*s/(i*i));0!=a&&(a=Math.sqrt(a)),a=n-a,t.y-e.y>0&&(a=-a),r.y+=a}return r},r}),"cylinder"),qt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s,halfPadding:a}=await Tt(t,e,"node "+e.classes+" "+e.class,!0),i=r.insert("rect",":first-child"),n=e.positioned?e.width:s.width+e.padding,l=e.positioned?e.height:s.height+e.padding,c=e.positioned?-n/2:-s.width/2-a,d=e.positioned?-l/2:-s.height/2-a;if(i.attr("class","basic label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",d).attr("width",n).attr("height",l),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(Vt(i,e.props.borders,n,l),t.delete("borders")),t.forEach((t=>{o.Rm.warn(`Unknown node property ${t}`)}))}return $t(e,i),e.intersect=function(t){return Nt.rect(e,t)},r}),"rect"),Gt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s,halfPadding:a}=await Tt(t,e,"node "+e.classes,!0),i=r.insert("rect",":first-child"),n=e.positioned?e.width:s.width+e.padding,l=e.positioned?e.height:s.height+e.padding,c=e.positioned?-n/2:-s.width/2-a,d=e.positioned?-l/2:-s.height/2-a;if(i.attr("class","basic cluster composite label-container").attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("x",c).attr("y",d).attr("width",n).attr("height",l),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(Vt(i,e.props.borders,n,l),t.delete("borders")),t.forEach((t=>{o.Rm.warn(`Unknown node property ${t}`)}))}return $t(e,i),e.intersect=function(t){return Nt.rect(e,t)},r}),"composite"),Jt=(0,o.K2)((async(t,e)=>{const{shapeSvg:r}=await Tt(t,e,"label",!0);o.Rm.trace("Classes = ",e.class);const s=r.insert("rect",":first-child");if(s.attr("width",0).attr("height",0),r.attr("class","label edgeLabel"),e.props){const t=new Set(Object.keys(e.props));e.props.borders&&(Vt(s,e.props.borders,0,0),t.delete("borders")),t.forEach((t=>{o.Rm.warn(`Unknown node property ${t}`)}))}return $t(e,s),e.intersect=function(t){return Nt.rect(e,t)},r}),"labelRect");function Vt(t,e,r,s){const a=[],i=(0,o.K2)((t=>{a.push(t,0)}),"addBorder"),n=(0,o.K2)((t=>{a.push(0,t)}),"skipBorder");e.includes("t")?(o.Rm.debug("add top border"),i(r)):n(r),e.includes("r")?(o.Rm.debug("add right border"),i(s)):n(s),e.includes("b")?(o.Rm.debug("add bottom border"),i(r)):n(r),e.includes("l")?(o.Rm.debug("add left border"),i(s)):n(s),t.attr("stroke-dasharray",a.join(" "))}(0,o.K2)(Vt,"applyNodePropertyBorders");var Qt=(0,o.K2)(((t,e)=>{let r;r=e.classes?"node "+e.classes:"node default";const s=t.insert("g").attr("class",r).attr("id",e.domId||e.id),a=s.insert("rect",":first-child"),i=s.insert("line"),n=s.insert("g").attr("class","label"),l=e.labelText.flat?e.labelText.flat():e.labelText;let c="";c="object"==typeof l?l[0]:l,o.Rm.info("Label text abc79",c,l,"object"==typeof l);const d=n.node().appendChild(it(c,e.labelStyle,!0,!0));let g={width:0,height:0};if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=d.children[0],e=(0,h.Ltv)(d);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}o.Rm.info("Text 2",l);const u=l.slice(1,l.length);let p=d.getBBox();const y=n.node().appendChild(it(u.join?u.join("
"):u,e.labelStyle,!0,!0));if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=y.children[0],e=(0,h.Ltv)(y);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}const b=e.padding/2;return(0,h.Ltv)(y).attr("transform","translate( "+(g.width>p.width?0:(p.width-g.width)/2)+", "+(p.height+b+5)+")"),(0,h.Ltv)(d).attr("transform","translate( "+(g.width{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.height+e.padding,i=s.width+a/4+e.padding,n=r.insert("rect",":first-child").attr("style",e.style).attr("rx",a/2).attr("ry",a/2).attr("x",-i/2).attr("y",-a/2).attr("width",i).attr("height",a);return $t(e,n),e.intersect=function(t){return Nt.rect(e,t)},r}),"stadium"),ee=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s,halfPadding:a}=await Tt(t,e,Bt(e,void 0),!0),i=r.insert("circle",":first-child");return i.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",s.width/2+a).attr("width",s.width+e.padding).attr("height",s.height+e.padding),o.Rm.info("Circle main"),$t(e,i),e.intersect=function(t){return o.Rm.info("Circle intersect",e,s.width/2+a,t),Nt.circle(e,s.width/2+a,t)},r}),"circle"),re=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s,halfPadding:a}=await Tt(t,e,Bt(e,void 0),!0),i=r.insert("g",":first-child"),n=i.insert("circle"),l=i.insert("circle");return i.attr("class",e.class),n.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",s.width/2+a+5).attr("width",s.width+e.padding+10).attr("height",s.height+e.padding+10),l.attr("style",e.style).attr("rx",e.rx).attr("ry",e.ry).attr("r",s.width/2+a).attr("width",s.width+e.padding).attr("height",s.height+e.padding),o.Rm.info("DoubleCircle main"),$t(e,n),e.intersect=function(t){return o.Rm.info("DoubleCircle intersect",e,s.width/2+a+5,t),Nt.circle(e,s.width/2+a+5,t)},r}),"doublecircle"),se=(0,o.K2)((async(t,e)=>{const{shapeSvg:r,bbox:s}=await Tt(t,e,Bt(e,void 0),!0),a=s.width+e.padding,i=s.height+e.padding,n=[{x:0,y:0},{x:a,y:0},{x:a,y:-i},{x:0,y:-i},{x:0,y:0},{x:-8,y:0},{x:a+8,y:0},{x:a+8,y:-i},{x:-8,y:-i},{x:-8,y:0}],o=At(r,a,i,n);return o.attr("style",e.style),$t(e,o),e.intersect=function(t){return Nt.polygon(e,n,t)},r}),"subroutine"),ae=(0,o.K2)(((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),s=r.insert("circle",":first-child");return s.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),$t(e,s),e.intersect=function(t){return Nt.circle(e,7,t)},r}),"start"),ie=(0,o.K2)(((t,e,r)=>{const s=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let a=70,i=10;"LR"===r&&(a=10,i=70);const n=s.append("rect").attr("x",-1*a/2).attr("y",-1*i/2).attr("width",a).attr("height",i).attr("class","fork-join");return $t(e,n),e.height=e.height+e.padding/2,e.width=e.width+e.padding/2,e.intersect=function(t){return Nt.rect(e,t)},s}),"forkJoin"),ne={rhombus:zt,composite:Gt,question:zt,rect:qt,labelRect:Jt,rectWithTitle:Qt,choice:Mt,circle:ee,doublecircle:re,stadium:te,hexagon:Pt,block_arrow:Yt,rect_left_inv_arrow:Ft,lean_right:jt,lean_left:Wt,trapezoid:Xt,inv_trapezoid:Ht,rect_right_inv_arrow:Ut,cylinder:Zt,start:ae,end:(0,o.K2)(((t,e)=>{const r=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),s=r.insert("circle",":first-child"),a=r.insert("circle",":first-child");return a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14),s.attr("class","state-end").attr("r",5).attr("width",10).attr("height",10),$t(e,a),e.intersect=function(t){return Nt.circle(e,7,t)},r}),"end"),note:It,subroutine:se,fork:ie,join:ie,class_box:(0,o.K2)(((t,e)=>{const r=e.padding/2;let s;s=e.classes?"node "+e.classes:"node default";const a=t.insert("g").attr("class",s).attr("id",e.domId||e.id),i=a.insert("rect",":first-child"),n=a.insert("line"),l=a.insert("line");let c=0,d=4;const g=a.insert("g").attr("class","label");let u=0;const p=e.classData.annotations?.[0],y=e.classData.annotations[0]?"\xab"+e.classData.annotations[0]+"\xbb":"",b=g.node().appendChild(it(y,e.labelStyle,!0,!0));let x=b.getBBox();if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=b.children[0],e=(0,h.Ltv)(b);x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}e.classData.annotations[0]&&(d+=x.height+4,c+=x.width);let f=e.classData.label;void 0!==e.classData.type&&""!==e.classData.type&&((0,o.D7)().flowchart.htmlLabels?f+="<"+e.classData.type+">":f+="<"+e.classData.type+">");const m=g.node().appendChild(it(f,e.labelStyle,!0,!0));(0,h.Ltv)(m).attr("class","classTitle");let w=m.getBBox();if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=m.children[0],e=(0,h.Ltv)(m);w=t.getBoundingClientRect(),e.attr("width",w.width),e.attr("height",w.height)}d+=w.height+4,w.width>c&&(c=w.width);const _=[];e.classData.members.forEach((t=>{const r=t.getDisplayDetails();let s=r.displayText;(0,o.D7)().flowchart.htmlLabels&&(s=s.replace(//g,">"));const a=g.node().appendChild(it(s,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let i=a.getBBox();if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=a.children[0],e=(0,h.Ltv)(a);i=t.getBoundingClientRect(),e.attr("width",i.width),e.attr("height",i.height)}i.width>c&&(c=i.width),d+=i.height+4,_.push(a)})),d+=8;const L=[];if(e.classData.methods.forEach((t=>{const r=t.getDisplayDetails();let s=r.displayText;(0,o.D7)().flowchart.htmlLabels&&(s=s.replace(//g,">"));const a=g.node().appendChild(it(s,r.cssStyle?r.cssStyle:e.labelStyle,!0,!0));let i=a.getBBox();if((0,o._3)((0,o.D7)().flowchart.htmlLabels)){const t=a.children[0],e=(0,h.Ltv)(a);i=t.getBoundingClientRect(),e.attr("width",i.width),e.attr("height",i.height)}i.width>c&&(c=i.width),d+=i.height+4,L.push(a)})),d+=8,p){let t=(c-x.width)/2;(0,h.Ltv)(b).attr("transform","translate( "+(-1*c/2+t)+", "+-1*d/2+")"),u=x.height+4}let k=(c-w.width)/2;return(0,h.Ltv)(m).attr("transform","translate( "+(-1*c/2+k)+", "+(-1*d/2+u)+")"),u+=w.height+4,n.attr("class","divider").attr("x1",-c/2-r).attr("x2",c/2+r).attr("y1",-d/2-r+8+u).attr("y2",-d/2-r+8+u),u+=8,_.forEach((t=>{(0,h.Ltv)(t).attr("transform","translate( "+-c/2+", "+(-1*d/2+u+4)+")");const e=t?.getBBox();u+=(e?.height??0)+4})),u+=8,l.attr("class","divider").attr("x1",-c/2-r).attr("x2",c/2+r).attr("y1",-d/2-r+8+u).attr("y2",-d/2-r+8+u),u+=8,L.forEach((t=>{(0,h.Ltv)(t).attr("transform","translate( "+-c/2+", "+(-1*d/2+u)+")");const e=t?.getBBox();u+=(e?.height??0)+4})),i.attr("style",e.style).attr("class","outer title-state").attr("x",-c/2-r).attr("y",-d/2-r).attr("width",c+e.padding).attr("height",d+e.padding),$t(e,i),e.intersect=function(t){return Nt.rect(e,t)},a}),"class_box")},oe={},le=(0,o.K2)((async(t,e,r)=>{let s,a;if(e.link){let i;"sandbox"===(0,o.D7)().securityLevel?i="_top":e.linkTarget&&(i=e.linkTarget||"_blank"),s=t.insert("svg:a").attr("xlink:href",e.link).attr("target",i),a=await ne[e.shape](s,e,r)}else a=await ne[e.shape](t,e,r),s=a;return e.tooltip&&a.attr("title",e.tooltip),e.class&&a.attr("class","node default "+e.class),oe[e.id]=s,e.haveCallback&&oe[e.id].attr("class",oe[e.id].attr("class")+" clickable"),s}),"insertNode"),ce=(0,o.K2)((t=>{const e=oe[t.id];o.Rm.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r}),"positionNode");function de(t,e,r=!1){const s=t;let a="default";(s?.classes?.length||0)>0&&(a=(s?.classes??[]).join(" ")),a+=" flowchart-label";let i,l=0,c="";switch(s.type){case"round":l=5,c="rect";break;case"composite":l=0,c="composite",i=0;break;case"square":case"group":default:c="rect";break;case"diamond":c="question";break;case"hexagon":c="hexagon";break;case"block_arrow":c="block_arrow";break;case"odd":case"rect_left_inv_arrow":c="rect_left_inv_arrow";break;case"lean_right":c="lean_right";break;case"lean_left":c="lean_left";break;case"trapezoid":c="trapezoid";break;case"inv_trapezoid":c="inv_trapezoid";break;case"circle":c="circle";break;case"ellipse":c="ellipse";break;case"stadium":c="stadium";break;case"subroutine":c="subroutine";break;case"cylinder":c="cylinder";break;case"doublecircle":c="doublecircle"}const d=(0,n.sM)(s?.styles??[]),h=s.label,g=s.size??{width:0,height:0,x:0,y:0};return{labelStyle:d.labelStyle,shape:c,labelText:h,rx:l,ry:l,class:a,style:d.style,id:s.id,directions:s.directions,width:g.width,height:g.height,x:g.x,y:g.y,positioned:r,intersect:void 0,type:s.type,padding:i??(0,o.zj)()?.block?.padding??0}}async function he(t,e,r){const s=de(e,0,!1);if("group"===s.type)return;const a=(0,o.zj)(),i=await le(t,s,{config:a}),n=i.node().getBBox(),l=r.getBlock(s.id);l.size={width:n.width,height:n.height,x:0,y:0,node:i},r.setBlock(l),i.remove()}async function ge(t,e,r){const s=de(e,0,!0);if("space"!==r.getBlock(s.id).type){const r=(0,o.zj)();await le(t,s,{config:r}),e.intersect=s?.intersect,ce(s)}}async function ue(t,e,r,s){for(const a of e)await s(t,a,r),a.children&&await ue(t,a.children,r,s)}async function pe(t,e,r){await ue(t,e,r,he)}async function ye(t,e,r){await ue(t,e,r,ge)}async function be(t,e,r,s,a){const i=new g.T({multigraph:!0,compound:!0});i.setGraph({rankdir:"TB",nodesep:10,ranksep:10,marginx:8,marginy:8});for(const n of r)n.size&&i.setNode(n.id,{width:n.size.width,height:n.size.height,intersect:n.intersect});for(const n of e)if(n.start&&n.end){const e=s.getBlock(n.start),r=s.getBlock(n.end);if(e?.size&&r?.size){const s=e.size,o=r.size,l=[{x:s.x,y:s.y},{x:s.x+(o.x-s.x)/2,y:s.y+(o.y-s.y)/2},{x:o.x,y:o.y}];xt(t,{v:n.start,w:n.end,name:n.id},{...n,arrowTypeEnd:n.arrowTypeEnd,arrowTypeStart:n.arrowTypeStart,points:l,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"},void 0,"block",i,a),n.label&&(await ht(t,{...n,label:n.label,labelStyle:"stroke: #333; stroke-width: 1.5px;fill:none;",arrowTypeEnd:n.arrowTypeEnd,arrowTypeStart:n.arrowTypeStart,points:l,classes:"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1"}),ut({...n,x:l[1].x,y:l[1].y},{originalPath:l}))}}}(0,o.K2)(de,"getNodeFromBlock"),(0,o.K2)(he,"calculateBlockSize"),(0,o.K2)(ge,"insertBlockPositioned"),(0,o.K2)(ue,"performOperations"),(0,o.K2)(pe,"calculateBlockSizes"),(0,o.K2)(ye,"insertBlocks"),(0,o.K2)(be,"insertEdges");var xe=(0,o.K2)((function(t,e){return e.db.getClasses()}),"getClasses"),fe={parser:p,db:W,renderer:{draw:(0,o.K2)((async function(t,e,r,s){const{securityLevel:a,block:i}=(0,o.zj)(),n=s.db;let l;"sandbox"===a&&(l=(0,h.Ltv)("#i"+e));const c="sandbox"===a?(0,h.Ltv)(l.nodes()[0].contentDocument.body):(0,h.Ltv)("body"),d="sandbox"===a?c.select(`[id="${e}"]`):(0,h.Ltv)(`[id="${e}"]`);q(d,["point","circle","cross"],s.type,e);const g=n.getBlocks(),u=n.getBlocksFlat(),p=n.getEdges(),y=d.insert("g").attr("class","block");await pe(y,g,n);const b=rt(n);if(await ye(y,g,n),await be(y,p,u,n,e),b){const t=b,e=Math.max(1,Math.round(t.width/t.height*.125)),r=t.height+e+10,s=t.width+10,{useMaxWidth:a}=i;(0,o.a$)(d,r,s,!!a),o.Rm.debug("Here Bounds",b,t),d.attr("viewBox",`${t.x-5} ${t.y-5} ${t.width+10} ${t.height+10}`)}}),"draw"),getClasses:xe},styles:H}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/39db4684.7504d8d4.js b/pr-preview/pr-976/assets/js/39db4684.7504d8d4.js new file mode 100644 index 0000000000..18bd023d82 --- /dev/null +++ b/pr-preview/pr-976/assets/js/39db4684.7504d8d4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3459],{67766:(e,t,n)=>{n.d(t,{A:()=>N});var r=n(96540),s=n(34164),o=n(85246),c=n(57880),i=n(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function b(e){let{href:t,children:n}=e;return(0,g.jsx)(c.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function j(e){let{href:t,icon:n,title:r,description:o}=e;return(0,g.jsxs)(b,{href:t,children:[(0,g.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:r,children:[n," ",r]}),o&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:o,children:o})]})}function v(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(j,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function w(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,g.jsx)(j,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function y(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(w,{item:t});case"category":return(0,g.jsx)(v,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function A(e){let{className:t}=e;const n=(0,o.$S)();return(0,g.jsx)(N,{items:n.items,className:t})}function N(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(A,{...e});const r=(0,o.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(y,{item:e})},t)))})}},56860:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"about/index","title":"About","description":"","source":"@site/versioned_docs/version-0.7/about/index.md","sourceDirName":"about","slug":"/about/","permalink":"/contrast/pr-preview/pr-976/0.7/about/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/about/index.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.7/features-limitations"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/0.7/about/telemetry"}}');var s=n(74848),o=n(28453),c=n(67766);const i={},a="About",l={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"about",children:"About"})}),"\n","\n",(0,s.jsx)(c.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(96540);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3a77bb3e.ae0e3a69.js b/pr-preview/pr-976/assets/js/3a77bb3e.ae0e3a69.js new file mode 100644 index 0000000000..4096d5e224 --- /dev/null +++ b/pr-preview/pr-976/assets/js/3a77bb3e.ae0e3a69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1889],{34690:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-0.5/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/getting-started/cluster-setup.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/install"},"next":{"title":"First steps","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which has\nthe permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "$azResourceGroup" \\\n --location "$azLocation"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First create an AKS cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "$azResourceGroup" \\\n --name "$azClusterName" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "$azResourceGroup" \\\n --name nodepool2 \\\n --cluster-name "$azClusterName" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "$azResourceGroup" \\\n --name "$azClusterName"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "$azResourceGroup"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "$azResourceGroup" \\\n --name "$azClusterName"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3d96af17.ef1ae4be.js b/pr-preview/pr-976/assets/js/3d96af17.ef1ae4be.js new file mode 100644 index 0000000000..b606b2c952 --- /dev/null +++ b/pr-preview/pr-976/assets/js/3d96af17.ef1ae4be.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4506],{78016:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-1.1/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/getting-started/cluster-setup.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/getting-started/install"},"next":{"title":"Bare metal setup","permalink":"/contrast/pr-preview/pr-976/getting-started/bare-metal"}}');var t=r(74848),a=r(28453);const o={},i="Create a cluster",c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Install version 2.44.1 or newer of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),". Note that your package manager will likely install an outdated version."]}),"\n",(0,t.jsxs)(n.li,{children:["Install a recent version of ",(0,t.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsx)(n.p,{children:"First, log in to your Azure subscription:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First, create a CoCo enabled AKS cluster with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.30 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["For validation, list the available nodes using ",(0,t.jsx)(n.code,{children:"kubectl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show a single node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready 9m47s v1.29.0\n"})}),"\n",(0,t.jsxs)(n.p,{children:["\ud83e\udd73 Congratulations. You're now ready to set up your first application with Contrast. Follow this ",(0,t.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/examples/emojivoto",children:"example"})," to learn how."]}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>i});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3d9be0cc.1005a9e5.js b/pr-preview/pr-976/assets/js/3d9be0cc.1005a9e5.js new file mode 100644 index 0000000000..4ecfcc1989 --- /dev/null +++ b/pr-preview/pr-976/assets/js/3d9be0cc.1005a9e5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5310],{51550:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-0.5/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/examples/emojivoto.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.5/examples/"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.5/deployment"}}');var i=n(74848),a=n(28453);const s={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(94239).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Get the deployment."})," This is currently available as part of the preview bundle."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA runtime class ",(0,i.jsx)(t.code,{children:"kata-cc-isolation"})," was added to the pods to signal they should be run\nas Confidential Containers. In addition, the Contrast Initializer was added\nas an init container to these workloads to facilitate the attestation and certificate pulling\nbefore the actual workload is started."]})}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the embedded reference values to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, we're ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The emojivoto version we're using is patched to only communicate\nvia mTLS (the original app talks plain HTTP). The different parts of the workload are configured\nto use the credentials from the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with each other."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using embedded reference values. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-root.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-root.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-root.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-root.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh root certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-root.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh root certificate on the manifest update. Workload certificates issued\nafter the manifest are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-root.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-root.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},94239:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var o=n(96540);const i={},a=o.createContext(i);function s(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/3e02a241.10a2e2ba.js b/pr-preview/pr-976/assets/js/3e02a241.10a2e2ba.js new file mode 100644 index 0000000000..dbc40d798a --- /dev/null +++ b/pr-preview/pr-976/assets/js/3e02a241.10a2e2ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8117],{28072:(t,e,i)=>{i.r(e),i.d(e,{assets:()=>a,contentTitle:()=>o,default:()=>u,frontMatter:()=>c,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/certificates-and-identities/pki","title":"pki","description":"","source":"@site/versioned_docs/version-0.5/architecture/certificates-and-identities/pki.md","sourceDirName":"architecture/certificates-and-identities","slug":"/architecture/certificates-and-identities/pki","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/certificates-and-identities/pki.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificates and Identities","permalink":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities"},"next":{"title":"Network Encryption","permalink":"/contrast/pr-preview/pr-976/0.5/category/network-encryption"}}');var r=i(74848),s=i(28453);const c={},o=void 0,a={},d=[];function p(t){return(0,r.jsx)(r.Fragment,{})}function u(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(p,{...t})}):p()}},28453:(t,e,i)=>{i.d(e,{R:()=>c,x:()=>o});var n=i(96540);const r={},s=n.createContext(r);function c(t){const e=n.useContext(s);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:c(t.components),n.createElement(s.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/41b31679.7dba08fd.js b/pr-preview/pr-976/assets/js/41b31679.7dba08fd.js new file mode 100644 index 0000000000..062c18a789 --- /dev/null +++ b/pr-preview/pr-976/assets/js/41b31679.7dba08fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4714],{65324:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});const o=JSON.parse('{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","source":"@site/versioned_docs/version-0.9/troubleshooting.md","sourceDirName":".","slug":"/troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.9/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/troubleshooting.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.9/deployment"},"next":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/0.9/components/overview"}}');var i=t(74848),s=t(28453);const a={},r="Troubleshooting",c={},d=[{value:"Logging",id:"logging",level:2},{value:"CLI",id:"cli",level:3},{value:"Coordinator and Initializer",id:"coordinator-and-initializer",level:3},{value:"Pod fails to start",id:"pod-fails-to-start",level:2},{value:"Regenerating the policies",id:"regenerating-the-policies",level:3},{value:"Pin container images",id:"pin-container-images",level:3},{value:"Validate Contrast components match",id:"validate-contrast-components-match",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section contains information on how to debug your Contrast deployment."}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"Collecting logs can be a good first step to identify problems in your\ndeployment. Both the CLI and the Contrast Coordinator as well as the Initializer\ncan be configured to emit additional logs."}),"\n",(0,i.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.p,{children:["The CLI logs can be configured with the ",(0,i.jsx)(n.code,{children:"--log-level"})," command-line flag, which\ncan be set to either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"})," or ",(0,i.jsx)(n.code,{children:"error"}),". The default is ",(0,i.jsx)(n.code,{children:"info"}),".\nSetting this to ",(0,i.jsx)(n.code,{children:"debug"})," can get more fine-grained information as to where the\nproblem lies."]}),"\n",(0,i.jsx)(n.h3,{id:"coordinator-and-initializer",children:"Coordinator and Initializer"}),"\n",(0,i.jsxs)(n.p,{children:["The logs from the Coordinator and the Initializer can be configured via the\nenvironment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"}),", ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," and\n",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"})," can be set to one of either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"}),", or\n",(0,i.jsx)(n.code,{children:"error"}),", similar to the CLI (defaults to ",(0,i.jsx)(n.code,{children:"info"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," can be set to ",(0,i.jsx)(n.code,{children:"text"})," or ",(0,i.jsx)(n.code,{children:"json"}),", determining the output\nformat (defaults to ",(0,i.jsx)(n.code,{children:"text"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," is a comma-seperated list of subsystems that should\nbe enabled for logging, which are disabled by default. Subsystems include:\n",(0,i.jsx)(n.code,{children:"kds-getter"}),", ",(0,i.jsx)(n.code,{children:"issuer"})," and ",(0,i.jsx)(n.code,{children:"validator"}),".\nTo enable all subsystems, use ",(0,i.jsx)(n.code,{children:"*"})," as the value for this environment variable.\nWarnings and error messages from subsystems get printed regardless of whether\nthe subsystem is listed in the ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," environment variable."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"To configure debug logging with all subsystems for your Coordinator, add the\nfollowing variables to your container definition."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n containers:\n image: "ghcr.io/edgelesssys/contrast/coordinator:v0.9.0@sha256:7530dcd0bd16b5dbeda915c8ebfeb5d860c2f9e4661acbc70fdaae60bf174e20"\n name: coordinator\n env:\n - name: CONTRAST_LOG_LEVEL\n value: debug\n - name: CONTRAST_LOG_SUBSYSTEMS\n value: "*"\n # ...\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["While the Contrast Coordinator has a policy that allows certain configurations,\nthe Initializer and service mesh don't. When changing environment variables of other\nparts than the Coordinator, ensure to rerun ",(0,i.jsx)(n.code,{children:"contrast generate"})," to update the policy."]})}),"\n",(0,i.jsxs)(n.p,{children:["To access the logs generated by the Coordinator, you can use ",(0,i.jsx)(n.code,{children:"kubectl"})," with the\nfollowing command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl logs \n"})}),"\n",(0,i.jsx)(n.h2,{id:"pod-fails-to-start",children:"Pod fails to start"}),"\n",(0,i.jsxs)(n.p,{children:["If the Coordinator or a workload pod fails to even start, it can be helpful to\nlook at the events of the pod during the startup process using the ",(0,i.jsx)(n.code,{children:"describe"}),"\ncommand."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n events --for pod/\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'LAST SEEN TYPE REASON OBJECT MESSAGE\n32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"A common error, as in this example, is that the container creation was blocked by the\npolicy. Potential reasons are a modification of the deployment YAML without updating\nthe policies afterward, or a version mismatch between Contrast components."}),"\n",(0,i.jsx)(n.h3,{id:"regenerating-the-policies",children:"Regenerating the policies"}),"\n",(0,i.jsx)(n.p,{children:"To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated\npolicies, rerun"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast generate\n"})}),"\n",(0,i.jsx)(n.p,{children:"on your deployment. If any of the policy annotations change, re-deploy with the updated policies."}),"\n",(0,i.jsx)(n.h3,{id:"pin-container-images",children:"Pin container images"}),"\n",(0,i.jsx)(n.p,{children:"When generating the policies, Contrast will download the images specified in your deployment\nYAML and include their cryptographic identity. If the image tag is moved to another\ncontainer image after the policy has been generated, the image downloaded at deploy time\nwill differ from the one at generation time, and the policy enforcement won't allow the\ncontainer to be started in the pod VM."}),"\n",(0,i.jsxs)(n.p,{children:["To ensure the correct image is always used, pin the container image to a fixed ",(0,i.jsx)(n.code,{children:"sha256"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This way, the same image will still be pulled when the container tag (",(0,i.jsx)(n.code,{children:"22.04"}),") is moved\nto another image."]}),"\n",(0,i.jsx)(n.h3,{id:"validate-contrast-components-match",children:"Validate Contrast components match"}),"\n",(0,i.jsx)(n.p,{children:"A version mismatch between Contrast components can cause policy validation or attestation\nto fail. Each Contrast runtime is identifiable based on its (shortened) measurement value\nused to name the runtime class version."}),"\n",(0,i.jsx)(n.p,{children:"First, analyze which runtime class is currently installed in your cluster by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl get runtimeclasses\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give you output similar to the following one."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"NAME HANDLER AGE\ncontrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h\nkata-cc-isolation kata-cc 45d\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided\nby the AKS CoCo preview, which isn't used by Contrast)."}),"\n",(0,i.jsx)(n.p,{children:"Next, check if the pod that won't start has the correct runtime class configured, and the\nCoordinator uses the exact same runtime:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n get -o=jsonpath='{.spec.runtimeClassName}' pod/\nkubectl -n get -o=jsonpath='{.spec.runtimeClassName}' pod/\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output should list the runtime class the pod is using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast-cc-aks-clh-snp-7173acb5\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Version information about the currently used CLI can be obtained via the ",(0,i.jsx)(n.code,{children:"version"})," flag:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast --version\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast version v0.X.0\n\n runtime handler: contrast-cc-aks-clh-snp-7173acb5\n launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35\n genpolicy version: 3.2.0.azl1.genpolicy0\n image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...\n ghcr.io/edgelesssys/contrast/initializer@sha256:...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4445.3811e3c0.js b/pr-preview/pr-976/assets/js/4445.3811e3c0.js new file mode 100644 index 0000000000..f504365ca9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4445.3811e3c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4445],{14445:(t,e,n)=>{n.d(e,{diagram:()=>D});var i=n(79515),s=n(5081),r=(n(34483),n(62392),n(86825),n(85039),n(61021)),o=n(45567),a=n(3219),c=n(78041),l=n(75263),h=function(){var t=(0,o.K2)((function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n}),"o"),e=[1,4],n=[1,13],i=[1,12],s=[1,15],r=[1,16],a=[1,20],c=[1,19],l=[6,7,8],h=[1,26],u=[1,24],g=[1,25],d=[6,7,11],p=[1,31],y=[6,7,11,24],f=[1,6,13,16,17,20,23],m=[1,35],_=[1,36],b=[1,6,7,11,13,16,17,20,23],k=[1,38],E={trace:(0,o.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:(0,o.K2)((function(t,e,n,i,s,r,o){var a=r.length-1;switch(s){case 6:case 7:return i;case 8:i.getLogger().trace("Stop NL ");break;case 9:i.getLogger().trace("Stop EOF ");break;case 11:i.getLogger().trace("Stop NL2 ");break;case 12:i.getLogger().trace("Stop EOF2 ");break;case 15:i.getLogger().info("Node: ",r[a-1].id),i.addNode(r[a-2].length,r[a-1].id,r[a-1].descr,r[a-1].type,r[a]);break;case 16:i.getLogger().info("Node: ",r[a].id),i.addNode(r[a-1].length,r[a].id,r[a].descr,r[a].type);break;case 17:i.getLogger().trace("Icon: ",r[a]),i.decorateNode({icon:r[a]});break;case 18:case 23:i.decorateNode({class:r[a]});break;case 19:i.getLogger().trace("SPACELIST");break;case 20:i.getLogger().trace("Node: ",r[a-1].id),i.addNode(0,r[a-1].id,r[a-1].descr,r[a-1].type,r[a]);break;case 21:i.getLogger().trace("Node: ",r[a].id),i.addNode(0,r[a].id,r[a].descr,r[a].type);break;case 22:i.decorateNode({icon:r[a]});break;case 27:i.getLogger().trace("node found ..",r[a-2]),this.$={id:r[a-1],descr:r[a-1],type:i.getType(r[a-2],r[a])};break;case 28:this.$={id:r[a],descr:r[a],type:0};break;case 29:i.getLogger().trace("node found ..",r[a-3]),this.$={id:r[a-3],descr:r[a-1],type:i.getType(r[a-2],r[a])};break;case 30:this.$=r[a-1]+r[a];break;case 31:this.$=r[a]}}),"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:n,7:[1,10],9:9,12:11,13:i,14:14,16:s,17:r,18:17,19:18,20:a,23:c},t(l,[2,3]),{1:[2,2]},t(l,[2,4]),t(l,[2,5]),{1:[2,6],6:n,12:21,13:i,14:14,16:s,17:r,18:17,19:18,20:a,23:c},{6:n,9:22,12:11,13:i,14:14,16:s,17:r,18:17,19:18,20:a,23:c},{6:h,7:u,10:23,11:g},t(d,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:a,23:c}),t(d,[2,19]),t(d,[2,21],{15:30,24:p}),t(d,[2,22]),t(d,[2,23]),t(y,[2,25]),t(y,[2,26]),t(y,[2,28],{20:[1,32]}),{21:[1,33]},{6:h,7:u,10:34,11:g},{1:[2,7],6:n,12:21,13:i,14:14,16:s,17:r,18:17,19:18,20:a,23:c},t(f,[2,14],{7:m,11:_}),t(b,[2,8]),t(b,[2,9]),t(b,[2,10]),t(d,[2,16],{15:37,24:p}),t(d,[2,17]),t(d,[2,18]),t(d,[2,20],{24:k}),t(y,[2,31]),{21:[1,39]},{22:[1,40]},t(f,[2,13],{7:m,11:_}),t(b,[2,11]),t(b,[2,12]),t(d,[2,15],{24:k}),t(y,[2,30]),{22:[1,41]},t(y,[2,27]),t(y,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:(0,o.K2)((function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)}),"parseError"),parse:(0,o.K2)((function(t){var e=this,n=[0],i=[],s=[null],r=[],a=this.table,c="",l=0,h=0,u=0,g=r.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(p.yy[y]=this.yy[y]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var f=d.yylloc;r.push(f);var m=d.options&&d.options.ranges;function _(){var t;return"number"!=typeof(t=i.pop()||d.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)((function(t){n.length=n.length-2*t,s.length=s.length-t,r.length=r.length-t}),"popStack"),(0,o.K2)(_,"lex");for(var b,k,E,S,N,x,D,L,I,C={};;){if(E=n[n.length-1],this.defaultActions[E]?S=this.defaultActions[E]:(null==b&&(b=_()),S=a[E]&&a[E][b]),void 0===S||!S.length||!S[0]){var O="";for(x in I=[],a[E])this.terminals_[x]&&x>2&&I.push("'"+this.terminals_[x]+"'");O=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+I.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(O,{text:d.match,token:this.terminals_[b]||b,line:d.yylineno,loc:f,expected:I})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+b);switch(S[0]){case 1:n.push(b),s.push(d.yytext),r.push(d.yylloc),n.push(S[1]),b=null,k?(b=k,k=null):(h=d.yyleng,c=d.yytext,l=d.yylineno,f=d.yylloc,u>0&&u--);break;case 2:if(D=this.productions_[S[1]][1],C.$=s[s.length-D],C._$={first_line:r[r.length-(D||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(D||1)].first_column,last_column:r[r.length-1].last_column},m&&(C._$.range=[r[r.length-(D||1)].range[0],r[r.length-1].range[1]]),void 0!==(N=this.performAction.apply(C,[c,h,l,p.yy,S[1],s,r].concat(g))))return N;D&&(n=n.slice(0,-1*D*2),s=s.slice(0,-1*D),r=r.slice(0,-1*D)),n.push(this.productions_[S[1]][0]),s.push(C.$),r.push(C._$),L=a[n[n.length-2]][n[n.length-1]],n.push(L);break;case 3:return!0}}return!0}),"parse")},S=function(){return{EOF:1,parseError:(0,o.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,o.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,o.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,o.K2)((function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,o.K2)((function(){return this._more=!0,this}),"more"),reject:(0,o.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,o.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,o.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,o.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,o.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,o.K2)((function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1}),"test_match"),next:(0,o.K2)((function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;re[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,o.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,o.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,o.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,o.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,o.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,o.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,o.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,o.K2)((function(t,e,n,i){switch(n){case 0:return this.pushState("shapeData"),e.yytext="",24;case 1:return this.pushState("shapeDataStr"),24;case 2:return this.popState(),24;case 3:const n=/\n\s*/g;return e.yytext=e.yytext.replace(n,"
"),24;case 4:return 24;case 5:case 10:case 29:case 32:this.popState();break;case 6:return t.getLogger().trace("Found comment",e.yytext),6;case 7:return 8;case 8:this.begin("CLASS");break;case 9:return this.popState(),17;case 11:t.getLogger().trace("Begin icon"),this.begin("ICON");break;case 12:return t.getLogger().trace("SPACELINE"),6;case 13:return 7;case 14:return 16;case 15:t.getLogger().trace("end icon"),this.popState();break;case 16:return t.getLogger().trace("Exploding node"),this.begin("NODE"),20;case 17:return t.getLogger().trace("Cloud"),this.begin("NODE"),20;case 18:return t.getLogger().trace("Explosion Bang"),this.begin("NODE"),20;case 19:return t.getLogger().trace("Cloud Bang"),this.begin("NODE"),20;case 20:case 21:case 22:case 23:return this.begin("NODE"),20;case 24:return 13;case 25:return 23;case 26:return 11;case 27:this.begin("NSTR2");break;case 28:return"NODE_DESCR";case 30:t.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 31:return t.getLogger().trace("description:",e.yytext),"NODE_DESCR";case 33:return this.popState(),t.getLogger().trace("node end ))"),"NODE_DEND";case 34:return this.popState(),t.getLogger().trace("node end )"),"NODE_DEND";case 35:return this.popState(),t.getLogger().trace("node end ...",e.yytext),"NODE_DEND";case 36:case 39:case 40:return this.popState(),t.getLogger().trace("node end (("),"NODE_DEND";case 37:case 38:return this.popState(),t.getLogger().trace("node end (-"),"NODE_DEND";case 41:case 42:return t.getLogger().trace("Long description:",e.yytext),21}}),"anonymous"),rules:[/^(?:@\{)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^\"]+)/i,/^(?:[^}^"]+)/i,/^(?:\})/i,/^(?:\s*%%.*)/i,/^(?:kanban\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}@]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{shapeDataEndBracket:{rules:[],inclusive:!1},shapeDataStr:{rules:[2,3],inclusive:!1},shapeData:{rules:[1,4,5],inclusive:!1},CLASS:{rules:[9,10],inclusive:!1},ICON:{rules:[14,15],inclusive:!1},NSTR2:{rules:[28,29],inclusive:!1},NSTR:{rules:[31,32],inclusive:!1},NODE:{rules:[27,30,33,34,35,36,37,38,39,40,41,42],inclusive:!1},INITIAL:{rules:[0,6,7,8,11,12,13,16,17,18,19,20,21,22,23,24,25,26],inclusive:!0}}}}();function N(){this.yy={}}return E.lexer=S,(0,o.K2)(N,"Parser"),N.prototype=E,E.Parser=N,new N}();h.parser=h;var u=h,g=[],d=[],p=0,y={},f=(0,o.K2)((()=>{g=[],d=[],p=0,y={}}),"clear"),m=(0,o.K2)((t=>{if(0===g.length)return null;const e=g[0].level;let n=null;for(let i=g.length-1;i>=0;i--)if(g[i].level!==e||n||(n=g[i]),g[i].levelt.parentId===i.id));for(const r of s){const e={id:r.id,parentId:i.id,label:(0,o.jZ)(r.label??"",n),isGroup:!1,ticket:r?.ticket,priority:r?.priority,assigned:r?.assigned,icon:r?.icon,shape:"kanbanItem",level:r.level,rx:5,ry:5,cssStyles:["text-align: left"]};t.push(e)}}return{nodes:t,edges:[],other:{},config:(0,o.D7)()}}),"getData"),k=(0,o.K2)(((t,e,n,s,r)=>{const a=(0,o.D7)();let c=a.mindmap?.padding??o.UI.mindmap.padding;switch(s){case E.ROUNDED_RECT:case E.RECT:case E.HEXAGON:c*=2}const l={id:(0,o.jZ)(e,a)||"kbn"+p++,level:t,label:(0,o.jZ)(n,a),width:a.mindmap?.maxNodeWidth??o.UI.mindmap.maxNodeWidth,padding:c,isGroup:!1};if(void 0!==r){let t;t=r.includes("\n")?r+"\n":"{\n"+r+"\n}";const e=(0,i.H)(t,{schema:i.r});if(e.shape&&(e.shape!==e.shape.toLowerCase()||e.shape.includes("_")))throw new Error(`No such shape: ${e.shape}. Shape names should be lowercase.`);e?.shape&&"kanbanItem"===e.shape&&(l.shape=e?.shape),e?.label&&(l.label=e?.label),e?.icon&&(l.icon=e?.icon),e?.assigned&&(l.assigned=e?.assigned),e?.ticket&&(l.ticket=e?.ticket),e?.priority&&(l.priority=e?.priority)}const h=m(t);h?l.parentId=h.id||"kbn"+p++:d.push(l),g.push(l)}),"addNode"),E={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},S={clear:f,addNode:k,getSections:_,getData:b,nodeType:E,getType:(0,o.K2)(((t,e)=>{switch(o.Rm.debug("In get type",t,e),t){case"[":return E.RECT;case"(":return")"===e?E.ROUNDED_RECT:E.CLOUD;case"((":return E.CIRCLE;case")":return E.CLOUD;case"))":return E.BANG;case"{{":return E.HEXAGON;default:return E.DEFAULT}}),"getType"),setElementForId:(0,o.K2)(((t,e)=>{y[t]=e}),"setElementForId"),decorateNode:(0,o.K2)((t=>{if(!t)return;const e=(0,o.D7)(),n=g[g.length-1];t.icon&&(n.icon=(0,o.jZ)(t.icon,e)),t.class&&(n.cssClasses=(0,o.jZ)(t.class,e))}),"decorateNode"),type2Str:(0,o.K2)((t=>{switch(t){case E.DEFAULT:return"no-border";case E.RECT:return"rect";case E.ROUNDED_RECT:return"rounded-rect";case E.CIRCLE:return"circle";case E.CLOUD:return"cloud";case E.BANG:return"bang";case E.HEXAGON:return"hexgon";default:return"no-border"}}),"type2Str"),getLogger:(0,o.K2)((()=>o.Rm),"getLogger"),getElementById:(0,o.K2)((t=>y[t]),"getElementById")},N={draw:(0,o.K2)((async(t,e,n,i)=>{o.Rm.debug("Rendering kanban diagram\n"+t);const a=i.db.getData(),c=(0,o.D7)();c.htmlLabels=!1;const l=(0,r.D)(e),h=l.append("g");h.attr("class","sections");const u=l.append("g");u.attr("class","items");const g=a.nodes.filter((t=>t.isGroup));let d=0;const p=[];let y=25;for(const r of g){const t=c?.kanban?.sectionWidth||200;d+=1,r.x=t*d+10*(d-1)/2,r.width=t,r.y=0,r.height=3*t,r.rx=5,r.ry=5,r.cssClasses=r.cssClasses+" section-"+d;const e=await(0,s.U)(h,r);y=Math.max(y,e?.labelBBox?.height),p.push(e)}let f=0;for(const r of g){const t=p[f];f+=1;const e=c?.kanban?.sectionWidth||200,n=3*-e/2+y;let i=n;const o=a.nodes.filter((t=>t.parentId===r.id));for(const a of o){if(a.isGroup)throw new Error("Groups within groups are not allowed in Kanban diagrams");a.x=r.x,a.width=e-15;const t=(await(0,s.on)(u,a,{config:c})).node().getBBox();a.y=i+t.height/2,await(0,s.U_)(a),i=a.y+t.height/2+5}const l=t.cluster.select("rect"),h=Math.max(i-n+30,50)+(y-25);l.attr("height",h)}(0,o.ot)(void 0,l,c.mindmap?.padding??o.UI.kanban.padding,c.mindmap?.useMaxWidth??o.UI.kanban.useMaxWidth)}),"draw")},x=(0,o.K2)((t=>{let e="";for(let i=0;it.darkMode?(0,l.A)(e,n):(0,c.A)(e,n)),"adjuster");for(let i=0;i`\n .edge {\n stroke-width: 3;\n }\n ${x(t)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .cluster-label, .label {\n color: ${t.textColor};\n fill: ${t.textColor};\n }\n .kanban-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4449.bb76b6fa.js b/pr-preview/pr-976/assets/js/4449.bb76b6fa.js new file mode 100644 index 0000000000..0ca96a23ac --- /dev/null +++ b/pr-preview/pr-976/assets/js/4449.bb76b6fa.js @@ -0,0 +1 @@ +(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4449],{87799:function(t,e,i){var n;n=function(t){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=7)}([function(e,i){e.exports=t},function(t,e,i){"use strict";var n=i(0).FDLayoutConstants;function r(){}for(var o in n)r[o]=n[o];r.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,r.DEFAULT_RADIAL_SEPARATION=n.DEFAULT_EDGE_LENGTH,r.DEFAULT_COMPONENT_SEPERATION=60,r.TILE=!0,r.TILING_PADDING_VERTICAL=10,r.TILING_PADDING_HORIZONTAL=10,r.TREE_REDUCTION_ON_INCREMENTAL=!1,t.exports=r},function(t,e,i){"use strict";var n=i(0).FDLayoutEdge;function r(t,e,i){n.call(this,t,e,i)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},function(t,e,i){"use strict";var n=i(0).LGraph;function r(t,e,i){n.call(this,t,e,i)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},function(t,e,i){"use strict";var n=i(0).LGraphManager;function r(t){n.call(this,t)}for(var o in r.prototype=Object.create(n.prototype),n)r[o]=n[o];t.exports=r},function(t,e,i){"use strict";var n=i(0).FDLayoutNode,r=i(0).IMath;function o(t,e,i,r){n.call(this,t,e,i,r)}for(var s in o.prototype=Object.create(n.prototype),n)o[s]=n[s];o.prototype.move=function(){var t=this.graphManager.getLayout();this.displacementX=t.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=t.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementX=t.coolingFactor*t.maxNodeDisplacement*r.sign(this.displacementX)),Math.abs(this.displacementY)>t.coolingFactor*t.maxNodeDisplacement&&(this.displacementY=t.coolingFactor*t.maxNodeDisplacement*r.sign(this.displacementY)),null==this.child||0==this.child.getNodes().length?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),t.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},o.prototype.propogateDisplacementToChildren=function(t,e){for(var i,n=this.getChild().getNodes(),r=0;r0)this.positionNodesRadially(t);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var e=new Set(this.getAllNodes()),i=this.nodesWithGravity.filter((function(t){return e.has(t)}));this.graphManager.setAllNodesToApplyGravitation(i),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},_.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}if(this.totalIterations%l.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged()){if(!(this.prunedNodesAll.length>0))return!0;this.isTreeGrowing=!0}this.coolingCycle++,0==this.layoutQuality?this.coolingAdjuster=this.coolingCycle:1==this.layoutQuality&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var t=new Set(this.getAllNodes()),e=this.nodesWithGravity.filter((function(e){return t.has(e)}));this.graphManager.setAllNodesToApplyGravitation(e),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var i=!this.isTreeGrowing&&!this.isGrowthFinished,n=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(i,n),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},_.prototype.getPositionsData=function(){for(var t=this.graphManager.getAllNodes(),e={},i=0;i1)for(a=0;an&&(n=Math.floor(s.y)),o=Math.floor(s.x+h.DEFAULT_COMPONENT_SEPERATION)}this.transform(new u(c.WORLD_CENTER_X-s.x/2,c.WORLD_CENTER_Y-s.y/2))},_.radialLayout=function(t,e,i){var n=Math.max(this.maxDiagonalInTree(t),h.DEFAULT_RADIAL_SEPARATION);_.branchRadialLayout(e,null,0,359,0,n);var r=y.calculateBounds(t),o=new E;o.setDeviceOrgX(r.getMinX()),o.setDeviceOrgY(r.getMinY()),o.setWorldOrgX(i.x),o.setWorldOrgY(i.y);for(var s=0;s1;){var E=y[0];y.splice(0,1);var m=c.indexOf(E);m>=0&&c.splice(m,1),p--,g--}u=null!=e?(c.indexOf(y[0])+1)%p:0;for(var v=Math.abs(n-i)/g,N=u;d!=g;N=++N%p){var A=c[N].getOtherEnd(t);if(A!=e){var L=(i+d*v)%360,T=(L+v)%360;_.branchRadialLayout(A,t,L,T,r+o,o),d++}}},_.maxDiagonalInTree=function(t){for(var e=p.MIN_VALUE,i=0;ie&&(e=n)}return e},_.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},_.prototype.groupZeroDegreeMembers=function(){var t=this,e={};this.memberGroups={},this.idToDummyNode={};for(var i=[],n=this.graphManager.getAllNodes(),r=0;r1){var n="DummyCompound_"+i;t.memberGroups[n]=e[i];var r=e[i][0].getParent(),o=new s(t.graphManager);o.id=n,o.paddingLeft=r.paddingLeft||0,o.paddingRight=r.paddingRight||0,o.paddingBottom=r.paddingBottom||0,o.paddingTop=r.paddingTop||0,t.idToDummyNode[n]=o;var a=t.getGraphManager().add(t.newGraph(),o),h=r.getChild();h.add(o);for(var l=0;l=0;t--){var e=this.compoundOrder[t],i=e.id,n=e.paddingLeft,r=e.paddingTop;this.adjustLocations(this.tiledMemberPack[i],e.rect.x,e.rect.y,n,r)}},_.prototype.repopulateZeroDegreeMembers=function(){var t=this,e=this.tiledZeroDegreePack;Object.keys(e).forEach((function(i){var n=t.idToDummyNode[i],r=n.paddingLeft,o=n.paddingTop;t.adjustLocations(e[i],n.rect.x,n.rect.y,r,o)}))},_.prototype.getToBeTiled=function(t){var e=t.id;if(null!=this.toBeTiled[e])return this.toBeTiled[e];var i=t.getChild();if(null==i)return this.toBeTiled[e]=!1,!1;for(var n=i.getNodes(),r=0;r0)return this.toBeTiled[e]=!1,!1;if(null!=o.getChild()){if(!this.getToBeTiled(o))return this.toBeTiled[e]=!1,!1}else this.toBeTiled[o.id]=!1}return this.toBeTiled[e]=!0,!0},_.prototype.getNodeDegree=function(t){t.id;for(var e=t.getEdges(),i=0,n=0;nh&&(h=c.rect.height)}i+=h+t.verticalPadding}},_.prototype.tileCompoundMembers=function(t,e){var i=this;this.tiledMemberPack=[],Object.keys(t).forEach((function(n){var r=e[n];i.tiledMemberPack[n]=i.tileNodes(t[n],r.paddingLeft+r.paddingRight),r.rect.width=i.tiledMemberPack[n].width,r.rect.height=i.tiledMemberPack[n].height}))},_.prototype.tileNodes=function(t,e){var i={rows:[],rowWidth:[],rowHeight:[],width:0,height:e,verticalPadding:h.TILING_PADDING_VERTICAL,horizontalPadding:h.TILING_PADDING_HORIZONTAL};t.sort((function(t,e){return t.rect.width*t.rect.height>e.rect.width*e.rect.height?-1:t.rect.width*t.rect.height0&&(o+=t.horizontalPadding),t.rowWidth[i]=o,t.width0&&(s+=t.verticalPadding);var a=0;s>t.rowHeight[i]&&(a=t.rowHeight[i],t.rowHeight[i]=s,a=t.rowHeight[i]-a),t.height+=a,t.rows[i].push(e)},_.prototype.getShortestRowIndex=function(t){for(var e=-1,i=Number.MAX_VALUE,n=0;ni&&(e=n,i=t.rowWidth[n]);return e},_.prototype.canAddHorizontal=function(t,e,i){var n=this.getShortestRowIndex(t);if(n<0)return!0;var r=t.rowWidth[n];if(r+t.horizontalPadding+e<=t.width)return!0;var o,s,a=0;return t.rowHeight[n]0&&(a=i+t.verticalPadding-t.rowHeight[n]),o=t.width-r>=e+t.horizontalPadding?(t.height+a)/(r+e+t.horizontalPadding):(t.height+a)/t.width,a=i+t.verticalPadding,(s=t.widtho&&e!=i){n.splice(-1,1),t.rows[i].push(r),t.rowWidth[e]=t.rowWidth[e]-o,t.rowWidth[i]=t.rowWidth[i]+o,t.width=t.rowWidth[instance.getLongestRowIndex(t)];for(var s=Number.MIN_VALUE,a=0;as&&(s=n[a].height);e>0&&(s+=t.verticalPadding);var h=t.rowHeight[e]+t.rowHeight[i];t.rowHeight[e]=s,t.rowHeight[i]0)for(var c=r;c<=o;c++)h[0]+=this.grid[c][s-1].length+this.grid[c][s].length-1;if(o0)for(c=s;c<=a;c++)h[3]+=this.grid[r-1][c].length+this.grid[r][c].length-1;for(var g,u,d=p.MAX_VALUE,f=0;f0&&(s=i.getGraphManager().add(i.newGraph(),o),this.processChildrenList(s,g,i))}},g.prototype.stop=function(){return this.stopped=!0,this};var d=function(t){t("layout","cose-bilkent",g)};"undefined"!=typeof cytoscape&&d(cytoscape),t.exports=d}])},t.exports=n(i(87799))},23143:function(t){var e;e=function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.i=function(t){return t},i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{configurable:!1,enumerable:!0,get:n})},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=26)}([function(t,e,i){"use strict";function n(){}n.QUALITY=1,n.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,n.DEFAULT_INCREMENTAL=!1,n.DEFAULT_ANIMATION_ON_LAYOUT=!0,n.DEFAULT_ANIMATION_DURING_LAYOUT=!1,n.DEFAULT_ANIMATION_PERIOD=50,n.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,n.DEFAULT_GRAPH_MARGIN=15,n.NODE_DIMENSIONS_INCLUDE_LABELS=!1,n.SIMPLE_NODE_SIZE=40,n.SIMPLE_NODE_HALF_SIZE=n.SIMPLE_NODE_SIZE/2,n.EMPTY_COMPOUND_NODE_SIZE=40,n.MIN_EDGE_LENGTH=1,n.WORLD_BOUNDARY=1e6,n.INITIAL_WORLD_BOUNDARY=n.WORLD_BOUNDARY/1e3,n.WORLD_CENTER_X=1200,n.WORLD_CENTER_Y=900,t.exports=n},function(t,e,i){"use strict";var n=i(2),r=i(8),o=i(9);function s(t,e,i){n.call(this,i),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=i,this.bendpoints=[],this.source=t,this.target=e}for(var a in s.prototype=Object.create(n.prototype),n)s[a]=n[a];s.prototype.getSource=function(){return this.source},s.prototype.getTarget=function(){return this.target},s.prototype.isInterGraph=function(){return this.isInterGraph},s.prototype.getLength=function(){return this.length},s.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},s.prototype.getBendpoints=function(){return this.bendpoints},s.prototype.getLca=function(){return this.lca},s.prototype.getSourceInLca=function(){return this.sourceInLca},s.prototype.getTargetInLca=function(){return this.targetInLca},s.prototype.getOtherEnd=function(t){if(this.source===t)return this.target;if(this.target===t)return this.source;throw"Node is not incident with this edge"},s.prototype.getOtherEndInGraph=function(t,e){for(var i=this.getOtherEnd(t),n=e.getGraphManager().getRoot();;){if(i.getOwner()==e)return i;if(i.getOwner()==n)break;i=i.getOwner().getParent()}return null},s.prototype.updateLength=function(){var t=new Array(4);this.isOverlapingSourceAndTarget=r.getIntersection(this.target.getRect(),this.source.getRect(),t),this.isOverlapingSourceAndTarget||(this.lengthX=t[0]-t[2],this.lengthY=t[1]-t[3],Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},s.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=o.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=o.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},t.exports=s},function(t,e,i){"use strict";t.exports=function(t){this.vGraphObject=t}},function(t,e,i){"use strict";var n=i(2),r=i(10),o=i(13),s=i(0),a=i(16),h=i(4);function l(t,e,i,s){null==i&&null==s&&(s=e),n.call(this,s),null!=t.graphManager&&(t=t.graphManager),this.estimatedSize=r.MIN_VALUE,this.inclusionTreeDepth=r.MAX_VALUE,this.vGraphObject=s,this.edges=[],this.graphManager=t,this.rect=null!=i&&null!=e?new o(e.x,e.y,i.width,i.height):new o}for(var c in l.prototype=Object.create(n.prototype),n)l[c]=n[c];l.prototype.getEdges=function(){return this.edges},l.prototype.getChild=function(){return this.child},l.prototype.getOwner=function(){return this.owner},l.prototype.getWidth=function(){return this.rect.width},l.prototype.setWidth=function(t){this.rect.width=t},l.prototype.getHeight=function(){return this.rect.height},l.prototype.setHeight=function(t){this.rect.height=t},l.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},l.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},l.prototype.getCenter=function(){return new h(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},l.prototype.getLocation=function(){return new h(this.rect.x,this.rect.y)},l.prototype.getRect=function(){return this.rect},l.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},l.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},l.prototype.setRect=function(t,e){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=e.width,this.rect.height=e.height},l.prototype.setCenter=function(t,e){this.rect.x=t-this.rect.width/2,this.rect.y=e-this.rect.height/2},l.prototype.setLocation=function(t,e){this.rect.x=t,this.rect.y=e},l.prototype.moveBy=function(t,e){this.rect.x+=t,this.rect.y+=e},l.prototype.getEdgeListToNode=function(t){var e=[],i=this;return i.edges.forEach((function(n){if(n.target==t){if(n.source!=i)throw"Incorrect edge source!";e.push(n)}})),e},l.prototype.getEdgesBetween=function(t){var e=[],i=this;return i.edges.forEach((function(n){if(n.source!=i&&n.target!=i)throw"Incorrect edge source and/or target";n.target!=t&&n.source!=t||e.push(n)})),e},l.prototype.getNeighborsList=function(){var t=new Set,e=this;return e.edges.forEach((function(i){if(i.source==e)t.add(i.target);else{if(i.target!=e)throw"Incorrect incidency!";t.add(i.source)}})),t},l.prototype.withChildren=function(){var t=new Set;if(t.add(this),null!=this.child)for(var e=this.child.getNodes(),i=0;ie&&(this.rect.x-=(this.labelWidth-e)/2,this.setWidth(this.labelWidth)),this.labelHeight>i&&("center"==this.labelPos?this.rect.y-=(this.labelHeight-i)/2:"top"==this.labelPos&&(this.rect.y-=this.labelHeight-i),this.setHeight(this.labelHeight))}}},l.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==r.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},l.prototype.transform=function(t){var e=this.rect.x;e>s.WORLD_BOUNDARY?e=s.WORLD_BOUNDARY:e<-s.WORLD_BOUNDARY&&(e=-s.WORLD_BOUNDARY);var i=this.rect.y;i>s.WORLD_BOUNDARY?i=s.WORLD_BOUNDARY:i<-s.WORLD_BOUNDARY&&(i=-s.WORLD_BOUNDARY);var n=new h(e,i),r=t.inverseTransformPoint(n);this.setLocation(r.x,r.y)},l.prototype.getLeft=function(){return this.rect.x},l.prototype.getRight=function(){return this.rect.x+this.rect.width},l.prototype.getTop=function(){return this.rect.y},l.prototype.getBottom=function(){return this.rect.y+this.rect.height},l.prototype.getParent=function(){return null==this.owner?null:this.owner.getParent()},t.exports=l},function(t,e,i){"use strict";function n(t,e){null==t&&null==e?(this.x=0,this.y=0):(this.x=t,this.y=e)}n.prototype.getX=function(){return this.x},n.prototype.getY=function(){return this.y},n.prototype.setX=function(t){this.x=t},n.prototype.setY=function(t){this.y=t},n.prototype.getDifference=function(t){return new DimensionD(this.x-t.x,this.y-t.y)},n.prototype.getCopy=function(){return new n(this.x,this.y)},n.prototype.translate=function(t){return this.x+=t.width,this.y+=t.height,this},t.exports=n},function(t,e,i){"use strict";var n=i(2),r=i(10),o=i(0),s=i(6),a=i(3),h=i(1),l=i(13),c=i(12),g=i(11);function u(t,e,i){n.call(this,i),this.estimatedSize=r.MIN_VALUE,this.margin=o.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=t,null!=e&&e instanceof s?this.graphManager=e:null!=e&&e instanceof Layout&&(this.graphManager=e.graphManager)}for(var d in u.prototype=Object.create(n.prototype),n)u[d]=n[d];u.prototype.getNodes=function(){return this.nodes},u.prototype.getEdges=function(){return this.edges},u.prototype.getGraphManager=function(){return this.graphManager},u.prototype.getParent=function(){return this.parent},u.prototype.getLeft=function(){return this.left},u.prototype.getRight=function(){return this.right},u.prototype.getTop=function(){return this.top},u.prototype.getBottom=function(){return this.bottom},u.prototype.isConnected=function(){return this.isConnected},u.prototype.add=function(t,e,i){if(null==e&&null==i){var n=t;if(null==this.graphManager)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(n)>-1)throw"Node already in graph!";return n.owner=this,this.getNodes().push(n),n}var r=t;if(!(this.getNodes().indexOf(e)>-1&&this.getNodes().indexOf(i)>-1))throw"Source or target not in graph!";if(e.owner!=i.owner||e.owner!=this)throw"Both owners must be this graph!";return e.owner!=i.owner?null:(r.source=e,r.target=i,r.isInterGraph=!1,this.getEdges().push(r),e.edges.push(r),i!=e&&i.edges.push(r),r)},u.prototype.remove=function(t){var e=t;if(t instanceof a){if(null==e)throw"Node is null!";if(null==e.owner||e.owner!=this)throw"Owner graph is invalid!";if(null==this.graphManager)throw"Owner graph manager is invalid!";for(var i=e.edges.slice(),n=i.length,r=0;r-1&&c>-1))throw"Source and/or target doesn't know this edge!";if(o.source.edges.splice(l,1),o.target!=o.source&&o.target.edges.splice(c,1),-1==(s=o.source.owner.getEdges().indexOf(o)))throw"Not in owner's edge list!";o.source.owner.getEdges().splice(s,1)}},u.prototype.updateLeftTop=function(){for(var t,e,i,n=r.MAX_VALUE,o=r.MAX_VALUE,s=this.getNodes(),a=s.length,h=0;h(t=l.getTop())&&(n=t),o>(e=l.getLeft())&&(o=e)}return n==r.MAX_VALUE?null:(i=null!=s[0].getParent().paddingLeft?s[0].getParent().paddingLeft:this.margin,this.left=o-i,this.top=n-i,new c(this.left,this.top))},u.prototype.updateBounds=function(t){for(var e,i,n,o,s,a=r.MAX_VALUE,h=-r.MAX_VALUE,c=r.MAX_VALUE,g=-r.MAX_VALUE,u=this.nodes,d=u.length,p=0;p(e=f.getLeft())&&(a=e),h<(i=f.getRight())&&(h=i),c>(n=f.getTop())&&(c=n),g<(o=f.getBottom())&&(g=o)}var y=new l(a,c,h-a,g-c);a==r.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),s=null!=u[0].getParent().paddingLeft?u[0].getParent().paddingLeft:this.margin,this.left=y.x-s,this.right=y.x+y.width+s,this.top=y.y-s,this.bottom=y.y+y.height+s},u.calculateBounds=function(t){for(var e,i,n,o,s=r.MAX_VALUE,a=-r.MAX_VALUE,h=r.MAX_VALUE,c=-r.MAX_VALUE,g=t.length,u=0;u(e=d.getLeft())&&(s=e),a<(i=d.getRight())&&(a=i),h>(n=d.getTop())&&(h=n),c<(o=d.getBottom())&&(c=o)}return new l(s,h,a-s,c-h)},u.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},u.prototype.getEstimatedSize=function(){if(this.estimatedSize==r.MIN_VALUE)throw"assert failed";return this.estimatedSize},u.prototype.calcEstimatedSize=function(){for(var t=0,e=this.nodes,i=e.length,n=0;n=this.nodes.length){var h=0;r.forEach((function(e){e.owner==t&&h++})),h==this.nodes.length&&(this.isConnected=!0)}}else this.isConnected=!0},t.exports=u},function(t,e,i){"use strict";var n,r=i(1);function o(t){n=i(5),this.layout=t,this.graphs=[],this.edges=[]}o.prototype.addRoot=function(){var t=this.layout.newGraph(),e=this.layout.newNode(null),i=this.add(t,e);return this.setRootGraph(i),this.rootGraph},o.prototype.add=function(t,e,i,n,r){if(null==i&&null==n&&null==r){if(null==t)throw"Graph is null!";if(null==e)throw"Parent node is null!";if(this.graphs.indexOf(t)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(t),null!=t.parent)throw"Already has a parent!";if(null!=e.child)throw"Already has a child!";return t.parent=e,e.child=t,t}r=i,i=t;var o=(n=e).getOwner(),s=r.getOwner();if(null==o||o.getGraphManager()!=this)throw"Source not in this graph mgr!";if(null==s||s.getGraphManager()!=this)throw"Target not in this graph mgr!";if(o==s)return i.isInterGraph=!1,o.add(i,n,r);if(i.isInterGraph=!0,i.source=n,i.target=r,this.edges.indexOf(i)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(i),null==i.source||null==i.target)throw"Edge source and/or target is null!";if(-1!=i.source.edges.indexOf(i)||-1!=i.target.edges.indexOf(i))throw"Edge already in source and/or target incidency list!";return i.source.edges.push(i),i.target.edges.push(i),i},o.prototype.remove=function(t){if(t instanceof n){var e=t;if(e.getGraphManager()!=this)throw"Graph not in this graph mgr";if(e!=this.rootGraph&&(null==e.parent||e.parent.graphManager!=this))throw"Invalid parent node!";for(var i,o=[],s=(o=o.concat(e.getEdges())).length,a=0;a=e.getRight()?i[0]+=Math.min(e.getX()-t.getX(),t.getRight()-e.getRight()):e.getX()<=t.getX()&&e.getRight()>=t.getRight()&&(i[0]+=Math.min(t.getX()-e.getX(),e.getRight()-t.getRight())),t.getY()<=e.getY()&&t.getBottom()>=e.getBottom()?i[1]+=Math.min(e.getY()-t.getY(),t.getBottom()-e.getBottom()):e.getY()<=t.getY()&&e.getBottom()>=t.getBottom()&&(i[1]+=Math.min(t.getY()-e.getY(),e.getBottom()-t.getBottom()));var o=Math.abs((e.getCenterY()-t.getCenterY())/(e.getCenterX()-t.getCenterX()));e.getCenterY()===t.getCenterY()&&e.getCenterX()===t.getCenterX()&&(o=1);var s=o*i[0],a=i[1]/o;i[0]s)return i[0]=n,i[1]=h,i[2]=o,i[3]=m,!1;if(ro)return i[0]=a,i[1]=r,i[2]=E,i[3]=s,!1;if(no?(i[0]=c,i[1]=g,L=!0):(i[0]=l,i[1]=h,L=!0):O===I&&(n>o?(i[0]=a,i[1]=h,L=!0):(i[0]=u,i[1]=g,L=!0)),-D===I?o>n?(i[2]=_,i[3]=m,T=!0):(i[2]=E,i[3]=y,T=!0):D===I&&(o>n?(i[2]=f,i[3]=y,T=!0):(i[2]=v,i[3]=m,T=!0)),L&&T)return!1;if(n>o?r>s?(w=this.getCardinalDirection(O,I,4),R=this.getCardinalDirection(D,I,2)):(w=this.getCardinalDirection(-O,I,3),R=this.getCardinalDirection(-D,I,1)):r>s?(w=this.getCardinalDirection(-O,I,1),R=this.getCardinalDirection(-D,I,3)):(w=this.getCardinalDirection(O,I,2),R=this.getCardinalDirection(D,I,4)),!L)switch(w){case 1:M=h,C=n+-p/I,i[0]=C,i[1]=M;break;case 2:C=u,M=r+d*I,i[0]=C,i[1]=M;break;case 3:M=g,C=n+p/I,i[0]=C,i[1]=M;break;case 4:C=c,M=r+-d*I,i[0]=C,i[1]=M}if(!T)switch(R){case 1:G=y,x=o+-A/I,i[2]=x,i[3]=G;break;case 2:x=v,G=s+N*I,i[2]=x,i[3]=G;break;case 3:G=m,x=o+A/I,i[2]=x,i[3]=G;break;case 4:x=_,G=s+-N*I,i[2]=x,i[3]=G}}return!1},r.getCardinalDirection=function(t,e,i){return t>e?i:1+i%4},r.getIntersection=function(t,e,i,r){if(null==r)return this.getIntersection2(t,e,i);var o,s,a,h,l,c,g,u=t.x,d=t.y,p=e.x,f=e.y,y=i.x,E=i.y,_=r.x,m=r.y;return 0==(g=(o=f-d)*(h=y-_)-(s=m-E)*(a=u-p))?null:new n((a*(c=_*E-y*m)-h*(l=p*d-u*f))/g,(s*l-o*c)/g)},r.angleOfVector=function(t,e,i,n){var r=void 0;return t!==i?(r=Math.atan((n-e)/(i-t)),i0?1:t<0?-1:0},n.floor=function(t){return t<0?Math.ceil(t):Math.floor(t)},n.ceil=function(t){return t<0?Math.floor(t):Math.ceil(t)},t.exports=n},function(t,e,i){"use strict";function n(){}n.MAX_VALUE=2147483647,n.MIN_VALUE=-2147483648,t.exports=n},function(t,e,i){"use strict";var n=function(){function t(t,e){for(var i=0;i0&&e;){for(a.push(l[0]);a.length>0&&e;){var c=a[0];a.splice(0,1),s.add(c);var g=c.getEdges();for(o=0;o-1&&l.splice(f,1)}s=new Set,h=new Map}else t=[]}return t},u.prototype.createDummyNodesForBendpoints=function(t){for(var e=[],i=t.source,n=this.graphManager.calcLowestCommonAncestor(t.source,t.target),r=0;r0){for(var r=this.edgeToDummyNodes.get(i),o=0;o=0&&e.splice(g,1),c.getNeighborsList().forEach((function(t){if(i.indexOf(t)<0){var e=n.get(t)-1;1==e&&h.push(t),n.set(t,e)}}))}i=i.concat(h),1!=e.length&&2!=e.length||(r=!0,o=e[0])}return o},u.prototype.setGraphManager=function(t){this.graphManager=t},t.exports=u},function(t,e,i){"use strict";function n(){}n.seed=1,n.x=0,n.nextDouble=function(){return n.x=1e4*Math.sin(n.seed++),n.x-Math.floor(n.x)},t.exports=n},function(t,e,i){"use strict";var n=i(4);function r(t,e){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}r.prototype.getWorldOrgX=function(){return this.lworldOrgX},r.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},r.prototype.getWorldOrgY=function(){return this.lworldOrgY},r.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},r.prototype.getWorldExtX=function(){return this.lworldExtX},r.prototype.setWorldExtX=function(t){this.lworldExtX=t},r.prototype.getWorldExtY=function(){return this.lworldExtY},r.prototype.setWorldExtY=function(t){this.lworldExtY=t},r.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},r.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},r.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},r.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},r.prototype.getDeviceExtX=function(){return this.ldeviceExtX},r.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},r.prototype.getDeviceExtY=function(){return this.ldeviceExtY},r.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},r.prototype.transformX=function(t){var e=0,i=this.lworldExtX;return 0!=i&&(e=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/i),e},r.prototype.transformY=function(t){var e=0,i=this.lworldExtY;return 0!=i&&(e=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/i),e},r.prototype.inverseTransformX=function(t){var e=0,i=this.ldeviceExtX;return 0!=i&&(e=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/i),e},r.prototype.inverseTransformY=function(t){var e=0,i=this.ldeviceExtY;return 0!=i&&(e=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/i),e},r.prototype.inverseTransformPoint=function(t){return new n(this.inverseTransformX(t.x),this.inverseTransformY(t.y))},t.exports=r},function(t,e,i){"use strict";var n=i(15),r=i(7),o=i(0),s=i(8),a=i(9);function h(){n.call(this),this.useSmartIdealEdgeLengthCalculation=r.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=r.DEFAULT_EDGE_LENGTH,this.springConstant=r.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=r.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=r.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=r.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=r.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=r.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*r.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=r.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=r.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=r.MAX_ITERATIONS}for(var l in h.prototype=Object.create(n.prototype),n)h[l]=n[l];h.prototype.initParameters=function(){n.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=r.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},h.prototype.calcIdealEdgeLengths=function(){for(var t,e,i,n,s,a,h=this.getGraphManager().getAllEdges(),l=0;lr.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*r.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-r.ADAPTATION_LOWER_NODE_LIMIT)/(r.ADAPTATION_UPPER_NODE_LIMIT-r.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-r.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=r.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>r.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(r.COOLING_ADAPTATION_FACTOR,1-(t-r.ADAPTATION_LOWER_NODE_LIMIT)/(r.ADAPTATION_UPPER_NODE_LIMIT-r.ADAPTATION_LOWER_NODE_LIMIT)*(1-r.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=r.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(5*this.getAllNodes().length,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},h.prototype.calcSpringForces=function(){for(var t,e=this.getAllEdges(),i=0;i0&&void 0!==arguments[0])||arguments[0],a=arguments.length>1&&void 0!==arguments[1]&&arguments[1],h=this.getAllNodes();if(this.useFRGridVariant)for(this.totalIterations%r.GRID_CALCULATION_CHECK_PERIOD==1&&s&&this.updateGrid(),o=new Set,t=0;t(h=e.getEstimatedSize()*this.gravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*r,t.gravitationForceY=-this.gravityConstant*o):(s>(h=e.getEstimatedSize()*this.compoundGravityRangeFactor)||a>h)&&(t.gravitationForceX=-this.gravityConstant*r*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*o*this.compoundGravityConstant)},h.prototype.isConverged=function(){var t,e=!1;return this.totalIterations>this.maxIterations/3&&(e=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement=a.length||l>=a[0].length))for(var c=0;ct}}]),t}();t.exports=o},function(t,e,i){"use strict";var n=function(){function t(t,e){for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:1,r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:-1,o=arguments.length>4&&void 0!==arguments[4]?arguments[4]:-1;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,t),this.sequence1=e,this.sequence2=i,this.match_score=n,this.mismatch_penalty=r,this.gap_penalty=o,this.iMax=e.length+1,this.jMax=i.length+1,this.grid=new Array(this.iMax);for(var s=0;s=0;i--){var n=this.listeners[i];n.event===t&&n.callback===e&&this.listeners.splice(i,1)}},r.emit=function(t,e){for(var i=0;i{"use strict";i.d(e,{diagram:()=>X});var n=i(86825),r=i(85039),o=i(61021),s=i(45567),a=i(90165),h=i(43457),l=i(20007),c=i(3219),g=i(78041),u=i(75263),d=function(){var t=(0,s.K2)((function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i}),"o"),e=[1,4],i=[1,13],n=[1,12],r=[1,15],o=[1,16],a=[1,20],h=[1,19],l=[6,7,8],c=[1,26],g=[1,24],u=[1,25],d=[6,7,11],p=[1,6,13,15,16,19,22],f=[1,33],y=[1,34],E=[1,6,7,11,13,15,16,19,22],_={trace:(0,s.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:(0,s.K2)((function(t,e,i,n,r,o,s){var a=o.length-1;switch(r){case 6:case 7:return n;case 8:n.getLogger().trace("Stop NL ");break;case 9:n.getLogger().trace("Stop EOF ");break;case 11:n.getLogger().trace("Stop NL2 ");break;case 12:n.getLogger().trace("Stop EOF2 ");break;case 15:n.getLogger().info("Node: ",o[a].id),n.addNode(o[a-1].length,o[a].id,o[a].descr,o[a].type);break;case 16:n.getLogger().trace("Icon: ",o[a]),n.decorateNode({icon:o[a]});break;case 17:case 21:n.decorateNode({class:o[a]});break;case 18:n.getLogger().trace("SPACELIST");break;case 19:n.getLogger().trace("Node: ",o[a].id),n.addNode(0,o[a].id,o[a].descr,o[a].type);break;case 20:n.decorateNode({icon:o[a]});break;case 25:n.getLogger().trace("node found ..",o[a-2]),this.$={id:o[a-1],descr:o[a-1],type:n.getType(o[a-2],o[a])};break;case 26:this.$={id:o[a],descr:o[a],type:n.nodeType.DEFAULT};break;case 27:n.getLogger().trace("node found ..",o[a-3]),this.$={id:o[a-3],descr:o[a-1],type:n.getType(o[a-2],o[a])}}}),"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:e},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:e},{6:i,7:[1,10],9:9,12:11,13:n,14:14,15:r,16:o,17:17,18:18,19:a,22:h},t(l,[2,3]),{1:[2,2]},t(l,[2,4]),t(l,[2,5]),{1:[2,6],6:i,12:21,13:n,14:14,15:r,16:o,17:17,18:18,19:a,22:h},{6:i,9:22,12:11,13:n,14:14,15:r,16:o,17:17,18:18,19:a,22:h},{6:c,7:g,10:23,11:u},t(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:a,22:h}),t(d,[2,18]),t(d,[2,19]),t(d,[2,20]),t(d,[2,21]),t(d,[2,23]),t(d,[2,24]),t(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:c,7:g,10:32,11:u},{1:[2,7],6:i,12:21,13:n,14:14,15:r,16:o,17:17,18:18,19:a,22:h},t(p,[2,14],{7:f,11:y}),t(E,[2,8]),t(E,[2,9]),t(E,[2,10]),t(d,[2,15]),t(d,[2,16]),t(d,[2,17]),{20:[1,35]},{21:[1,36]},t(p,[2,13],{7:f,11:y}),t(E,[2,11]),t(E,[2,12]),{21:[1,37]},t(d,[2,25]),t(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:(0,s.K2)((function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)}),"parseError"),parse:(0,s.K2)((function(t){var e=this,i=[0],n=[],r=[null],o=[],a=this.table,h="",l=0,c=0,g=0,u=o.slice.call(arguments,1),d=Object.create(this.lexer),p={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(p.yy[f]=this.yy[f]);d.setInput(t,p.yy),p.yy.lexer=d,p.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var y=d.yylloc;o.push(y);var E=d.options&&d.options.ranges;function _(){var t;return"number"!=typeof(t=n.pop()||d.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)((function(t){i.length=i.length-2*t,r.length=r.length-t,o.length=o.length-t}),"popStack"),(0,s.K2)(_,"lex");for(var m,v,N,A,L,T,O,D,I,w={};;){if(N=i[i.length-1],this.defaultActions[N]?A=this.defaultActions[N]:(null==m&&(m=_()),A=a[N]&&a[N][m]),void 0===A||!A.length||!A[0]){var R="";for(T in I=[],a[N])this.terminals_[T]&&T>2&&I.push("'"+this.terminals_[T]+"'");R=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+I.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(R,{text:d.match,token:this.terminals_[m]||m,line:d.yylineno,loc:y,expected:I})}if(A[0]instanceof Array&&A.length>1)throw new Error("Parse Error: multiple actions possible at state: "+N+", token: "+m);switch(A[0]){case 1:i.push(m),r.push(d.yytext),o.push(d.yylloc),i.push(A[1]),m=null,v?(m=v,v=null):(c=d.yyleng,h=d.yytext,l=d.yylineno,y=d.yylloc,g>0&&g--);break;case 2:if(O=this.productions_[A[1]][1],w.$=r[r.length-O],w._$={first_line:o[o.length-(O||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(O||1)].first_column,last_column:o[o.length-1].last_column},E&&(w._$.range=[o[o.length-(O||1)].range[0],o[o.length-1].range[1]]),void 0!==(L=this.performAction.apply(w,[h,c,l,p.yy,A[1],r,o].concat(u))))return L;O&&(i=i.slice(0,-1*O*2),r=r.slice(0,-1*O),o=o.slice(0,-1*O)),i.push(this.productions_[A[1]][0]),r.push(w.$),o.push(w._$),D=a[i[i.length-2]][i[i.length-1]],i.push(D);break;case 3:return!0}}return!0}),"parse")},m=function(){return{EOF:1,parseError:(0,s.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,s.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,s.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,s.K2)((function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,s.K2)((function(){return this._more=!0,this}),"more"),reject:(0,s.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,s.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,s.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,s.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,s.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,s.K2)((function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var o in r)this[o]=r[o];return!1}return!1}),"test_match"),next:(0,s.K2)((function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),o=0;oe[0].length)){if(e=i,n=o,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[o])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,s.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,s.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,s.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,s.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,s.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,s.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,s.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,s.K2)((function(t,e,i,n){switch(i){case 0:return t.getLogger().trace("Found comment",e.yytext),6;case 1:return 8;case 2:this.begin("CLASS");break;case 3:return this.popState(),16;case 4:case 23:case 26:this.popState();break;case 5:t.getLogger().trace("Begin icon"),this.begin("ICON");break;case 6:return t.getLogger().trace("SPACELINE"),6;case 7:return 7;case 8:return 15;case 9:t.getLogger().trace("end icon"),this.popState();break;case 10:return t.getLogger().trace("Exploding node"),this.begin("NODE"),19;case 11:return t.getLogger().trace("Cloud"),this.begin("NODE"),19;case 12:return t.getLogger().trace("Explosion Bang"),this.begin("NODE"),19;case 13:return t.getLogger().trace("Cloud Bang"),this.begin("NODE"),19;case 14:case 15:case 16:case 17:return this.begin("NODE"),19;case 18:return 13;case 19:return 22;case 20:return 11;case 21:this.begin("NSTR2");break;case 22:return"NODE_DESCR";case 24:t.getLogger().trace("Starting NSTR"),this.begin("NSTR");break;case 25:return t.getLogger().trace("description:",e.yytext),"NODE_DESCR";case 27:return this.popState(),t.getLogger().trace("node end ))"),"NODE_DEND";case 28:return this.popState(),t.getLogger().trace("node end )"),"NODE_DEND";case 29:return this.popState(),t.getLogger().trace("node end ...",e.yytext),"NODE_DEND";case 30:case 33:case 34:return this.popState(),t.getLogger().trace("node end (("),"NODE_DEND";case 31:case 32:return this.popState(),t.getLogger().trace("node end (-"),"NODE_DEND";case 35:case 36:return t.getLogger().trace("Long description:",e.yytext),20}}),"anonymous"),rules:[/^(?:\s*%%.*)/i,/^(?:mindmap\b)/i,/^(?::::)/i,/^(?:.+)/i,/^(?:\n)/i,/^(?:::icon\()/i,/^(?:[\s]+[\n])/i,/^(?:[\n]+)/i,/^(?:[^\)]+)/i,/^(?:\))/i,/^(?:-\))/i,/^(?:\(-)/i,/^(?:\)\))/i,/^(?:\))/i,/^(?:\(\()/i,/^(?:\{\{)/i,/^(?:\()/i,/^(?:\[)/i,/^(?:[\s]+)/i,/^(?:[^\(\[\n\)\{\}]+)/i,/^(?:$)/i,/^(?:["][`])/i,/^(?:[^`"]+)/i,/^(?:[`]["])/i,/^(?:["])/i,/^(?:[^"]+)/i,/^(?:["])/i,/^(?:[\)]\))/i,/^(?:[\)])/i,/^(?:[\]])/i,/^(?:\}\})/i,/^(?:\(-)/i,/^(?:-\))/i,/^(?:\(\()/i,/^(?:\()/i,/^(?:[^\)\]\(\}]+)/i,/^(?:.+(?!\(\())/i],conditions:{CLASS:{rules:[3,4],inclusive:!1},ICON:{rules:[8,9],inclusive:!1},NSTR2:{rules:[22,23],inclusive:!1},NSTR:{rules:[25,26],inclusive:!1},NODE:{rules:[21,24,27,28,29,30,31,32,33,34,35,36],inclusive:!1},INITIAL:{rules:[0,1,2,5,6,7,10,11,12,13,14,15,16,17,18,19,20],inclusive:!0}}}}();function v(){this.yy={}}return _.lexer=m,(0,s.K2)(v,"Parser"),v.prototype=_,_.Parser=v,new v}();d.parser=d;var p=d,f=[],y=0,E={},_=(0,s.K2)((()=>{f=[],y=0,E={}}),"clear"),m=(0,s.K2)((function(t){for(let e=f.length-1;e>=0;e--)if(f[e].levelf.length>0?f[0]:null),"getMindmap"),N=(0,s.K2)(((t,e,i,n)=>{s.Rm.info("addNode",t,e,i,n);const r=(0,s.D7)();let o=r.mindmap?.padding??s.UI.mindmap.padding;switch(n){case A.ROUNDED_RECT:case A.RECT:case A.HEXAGON:o*=2}const a={id:y++,nodeId:(0,s.jZ)(e,r),level:t,descr:(0,s.jZ)(i,r),type:n,children:[],width:r.mindmap?.maxNodeWidth??s.UI.mindmap.maxNodeWidth,padding:o},h=m(t);if(h)h.children.push(a),f.push(a);else{if(0!==f.length)throw new Error('There can be only one root. No parent could be found for ("'+a.descr+'")');f.push(a)}}),"addNode"),A={DEFAULT:0,NO_BORDER:0,ROUNDED_RECT:1,RECT:2,CIRCLE:3,CLOUD:4,BANG:5,HEXAGON:6},L={clear:_,addNode:N,getMindmap:v,nodeType:A,getType:(0,s.K2)(((t,e)=>{switch(s.Rm.debug("In get type",t,e),t){case"[":return A.RECT;case"(":return")"===e?A.ROUNDED_RECT:A.CLOUD;case"((":return A.CIRCLE;case")":return A.CLOUD;case"))":return A.BANG;case"{{":return A.HEXAGON;default:return A.DEFAULT}}),"getType"),setElementForId:(0,s.K2)(((t,e)=>{E[t]=e}),"setElementForId"),decorateNode:(0,s.K2)((t=>{if(!t)return;const e=(0,s.D7)(),i=f[f.length-1];t.icon&&(i.icon=(0,s.jZ)(t.icon,e)),t.class&&(i.class=(0,s.jZ)(t.class,e))}),"decorateNode"),type2Str:(0,s.K2)((t=>{switch(t){case A.DEFAULT:return"no-border";case A.RECT:return"rect";case A.ROUNDED_RECT:return"rounded-rect";case A.CIRCLE:return"circle";case A.CLOUD:return"cloud";case A.BANG:return"bang";case A.HEXAGON:return"hexgon";default:return"no-border"}}),"type2Str"),getLogger:(0,s.K2)((()=>s.Rm),"getLogger"),getElementById:(0,s.K2)((t=>E[t]),"getElementById")},T=(0,s.K2)((function(t,e,i,n){e.append("path").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("d",`M0 ${i.height-5} v${10-i.height} q0,-5 5,-5 h${i.width-10} q5,0 5,5 v${i.height-5} H0 Z`),e.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",i.height).attr("x2",i.width).attr("y2",i.height)}),"defaultBkg"),O=(0,s.K2)((function(t,e,i){e.append("rect").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("height",i.height).attr("width",i.width)}),"rectBkg"),D=(0,s.K2)((function(t,e,i){const n=i.width,r=i.height,o=.15*n,s=.25*n,a=.35*n,h=.2*n;e.append("path").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("d",`M0 0 a${o},${o} 0 0,1 ${.25*n},${-1*n*.1}\n a${a},${a} 1 0,1 ${.4*n},${-1*n*.1}\n a${s},${s} 1 0,1 ${.35*n},${1*n*.2}\n\n a${o},${o} 1 0,1 ${.15*n},${1*r*.35}\n a${h},${h} 1 0,1 ${-1*n*.15},${1*r*.65}\n\n a${s},${o} 1 0,1 ${-1*n*.25},${.15*n}\n a${a},${a} 1 0,1 ${-1*n*.5},0\n a${o},${o} 1 0,1 ${-1*n*.25},${-1*n*.15}\n\n a${o},${o} 1 0,1 ${-1*n*.1},${-1*r*.35}\n a${h},${h} 1 0,1 ${.1*n},${-1*r*.65}\n\n H0 V0 Z`)}),"cloudBkg"),I=(0,s.K2)((function(t,e,i){const n=i.width,r=i.height,o=.15*n;e.append("path").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("d",`M0 0 a${o},${o} 1 0,0 ${.25*n},${-1*r*.1}\n a${o},${o} 1 0,0 ${.25*n},0\n a${o},${o} 1 0,0 ${.25*n},0\n a${o},${o} 1 0,0 ${.25*n},${1*r*.1}\n\n a${o},${o} 1 0,0 ${.15*n},${1*r*.33}\n a${.8*o},${.8*o} 1 0,0 0,${1*r*.34}\n a${o},${o} 1 0,0 ${-1*n*.15},${1*r*.33}\n\n a${o},${o} 1 0,0 ${-1*n*.25},${.15*r}\n a${o},${o} 1 0,0 ${-1*n*.25},0\n a${o},${o} 1 0,0 ${-1*n*.25},0\n a${o},${o} 1 0,0 ${-1*n*.25},${-1*r*.15}\n\n a${o},${o} 1 0,0 ${-1*n*.1},${-1*r*.33}\n a${.8*o},${.8*o} 1 0,0 0,${-1*r*.34}\n a${o},${o} 1 0,0 ${.1*n},${-1*r*.33}\n\n H0 V0 Z`)}),"bangBkg"),w=(0,s.K2)((function(t,e,i){e.append("circle").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("r",i.width/2)}),"circleBkg");function R(t,e,i,n,r){return t.insert("polygon",":first-child").attr("points",n.map((function(t){return t.x+","+t.y})).join(" ")).attr("transform","translate("+(r.width-e)/2+", "+i+")")}(0,s.K2)(R,"insertPolygonShape");var C=(0,s.K2)((function(t,e,i){const n=i.height,r=n/4,o=i.width-i.padding+2*r;R(e,o,n,[{x:r,y:0},{x:o-r,y:0},{x:o,y:-n/2},{x:o-r,y:-n},{x:r,y:-n},{x:0,y:-n/2}],i)}),"hexagonBkg"),M=(0,s.K2)((function(t,e,i){e.append("rect").attr("id","node-"+i.id).attr("class","node-bkg node-"+t.type2Str(i.type)).attr("height",i.height).attr("rx",i.padding).attr("ry",i.padding).attr("width",i.width)}),"roundedRectBkg"),x=(0,s.K2)((async function(t,e,i,o,s){const a=s.htmlLabels,h=o%11,l=e.append("g");i.section=h;let c="section-"+h;h<0&&(c+=" section-root"),l.attr("class",(i.class?i.class+" ":"")+"mindmap-node "+c);const g=l.append("g"),u=l.append("g"),d=i.descr.replace(/()/g,"\n");await(0,n.GZ)(u,d,{useHtmlLabels:a,width:i.width,classes:"mindmap-node-label"},s),a||u.attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle");const p=u.node().getBBox(),[f]=(0,r.I5)(s.fontSize);if(i.height=p.height+1.1*f*.5+i.padding,i.width=p.width+2*i.padding,i.icon)if(i.type===t.nodeType.CIRCLE){i.height+=50,i.width+=50;l.append("foreignObject").attr("height","50px").attr("width",i.width).attr("style","text-align: center;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+h+" "+i.icon),u.attr("transform","translate("+i.width/2+", "+(i.height/2-1.5*i.padding)+")")}else{i.width+=50;const t=i.height;i.height=Math.max(t,60);const e=Math.abs(i.height-t);l.append("foreignObject").attr("width","60px").attr("height",i.height).attr("style","text-align: center;margin-top:"+e/2+"px;").append("div").attr("class","icon-container").append("i").attr("class","node-icon-"+h+" "+i.icon),u.attr("transform","translate("+(25+i.width/2)+", "+(e/2+i.padding/2)+")")}else if(a){const t=(i.width-p.width)/2,e=(i.height-p.height)/2;u.attr("transform","translate("+t+", "+e+")")}else{const t=i.width/2,e=i.padding/2;u.attr("transform","translate("+t+", "+e+")")}switch(i.type){case t.nodeType.DEFAULT:T(t,g,i,h);break;case t.nodeType.ROUNDED_RECT:M(t,g,i,h);break;case t.nodeType.RECT:O(t,g,i,h);break;case t.nodeType.CIRCLE:g.attr("transform","translate("+i.width/2+", "+ +i.height/2+")"),w(t,g,i,h);break;case t.nodeType.CLOUD:D(t,g,i,h);break;case t.nodeType.BANG:I(t,g,i,h);break;case t.nodeType.HEXAGON:C(t,g,i,h)}return t.setElementForId(i.id,l),i.height}),"drawNode"),G=(0,s.K2)((function(t,e){const i=t.getElementById(e.id),n=e.x||0,r=e.y||0;i.attr("transform","translate("+n+","+r+")")}),"positionNode");async function S(t,e,i,n,r){await x(t,e,i,n,r),i.children&&await Promise.all(i.children.map(((i,o)=>S(t,e,i,n<0?o:n,r))))}function b(t,e){e.edges().map(((e,i)=>{const n=e.data();if(e[0]._private.bodyBounds){const r=e[0]._private.rscratch;s.Rm.trace("Edge: ",i,n),t.insert("path").attr("d",`M ${r.startX},${r.startY} L ${r.midX},${r.midY} L${r.endX},${r.endY} `).attr("class","edge section-edge-"+n.section+" edge-depth-"+n.depth)}}))}function F(t,e,i,n){e.add({group:"nodes",data:{id:t.id.toString(),labelText:t.descr,height:t.height,width:t.width,level:n,nodeId:t.id,padding:t.padding,type:t.type},position:{x:t.x,y:t.y}}),t.children&&t.children.forEach((r=>{F(r,e,i,n+1),e.add({group:"edges",data:{id:`${t.id}_${r.id}`,source:t.id,target:r.id,depth:n,section:r.section}})}))}function P(t,e){return new Promise((i=>{const n=(0,l.Ltv)("body").append("div").attr("id","cy").attr("style","display:none"),r=(0,a.A)({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});n.remove(),F(t,r,e,0),r.nodes().forEach((function(t){t.layoutDimensions=()=>{const e=t.data();return{w:e.width,h:e.height}}})),r.layout({name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1}).run(),r.ready((t=>{s.Rm.info("Ready",t),i(r)}))}))}function U(t,e){e.nodes().map(((e,i)=>{const n=e.data();n.x=e.position().x,n.y=e.position().y,G(t,n);const r=t.getElementById(n.nodeId);s.Rm.info("Id:",i,"Position: (",e.position().x,", ",e.position().y,")",n),r.attr("transform",`translate(${e.position().x-n.width/2}, ${e.position().y-n.height/2})`),r.attr("attr",`apa-${i})`)}))}a.A.use(h),(0,s.K2)(S,"drawNodes"),(0,s.K2)(b,"drawEdges"),(0,s.K2)(F,"addNodes"),(0,s.K2)(P,"layoutMindmap"),(0,s.K2)(U,"positionNodes");var Y={draw:(0,s.K2)((async(t,e,i,n)=>{s.Rm.debug("Rendering mindmap diagram\n"+t);const r=n.db,a=r.getMindmap();if(!a)return;const h=(0,s.D7)();h.htmlLabels=!1;const l=(0,o.D)(e),c=l.append("g");c.attr("class","mindmap-edges");const g=l.append("g");g.attr("class","mindmap-nodes"),await S(r,g,a,-1,h);const u=await P(a,h);b(c,u),U(r,u),(0,s.ot)(void 0,l,h.mindmap?.padding??s.UI.mindmap.padding,h.mindmap?.useMaxWidth??s.UI.mindmap.useMaxWidth)}),"draw")},k=(0,s.K2)((t=>{let e="";for(let i=0;i`\n .edge {\n stroke-width: 3;\n }\n ${k(t)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/44b49990.29d0eb8e.js b/pr-preview/pr-976/assets/js/44b49990.29d0eb8e.js new file mode 100644 index 0000000000..84c5e88e16 --- /dev/null +++ b/pr-preview/pr-976/assets/js/44b49990.29d0eb8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9652],{40820:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-0.9/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/0.9/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/intro.md","tags":[],"version":"0.9","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/getting-started/install",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/45c98560.977c2d08.js b/pr-preview/pr-976/assets/js/45c98560.977c2d08.js new file mode 100644 index 0000000000..f1660ff72e --- /dev/null +++ b/pr-preview/pr-976/assets/js/45c98560.977c2d08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9361],{70687:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"components/index","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-0.6/components/index.md","sourceDirName":"components","slug":"/components/","permalink":"/contrast/pr-preview/pr-976/0.6/components/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/components/index.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.6/deployment"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.6/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},d=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(80013).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},80013:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-dd64f006e7d6b6facb9eb16f1af59d39.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/484.808d13de.js b/pr-preview/pr-976/assets/js/484.808d13de.js new file mode 100644 index 0000000000..722cbb0613 --- /dev/null +++ b/pr-preview/pr-976/assets/js/484.808d13de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[484],{50484:(t,e,a)=>{a.d(e,{diagram:()=>L});var i,n=a(69664),r=(a(79972),a(79740),a(6396),a(5081),a(34483),a(52294),a(62392),a(86825),a(85039)),d=a(45567),s=a(20007),o=a(62334),g=a(697),c={},p=(0,d.K2)(((t,e)=>{c[t]=e}),"set"),h=(0,d.K2)((t=>c[t]),"get"),l=(0,d.K2)((()=>Object.keys(c)),"keys"),x=(0,d.K2)((()=>l().length),"size"),D={get:h,set:p,keys:l,size:x},u=(0,d.K2)((t=>t.append("circle").attr("class","start-state").attr("r",(0,d.D7)().state.sizeUnit).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit)),"drawStartState"),f=(0,d.K2)((t=>t.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",(0,d.D7)().state.textHeight).attr("class","divider").attr("x2",2*(0,d.D7)().state.textHeight).attr("y1",0).attr("y2",0)),"drawDivider"),y=(0,d.K2)(((t,e)=>{const a=t.append("text").attr("x",2*(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.textHeight+2*(0,d.D7)().state.padding).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.id),i=a.node().getBBox();return t.insert("rect",":first-child").attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding).attr("width",i.width+2*(0,d.D7)().state.padding).attr("height",i.height+2*(0,d.D7)().state.padding).attr("rx",(0,d.D7)().state.radius),a}),"drawSimpleState"),w=(0,d.K2)(((t,e)=>{const a=(0,d.K2)((function(t,e,a){const i=t.append("tspan").attr("x",2*(0,d.D7)().state.padding).text(e);a||i.attr("dy",(0,d.D7)().state.textHeight)}),"addTspan"),i=t.append("text").attr("x",2*(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.textHeight+1.3*(0,d.D7)().state.padding).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.descriptions[0]).node().getBBox(),n=i.height,r=t.append("text").attr("x",(0,d.D7)().state.padding).attr("y",n+.4*(0,d.D7)().state.padding+(0,d.D7)().state.dividerMargin+(0,d.D7)().state.textHeight).attr("class","state-description");let s=!0,o=!0;e.descriptions.forEach((function(t){s||(a(r,t,o),o=!1),s=!1}));const g=t.append("line").attr("x1",(0,d.D7)().state.padding).attr("y1",(0,d.D7)().state.padding+n+(0,d.D7)().state.dividerMargin/2).attr("y2",(0,d.D7)().state.padding+n+(0,d.D7)().state.dividerMargin/2).attr("class","descr-divider"),c=r.node().getBBox(),p=Math.max(c.width,i.width);return g.attr("x2",p+3*(0,d.D7)().state.padding),t.insert("rect",":first-child").attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding).attr("width",p+2*(0,d.D7)().state.padding).attr("height",c.height+n+2*(0,d.D7)().state.padding).attr("rx",(0,d.D7)().state.radius),t}),"drawDescrState"),m=(0,d.K2)(((t,e,a)=>{const i=(0,d.D7)().state.padding,n=2*(0,d.D7)().state.padding,r=t.node().getBBox(),s=r.width,o=r.x,g=t.append("text").attr("x",0).attr("y",(0,d.D7)().state.titleShift).attr("font-size",(0,d.D7)().state.fontSize).attr("class","state-title").text(e.id),c=g.node().getBBox().width+n;let p,h=Math.max(c,s);h===s&&(h+=n);const l=t.node().getBBox();e.doc,p=o-i,c>s&&(p=(s-h)/2+i),Math.abs(o-l.x)s&&(p=o-(c-s)/2);const x=1-(0,d.D7)().state.textHeight;return t.insert("rect",":first-child").attr("x",p).attr("y",x).attr("class",a?"alt-composit":"composit").attr("width",h).attr("height",l.height+(0,d.D7)().state.textHeight+(0,d.D7)().state.titleShift+1).attr("rx","0"),g.attr("x",p+i),c<=s&&g.attr("x",o+(h-n)/2-c/2+i),t.insert("rect",":first-child").attr("x",p).attr("y",(0,d.D7)().state.titleShift-(0,d.D7)().state.textHeight-(0,d.D7)().state.padding).attr("width",h).attr("height",3*(0,d.D7)().state.textHeight).attr("rx",(0,d.D7)().state.radius),t.insert("rect",":first-child").attr("x",p).attr("y",(0,d.D7)().state.titleShift-(0,d.D7)().state.textHeight-(0,d.D7)().state.padding).attr("width",h).attr("height",l.height+3+2*(0,d.D7)().state.textHeight).attr("rx",(0,d.D7)().state.radius),t}),"addTitleAndBox"),b=(0,d.K2)((t=>(t.append("circle").attr("class","end-state-outer").attr("r",(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+(0,d.D7)().state.miniPadding),t.append("circle").attr("class","end-state-inner").attr("r",(0,d.D7)().state.sizeUnit).attr("cx",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+2).attr("cy",(0,d.D7)().state.padding+(0,d.D7)().state.sizeUnit+2))),"drawEndState"),B=(0,d.K2)(((t,e)=>{let a=(0,d.D7)().state.forkWidth,i=(0,d.D7)().state.forkHeight;if(e.parentId){let t=a;a=i,i=t}return t.append("rect").style("stroke","black").style("fill","black").attr("width",a).attr("height",i).attr("x",(0,d.D7)().state.padding).attr("y",(0,d.D7)().state.padding)}),"drawForkJoinState"),k=(0,d.K2)(((t,e,a,i)=>{let n=0;const r=i.append("text");r.style("text-anchor","start"),r.attr("class","noteText");let s=t.replace(/\r\n/g,"
");s=s.replace(/\n/g,"
");const o=s.split(d.Y2.lineBreakRegex);let g=1.25*(0,d.D7)().state.noteMargin;for(const c of o){const t=c.trim();if(t.length>0){const i=r.append("tspan");if(i.text(t),0===g){g+=i.node().getBBox().height}n+=g,i.attr("x",e+(0,d.D7)().state.noteMargin),i.attr("y",a+n+1.25*(0,d.D7)().state.noteMargin)}}return{textWidth:r.node().getBBox().width,textHeight:n}}),"_drawLongText"),S=(0,d.K2)(((t,e)=>{e.attr("class","state-note");const a=e.append("rect").attr("x",0).attr("y",(0,d.D7)().state.padding),i=e.append("g"),{textWidth:n,textHeight:r}=k(t,0,0,i);return a.attr("height",r+2*(0,d.D7)().state.noteMargin),a.attr("width",n+2*(0,d.D7)().state.noteMargin),a}),"drawNote"),N=(0,d.K2)((function(t,e){const a=e.id,i={id:a,label:e.id,width:0,height:0},n=t.append("g").attr("id",a).attr("class","stateGroup");"start"===e.type&&u(n),"end"===e.type&&b(n),"fork"!==e.type&&"join"!==e.type||B(n,e),"note"===e.type&&S(e.note.text,n),"divider"===e.type&&f(n),"default"===e.type&&0===e.descriptions.length&&y(n,e),"default"===e.type&&e.descriptions.length>0&&w(n,e);const r=n.node().getBBox();return i.width=r.width+2*(0,d.D7)().state.padding,i.height=r.height+2*(0,d.D7)().state.padding,D.set(a,i),i}),"drawState"),E=0,K=(0,d.K2)((function(t,e,a){const i=(0,d.K2)((function(t){switch(t){case n.iP.relationType.AGGREGATION:return"aggregation";case n.iP.relationType.EXTENSION:return"extension";case n.iP.relationType.COMPOSITION:return"composition";case n.iP.relationType.DEPENDENCY:return"dependency"}}),"getRelationType");e.points=e.points.filter((t=>!Number.isNaN(t.y)));const o=e.points,g=(0,s.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(s.qrM),c=t.append("path").attr("d",g(o)).attr("id","edge"+E).attr("class","transition");let p="";if((0,d.D7)().state.arrowMarkerAbsolute&&(p=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,p=p.replace(/\(/g,"\\("),p=p.replace(/\)/g,"\\)")),c.attr("marker-end","url("+p+"#"+i(n.iP.relationType.DEPENDENCY)+"End)"),void 0!==a.title){const i=t.append("g").attr("class","stateLabel"),{x:n,y:s}=r._K.calcLabelPosition(e.points),o=d.Y2.getRows(a.title);let g=0;const c=[];let p=0,h=0;for(let t=0;t<=o.length;t++){const e=i.append("text").attr("text-anchor","middle").text(o[t]).attr("x",n).attr("y",s+g),a=e.node().getBBox();if(p=Math.max(p,a.width),h=Math.min(h,a.x),d.Rm.info(a.x,n,s+g),0===g){const t=e.node().getBBox();g=t.height,d.Rm.info("Title height",g,s)}c.push(e)}let l=g*o.length;if(o.length>1){const t=(o.length-1)*g*.5;c.forEach(((e,a)=>e.attr("y",s+a*g-t))),l=g*o.length}const x=i.node().getBBox();i.insert("rect",":first-child").attr("class","box").attr("x",n-p/2-(0,d.D7)().state.padding/2).attr("y",s-l/2-(0,d.D7)().state.padding/2-3.5).attr("width",p+(0,d.D7)().state.padding).attr("height",l+(0,d.D7)().state.padding),d.Rm.info(x)}E++}),"drawEdge"),M={},v=(0,d.K2)((function(){}),"setConf"),R=(0,d.K2)((function(t){t.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}),"insertMarkers"),z=(0,d.K2)((function(t,e,a,n){i=(0,d.D7)().state;const r=(0,d.D7)().securityLevel;let o;"sandbox"===r&&(o=(0,s.Ltv)("#i"+e));const g="sandbox"===r?(0,s.Ltv)(o.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),c="sandbox"===r?o.nodes()[0].contentDocument:document;d.Rm.debug("Rendering diagram "+t);const p=g.select(`[id='${e}']`);R(p);const h=n.db.getRootDoc();T(h,p,void 0,!1,g,c,n);const l=i.padding,x=p.node().getBBox(),D=x.width+2*l,u=x.height+2*l,f=1.75*D;(0,d.a$)(p,u,f,i.useMaxWidth),p.attr("viewBox",`${x.x-i.padding} ${x.y-i.padding} `+D+" "+u)}),"draw"),H=(0,d.K2)((t=>t?t.length*i.fontSizeFactor:1),"getLabelWidth"),T=(0,d.K2)(((t,e,a,n,r,s,c)=>{const p=new g.T({compound:!0,multigraph:!0});let h,l=!0;for(h=0;h{const e=t.parentElement;let a=0,i=0;e&&(e.parentElement&&(a=e.parentElement.getBBox().width),i=parseInt(e.getAttribute("data-x-shift"),10),Number.isNaN(i)&&(i=0)),t.setAttribute("x1",0-i+8),t.setAttribute("x2",a-i-8)}))}else d.Rm.debug("No Node "+t+": "+JSON.stringify(p.node(t)))}));let w=y.getBBox();p.edges().forEach((function(t){void 0!==t&&void 0!==p.edge(t)&&(d.Rm.debug("Edge "+t.v+" -> "+t.w+": "+JSON.stringify(p.edge(t))),K(e,p.edge(t),p.edge(t).relation))})),w=y.getBBox();const b={id:a||"root",label:a||"root",width:0,height:0};return b.width=w.width+2*i.padding,b.height=w.height+2*i.padding,d.Rm.debug("Doc rendered",b,p),b}),"renderDoc"),P={setConf:v,draw:z},L={parser:n.Zk,db:n.iP,renderer:P,styles:n.tM,init:(0,d.K2)((t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute,n.iP.clear()}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/48f2f8ef.3afa4ead.js b/pr-preview/pr-976/assets/js/48f2f8ef.3afa4ead.js new file mode 100644 index 0000000000..20207152ad --- /dev/null +++ b/pr-preview/pr-976/assets/js/48f2f8ef.3afa4ead.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2020],{80401:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-1.1/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/architecture/attestation.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/components/service-mesh"},"next":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/architecture/secrets"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(69184).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(50981).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nThe hypervisor adds the hash of the policy to the attestation report via the HOSTDATA (on AMD SEV-SNP) or MRCONFIGID (Intel TDX) fields.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,r.jsx)(t.code,{children:"MRCONFIGID"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(26080).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP or Intel TDX to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},26080:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},50981:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},69184:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4ce6baab.ddbc3709.js b/pr-preview/pr-976/assets/js/4ce6baab.ddbc3709.js new file mode 100644 index 0000000000..4b29df9962 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4ce6baab.ddbc3709.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[455],{57718:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-1.0/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/1.0/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/about/telemetry.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/1.0/features-limitations"}}');var r=n(74848),o=n(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4cf3063f.ffa75230.js b/pr-preview/pr-976/assets/js/4cf3063f.ffa75230.js new file mode 100644 index 0000000000..63863a4537 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4cf3063f.ffa75230.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8364],{53881:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-1.0/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/1.0/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/basics/features.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/1.0/basics/security-benefits"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/install"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4eec459c.883ecb5e.js b/pr-preview/pr-976/assets/js/4eec459c.883ecb5e.js new file mode 100644 index 0000000000..e5313b4fb6 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4eec459c.883ecb5e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2639],{13204:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-1.1/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/components/runtime.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/components/overview"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"Virtual machine manager (VMM)",id:"virtual-machine-manager-vmm",level:3},{value:"Snapshotters",id:"snapshotters",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled/TDX-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(81553).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"virtual-machine-manager-vmm",children:"Virtual machine manager (VMM)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses a virtual machine monitor to create a confidential virtual machine for every pod.\nOn AKS, Contrast uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})}),".\nOn bare metal, Contrast uses ",(0,i.jsx)(n.a,{href:"https://www.qemu.org/",children:(0,i.jsx)(n.code,{children:"QEMU"})}),".\nThe appropriate files are installed on every node by the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"snapshotters",children:"Snapshotters"}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotters"]})," to provide container images to the pod-VM.\nEach snapshotter consists of a host component that pulls container images and a guest component used to mount/pull container images."]}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, Contrast uses the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})})," snapshotter to provide container images as block devices to the pod-VM.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["On bare metal, Contrast uses the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/nydus-snapshotter",children:(0,i.jsx)(n.code,{children:"nydus"})})," snapshotter to store metadata about the images. This metadata is communicated to the guest, so that it can pull the images itself."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," or ",(0,i.jsx)(n.code,{children:"QEMU"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file or separate firmware and kernel files for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},81553:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4f453872.072c6bcc.js b/pr-preview/pr-976/assets/js/4f453872.072c6bcc.js new file mode 100644 index 0000000000..0a2e514d72 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4f453872.072c6bcc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8170],{80786:(t,e,r)=>{r.r(e),r.d(e,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"architecture/attestation/pod-vm","title":"pod-vm","description":"","source":"@site/versioned_docs/version-0.5/architecture/attestation/pod-vm.md","sourceDirName":"architecture/attestation","slug":"/architecture/attestation/pod-vm","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/attestation/pod-vm.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Hardware","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware"},"next":{"title":"Runtime policies","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies"}}');var o=r(74848),s=r(28453);const a={},i=void 0,c={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},28453:(t,e,r)=>{r.d(e,{R:()=>a,x:()=>i});var n=r(96540);const o={},s=n.createContext(o);function a(t){const e=n.useContext(s);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:a(t.components),n.createElement(s.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/4fb24623.4962c99a.js b/pr-preview/pr-976/assets/js/4fb24623.4962c99a.js new file mode 100644 index 0000000000..628b666537 --- /dev/null +++ b/pr-preview/pr-976/assets/js/4fb24623.4962c99a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2550],{17364:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/docs/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/next/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/architecture/certificates.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/next/architecture/secrets"},"next":{"title":"Security considerations","permalink":"/contrast/pr-preview/pr-976/next/architecture/security-considerations"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(34102).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},34102:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/50474e10.3e18d095.js b/pr-preview/pr-976/assets/js/50474e10.3e18d095.js new file mode 100644 index 0000000000..2b481c6470 --- /dev/null +++ b/pr-preview/pr-976/assets/js/50474e10.3e18d095.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7061],{63297:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-0.6/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/basics/confidential-containers.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Contrast","permalink":"/contrast/pr-preview/pr-976/0.6/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/51513a8d.cdeb6e9c.js b/pr-preview/pr-976/assets/js/51513a8d.cdeb6e9c.js new file mode 100644 index 0000000000..426fe67f29 --- /dev/null +++ b/pr-preview/pr-976/assets/js/51513a8d.cdeb6e9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3859],{12241:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/versioned_docs/version-1.0/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/architecture/observability.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/certificates"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/1.0/features-limitations"}}');var s=r(74848),i=r(28453);const o={},c="Observability",a={},d=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function h(e){const t={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator exports gRPC metrics under the prefix ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_"}),".\nThese metrics are labeled with the gRPC service name and method name.\nMetrics of interest include ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handled_total"}),", which counts\nthe number of requests by return code, and\n",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handling_seconds_bucket"}),", which produces a histogram of",(0,s.jsx)(t.br,{}),"\n","request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["The gRPC service ",(0,s.jsx)(t.code,{children:"userapi.UserAPI"})," records metrics for the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"meshapi.MeshAPI"})," service records metrics for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"}),", which\ngets called by the ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures_total"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>c});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/54c6367b.8cc47335.js b/pr-preview/pr-976/assets/js/54c6367b.8cc47335.js new file mode 100644 index 0000000000..65009f6a4f --- /dev/null +++ b/pr-preview/pr-976/assets/js/54c6367b.8cc47335.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5999],{84608:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"components/service-mesh","title":"Service Mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-0.6/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/0.6/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/components/service-mesh.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.6/components/policies"},"next":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/"}}');var s=t(74848),r=t(28453);const o={},c="Service Mesh",a={},h=[{value:"Configuring the Proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"service-mesh",children:"Service Mesh"})}),"\n",(0,s.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The service mesh can be enabled on a per-pod basis by adding the ",(0,s.jsx)(n.code,{children:"service-mesh"}),"\ncontainer as a ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar container"}),".\nThe service mesh container first sets up ",(0,s.jsx)(n.code,{children:"iptables"}),"\nrules based on its configuration and then starts ",(0,s.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"}),"\nfor TLS origination and termination."]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the Proxy"}),"\n",(0,s.jsxs)(n.p,{children:["The service mesh container can be configured using the ",(0,s.jsx)(n.code,{children:"EDG_INGRESS_PROXY_CONFIG"}),"\nand ",(0,s.jsx)(n.code,{children:"EDG_EGRESS_PROXY_CONFIG"})," environment variables."]}),"\n",(0,s.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,s.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,s.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,s.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,s.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the environment variable ",(0,s.jsx)(n.code,{children:"EDG_INGRESS_PROXY_CONFIG"})," as\n",(0,s.jsx)(n.code,{children:"##false"}),". Separate multiple entries with ",(0,s.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the\ninformational-only field ",(0,s.jsx)(n.code,{children:""}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,s.jsx)(n.code,{children:"##true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,s.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n initContainers:\n - name: initializer\n image: "ghcr.io/edgelesssys/contrast/initializer@sha256:..."\n env:\n - name: COORDINATOR_HOST\n value: coordinator\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n - name: sidecar\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy@sha256:..."\n restartPolicy: Always\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n env:\n - name: EDG_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n securityContext:\n privileged: true\n capabilities:\n add:\n - NET_ADMIN\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n volumes:\n - name: tls-certs\n emptyDir: {}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,s.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,s.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,s.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,s.jsxs)(n.li,{children:["Set ",(0,s.jsx)(n.code,{children:"#:#:"}),"\nas ",(0,s.jsx)(n.code,{children:"EDG_EGRESS_PROXY_CONFIG"}),". Separate multiple entries with ",(0,s.jsx)(n.code,{children:"##"}),". Choose any\nstring identifying the service on the given port as ",(0,s.jsx)(n.code,{children:""}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,s.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are themselves part\nof the confidential deployment. One is reachable under ",(0,s.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,s.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n initContainers:\n - name: initializer\n image: "ghcr.io/edgelesssys/contrast/initializer@sha256:..."\n env:\n - name: COORDINATOR_HOST\n value: coordinator\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n - name: sidecar\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy@sha256:..."\n restartPolicy: Always\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n env:\n - name: EDG_EGRESS_PROXY_CONFIG\n value: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\n securityContext:\n privileged: true\n capabilities:\n add:\n - NET_ADMIN\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n volumes:\n - name: tls-certs\n emptyDir: {}\n'})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5606.5910c299.js b/pr-preview/pr-976/assets/js/5606.5910c299.js new file mode 100644 index 0000000000..4db921b0cd --- /dev/null +++ b/pr-preview/pr-976/assets/js/5606.5910c299.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5606],{65606:(s,r,a)=>{a.d(r,{diagram:()=>c});var e=a(96790),t=(a(79972),a(79740),a(6396),a(5081),a(34483),a(52294),a(62392),a(86825),a(85039),a(45567)),c={parser:e._$,db:e.z2,renderer:e.Lh,styles:e.tM,init:(0,t.K2)((s=>{s.class||(s.class={}),s.class.arrowMarkerAbsolute=s.arrowMarkerAbsolute,e.z2.clear()}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/567e04ee.8a836253.js b/pr-preview/pr-976/assets/js/567e04ee.8a836253.js new file mode 100644 index 0000000000..4e3ae13b11 --- /dev/null +++ b/pr-preview/pr-976/assets/js/567e04ee.8a836253.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6440],{71871:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-0.6/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/0.6/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/components/policies.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.6/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.6/components/service-mesh"}}');var s=n(74848),o=n(28453);const r={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5aa90309.c36a9a65.js b/pr-preview/pr-976/assets/js/5aa90309.c36a9a65.js new file mode 100644 index 0000000000..6e88dc4621 --- /dev/null +++ b/pr-preview/pr-976/assets/js/5aa90309.c36a9a65.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1381],{3189:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Attestation","slug":"/category/attestation","permalink":"/contrast/pr-preview/pr-976/0.5/category/attestation","sidebar":"docs","navigation":{"previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers"},"next":{"title":"Hardware","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5c6fa5d3.98b892e1.js b/pr-preview/pr-976/assets/js/5c6fa5d3.98b892e1.js new file mode 100644 index 0000000000..028ba419a7 --- /dev/null +++ b/pr-preview/pr-976/assets/js/5c6fa5d3.98b892e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[722],{30014:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-1.1/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/examples/emojivoto.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Bare metal setup","permalink":"/contrast/pr-preview/pr-976/getting-started/bare-metal"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/deployment"}}');var o=n(74848),s=n(28453);const a={},r="Confidential emoji voting",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Download the deployment files",id:"download-the-deployment-files",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Verifying the deployment as a user",id:"verifying-the-deployment-as-a-user",level:2},{value:"Verifying the Coordinator",id:"verifying-the-coordinator",level:3},{value:"Auditing the manifest history and artifacts",id:"auditing-the-manifest-history-and-artifacts",level:3},{value:"Connecting securely to the application",id:"connecting-securely-to-the-application",level:3},{value:"Updating the certificate SAN and the manifest (optional)",id:"updating-the-certificate-san-and-the-manifest-optional",level:2},{value:"Configuring the service SAN in the manifest",id:"configuring-the-service-san-in-the-manifest",level:3},{value:"Updating the manifest",id:"updating-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components},{TabItem:i,Tabs:a}=t;return i||p("TabItem",!0),a||p("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(2740).A+"",width:"1503",height:"732"})}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,o.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voter's perspective."]})}),"\n",(0,o.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,o.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,o.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,o.jsx)(t.code,{children:"voting"}),"). The ",(0,o.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,o.jsx)(t.p,{children:"Emojivoto can be seen as a lighthearted example of an app dealing with sensitive data.\nContrast protects emojivoto in two ways. First, it shields emojivoto as a whole from the infrastructure, for example, Azure.\nSecond, it can be configured to also prevent data access even from the administrator of the app. In the case of emojivoto, this gives assurance to users that their votes remain secret."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installed Contrast CLI"}),"\n",(0,o.jsxs)(t.li,{children:["A running Kubernetes cluster with support for confidential containers, either on ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/getting-started/cluster-setup",children:"AKS"})," or on ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/getting-started/bare-metal",children:"bare metal"}),"."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,o.jsx)(t.h3,{id:"download-the-deployment-files",children:"Download the deployment files"}),"\n",(0,o.jsx)(t.p,{children:"The emojivoto deployment files are part of the Contrast release. You can download them by running:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/download/v1.1.0/emojivoto-demo.yml --create-dirs --output-dir deployment\n"})}),"\n",(0,o.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/runtime",children:"custom Kubernetes RuntimeClass"}),",\nwhich needs to be installed to the cluster initially.\nThis consists of a ",(0,o.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,o.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-aks-clh-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-k3s-qemu-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,o.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-aks-clh-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-k3s-qemu-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,o.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,o.jsxs)(t.p,{children:["Run the ",(0,o.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,o.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp deployment/\n"})})}),(0,o.jsxs)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp deployment/\n"})}),(0,o.jsx)(t.admonition,{title:"Missing TCB values",type:"note",children:(0,o.jsxs)(t.p,{children:["On bare-metal SEV-SNP, ",(0,o.jsx)(t.code,{children:"contrast generate"})," is unable to fill in the ",(0,o.jsx)(t.code,{children:"MinimumTCB"})," values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,o.jsx)(t.code,{children:'{"BootloaderVersion":255,"TEEVersion":255,"SNPVersion":255,"MicrocodeVersion":255}'})," and observe the real values in the error messages in the following steps. This should only be done in a secure environment. Note that the values will differ between CPU models."]})})]}),(0,o.jsxs)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx deployment/\n"})}),(0,o.jsx)(t.admonition,{title:"Missing TCB values",type:"note",children:(0,o.jsxs)(t.p,{children:["On bare-metal TDX, ",(0,o.jsx)(t.code,{children:"contrast generate"})," is unable to fill in the ",(0,o.jsx)(t.code,{children:"MinimumTeeTcbSvn"})," and ",(0,o.jsx)(t.code,{children:"MrSeam"})," TCB values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,o.jsx)(t.code,{children:"ffffffffffffffffffffffffffffffff"})," and ",(0,o.jsx)(t.code,{children:"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"})," respectively and observe the real values in the error messages in the following steps. This should only be done in a secure environment."]})})]})]}),"\n",(0,o.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,o.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,o.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,o.jsx)(t.code,{children:"contrast-cc--"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,o.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,o.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,o.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,o.jsx)(t.p,{children:"The CLI will use the reference values from the manifest to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,o.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,o.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,o.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,o.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,o.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,o.jsx)(t.h2,{id:"verifying-the-deployment-as-a-user",children:"Verifying the deployment as a user"}),"\n",(0,o.jsx)(t.p,{children:"In different scenarios, users of an app may want to verify its security and identity before sharing data, for example, before casting a vote.\nWith Contrast, a user only needs a single remote-attestation step to verify the deployment - regardless of the size or scale of the deployment.\nContrast is designed such that, by verifying the Coordinator, the user transitively verifies those systems the Coordinator has already verified or will verify in the future.\nSuccessful verification of the Coordinator means that the user can be sure that the given manifest will be enforced."}),"\n",(0,o.jsx)(t.h3,{id:"verifying-the-coordinator",children:"Verifying the Coordinator"}),"\n",(0,o.jsx)(t.p,{children:"A user can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313" -m manifest.json\n'})}),"\n",(0,o.jsxs)(t.p,{children:["The CLI will verify the Coordinator via remote attestation using the reference values from a given manifest. This manifest needs\nto be communicated out of band to everyone wanting to verify the deployment, as the ",(0,o.jsx)(t.code,{children:"verify"})," command checks\nif the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,o.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,o.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"auditing-the-manifest-history-and-artifacts",children:"Auditing the manifest history and artifacts"}),"\n",(0,o.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,o.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,o.jsx)(t.h3,{id:"connecting-securely-to-the-application",children:"Connecting securely to the application"}),"\n",(0,o.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, the user can securely connect\nto the application using the Coordinator's ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,o.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Using ",(0,o.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,o.jsx)(t.h2,{id:"updating-the-certificate-san-and-the-manifest-optional",children:"Updating the certificate SAN and the manifest (optional)"}),"\n",(0,o.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,o.jsx)(t.h3,{id:"configuring-the-service-san-in-the-manifest",children:"Configuring the service SAN in the manifest"}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,o.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,o.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {\n "SANs": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n "WorkloadSecretID": "web"\n },\n'})}),"\n",(0,o.jsx)(t.h3,{id:"updating-the-manifest",children:"Updating the manifest"}),"\n",(0,o.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,o.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,o.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,o.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function p(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},2740:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5e95c892.c959e509.js b/pr-preview/pr-976/assets/js/5e95c892.c959e509.js new file mode 100644 index 0000000000..5df8913af3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/5e95c892.c959e509.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9647],{27591:(s,e,r)=>{r.r(e),r.d(e,{default:()=>d});r(96540);var c=r(34164),t=r(63523),a=r(74717),n=r(22831),u=r(83502),o=r(74848);function d(s){return(0,o.jsx)(t.e3,{className:(0,c.A)(a.G.wrapper.docsPages),children:(0,o.jsx)(u.A,{children:(0,n.v)(s.route.routes)})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5eab7755.b121b0e1.js b/pr-preview/pr-976/assets/js/5eab7755.b121b0e1.js new file mode 100644 index 0000000000..ed7a0421da --- /dev/null +++ b/pr-preview/pr-976/assets/js/5eab7755.b121b0e1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2772],{67766:(e,t,n)=>{n.d(t,{A:()=>k});var r=n(96540),s=n(34164),o=n(85246),i=n(57880),c=n(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const g={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(74848);function j(e){let{href:t,children:n}=e;return(0,x.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",g.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,x.jsxs)(j,{href:t,children:[(0,x.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",g.cardTitle),title:r,children:[n," ",r]}),o&&(0,x.jsx)("p",{className:(0,s.A)("text--truncate",g.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,x.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function b(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(y,{item:t});case"category":return(0,x.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,x.jsx)(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,x.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(b,{item:e})},t)))})}},80601:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"getting-started/index","title":"Getting started","description":"","source":"@site/versioned_docs/version-0.7/getting-started/index.md","sourceDirName":"getting-started","slug":"/getting-started/","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/getting-started/index.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.7/basics/features"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/install"}}');var s=n(74848),o=n(28453),i=n(67766);const c={},a="Getting started",l={},d=[];function u(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started",children:"Getting started"})}),"\n","\n",(0,s.jsx)(i.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5ecc20d3.560917b7.js b/pr-preview/pr-976/assets/js/5ecc20d3.560917b7.js new file mode 100644 index 0000000000..d31c0a0642 --- /dev/null +++ b/pr-preview/pr-976/assets/js/5ecc20d3.560917b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1954],{71417:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-1.1/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/architecture/certificates.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/architecture/secrets"},"next":{"title":"Security considerations","permalink":"/contrast/pr-preview/pr-976/architecture/security-considerations"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(95900).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},95900:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/5f998a2f.761e3939.js b/pr-preview/pr-976/assets/js/5f998a2f.761e3939.js new file mode 100644 index 0000000000..5a3687cab0 --- /dev/null +++ b/pr-preview/pr-976/assets/js/5f998a2f.761e3939.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[941],{67785:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-1.1/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/intro.md","tags":[],"version":"1.1","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/getting-started/install",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6009a9aa.e37420d5.js b/pr-preview/pr-976/assets/js/6009a9aa.e37420d5.js new file mode 100644 index 0000000000..0811490a64 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6009a9aa.e37420d5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8212],{80621:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-0.9/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/0.9/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/components/runtime.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/0.9/components/overview"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.9/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"cloud-hypervisor virtual machine manager (VMM)",id:"cloud-hypervisor-virtual-machine-manager-vmm",level:3},{value:"Tardev snapshotter",id:"tardev-snapshotter",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(60010).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"cloud-hypervisor-virtual-machine-manager-vmm",children:[(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," virtual machine manager (VMM)"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})})," to create a confidential virtual machine for every pod.\nThis requires the ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," binary to be installed on every node (responsibility of the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),")."]}),"\n",(0,i.jsx)(n.h3,{id:"tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"Tardev snapshotter"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses a special ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotter"]})," (",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})}),") to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},60010:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6100b425.8c972462.js b/pr-preview/pr-976/assets/js/6100b425.8c972462.js new file mode 100644 index 0000000000..0396916b5f --- /dev/null +++ b/pr-preview/pr-976/assets/js/6100b425.8c972462.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3129],{11768:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-0.9/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/0.9/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/basics/features.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.9/basics/security-benefits"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/install"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/640cb024.2e039806.js b/pr-preview/pr-976/assets/js/640cb024.2e039806.js new file mode 100644 index 0000000000..49d729c565 --- /dev/null +++ b/pr-preview/pr-976/assets/js/640cb024.2e039806.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7682],{8381:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/docs/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/next/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/basics/security-benefits.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/next/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/next/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(67976).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(82766).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},82766:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},67976:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/642ed902.37cf76bd.js b/pr-preview/pr-976/assets/js/642ed902.37cf76bd.js new file mode 100644 index 0000000000..5c8010a87b --- /dev/null +++ b/pr-preview/pr-976/assets/js/642ed902.37cf76bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5541],{48162:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/docs/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/next/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/architecture/attestation.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/next/components/service-mesh"},"next":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/next/architecture/secrets"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(82050).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(53787).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nThe hypervisor adds the hash of the policy to the attestation report via the HOSTDATA (on AMD SEV-SNP) or MRCONFIGID (Intel TDX) fields.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,r.jsx)(t.code,{children:"MRCONFIGID"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(43486).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP or Intel TDX to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},43486:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},53787:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},82050:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6452.9f5d0a8d.js b/pr-preview/pr-976/assets/js/6452.9f5d0a8d.js new file mode 100644 index 0000000000..40647f87a7 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6452.9f5d0a8d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6452],{6452:(c,e,s)=>{s.d(e,{createPacketServices:()=>t.$});var t=s(71609);s(19369)}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6478b99f.23cfdac2.js b/pr-preview/pr-976/assets/js/6478b99f.23cfdac2.js new file mode 100644 index 0000000000..43ef26a159 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6478b99f.23cfdac2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3506],{56468:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"known-limitations","title":"Known Limitations","description":"As Contrast is currently in an early development stage, it\'s built on several projects that are also under active development.","source":"@site/versioned_docs/version-0.6/known-limitations.md","sourceDirName":".","slug":"/known-limitations","permalink":"/contrast/pr-preview/pr-976/0.6/known-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/known-limitations.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/certificates"},"next":{"title":"About","permalink":"/contrast/pr-preview/pr-976/0.6/about/"}}');var s=t(74848),r=t(28453);const o={},a="Known Limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes Features",id:"kubernetes-features",level:2},{value:"Runtime Policies",id:"runtime-policies",level:2},{value:"Tooling Integration",id:"tooling-integration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"known-limitations",children:"Known Limitations"})}),"\n",(0,s.jsx)(n.p,{children:"As Contrast is currently in an early development stage, it's built on several projects that are also under active development.\nThis section outlines the most significant known limitations, providing stakeholders with clear expectations and understanding of the current state."}),"\n",(0,s.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Platform Support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes Features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Persistent Volumes"}),": Not currently supported within Confidential Containers."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Port-Forwarding"}),": This feature ",(0,s.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,s.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Resource Limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"runtime-policies",children:"Runtime Policies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,s.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,s.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,s.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,s.jsx)(n.h2,{id:"tooling-integration",children:"Tooling Integration"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"CLI Availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/64d58a39.1a4a9610.js b/pr-preview/pr-976/assets/js/64d58a39.1a4a9610.js new file mode 100644 index 0000000000..da22fc5acc --- /dev/null +++ b/pr-preview/pr-976/assets/js/64d58a39.1a4a9610.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2005],{4463:(t,e,r)=>{r.r(e),r.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>s,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/attestation/coordinator","title":"coordinator","description":"","source":"@site/versioned_docs/version-0.5/architecture/attestation/coordinator.md","sourceDirName":"architecture/attestation","slug":"/architecture/attestation/coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/attestation/coordinator.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Manifest","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest"},"next":{"title":"Certificates and Identities","permalink":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities"}}');var o=r(74848),i=r(28453);const s={},a=void 0,c={},d=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function p(t={}){const{wrapper:e}={...(0,i.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},28453:(t,e,r)=>{r.d(e,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(t){const e=n.useContext(i);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:s(t.components),n.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6507182a.417f4320.js b/pr-preview/pr-976/assets/js/6507182a.417f4320.js new file mode 100644 index 0000000000..21bf49a3a9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6507182a.417f4320.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9079],{90915:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"architecture/security-considerations","title":"Security Considerations","description":"Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits).","source":"@site/versioned_docs/version-1.1/architecture/security-considerations.md","sourceDirName":"architecture","slug":"/architecture/security-considerations","permalink":"/contrast/pr-preview/pr-976/architecture/security-considerations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/architecture/security-considerations.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/architecture/certificates"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/architecture/observability"}}');var r=n(74848),s=n(28453);const o={},a="Security Considerations",c={},d=[{value:"General recommendations",id:"general-recommendations",level:2},{value:"Authentication",id:"authentication",level:3},{value:"Encryption",id:"encryption",level:3},{value:"Contrast security guarantees",id:"contrast-security-guarantees",level:2},{value:"Limitations inherent to policy checking",id:"limitations-inherent-to-policy-checking",level:3},{value:"Logs",id:"logs",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-considerations",children:"Security Considerations"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast ensures application integrity and provides secure means of communication and bootstrapping (see ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/basics/security-benefits",children:"security benefits"}),").\nHowever, care must be taken when interacting with the outside of Contrast's confidential environment.\nThis page presents some tips for writing secure applications and outlines the trust boundaries app developers need to know."]}),"\n",(0,r.jsx)(t.h2,{id:"general-recommendations",children:"General recommendations"}),"\n",(0,r.jsx)(t.h3,{id:"authentication",children:"Authentication"}),"\n",(0,r.jsx)(t.p,{children:"The application receives credentials from the Contrast Coordinator during initialization.\nThis allows to authenticate towards peers and to verify credentials received from peers.\nThe application should use the certificate bundle to authenticate incoming requests and be wary of unauthenticated requests or requests with a different root of trust (for example the internet PKI)."}),"\n",(0,r.jsx)(t.p,{children:"The recommendation to authenticate not only applies to network traffic, but also to volumes, GPUs and other devices.\nGenerally speaking, all information provided by the world outside the confidential VM should be treated with due scepticism, especially if it's not authenticated.\nCommon cases where Kubernetes apps interact with external services include DNS, Kubernetes API clients and cloud storage endpoints."}),"\n",(0,r.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,r.jsx)(t.p,{children:"Any external persistence should be encrypted with an authenticated cipher.\nThis recommendation applies to block devices or filesystems mounted into the container, but also to cloud blob storage or external databases."}),"\n",(0,r.jsx)(t.h2,{id:"contrast-security-guarantees",children:"Contrast security guarantees"}),"\n",(0,r.jsx)(t.p,{children:"If an application authenticates with a certificate signed by the Contrast Mesh CA of a given manifest, Contrast provides the following guarantees:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"The container images used by the app are the images specified in the resource definitions."}),"\n",(0,r.jsx)(t.li,{children:"The command line arguments of containers are exactly the arguments specified in the resource definitions."}),"\n",(0,r.jsx)(t.li,{children:"All environment variables are either specified in resource definitions, in the container image manifest or in a settings file for the Contrast CLI."}),"\n",(0,r.jsx)(t.li,{children:"The containers run in a confidential VM that matches the reference values in the manifest."}),"\n",(0,r.jsx)(t.li,{children:"The containers' root filesystems are mounted in encrypted memory."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"limitations-inherent-to-policy-checking",children:"Limitations inherent to policy checking"}),"\n",(0,r.jsx)(t.p,{children:"Workload policies serve as workload identities.\nFrom the perspective of the Contrast Coordinator, all workloads that authenticate with the same policy are equal.\nThus, it's not possible to disambiguate, for example, pods spawned from a deployment or to limit the amount of certificates issued per policy."}),"\n",(0,r.jsxs)(t.p,{children:["Container image references from Kubernetes resource definitions are taken into account when generating the policy.\nA mutable reference may lead to policy failures or unverified image content, depending on the Contrast runtime.\nReliability and security can only be ensured with a full image reference, including digest.\nThe ",(0,r.jsxs)(t.a,{href:"https://docs.docker.com/reference/cli/docker/image/pull/#pull-an-image-by-digest-immutable-identifier",children:[(0,r.jsx)(t.code,{children:"docker pull"})," documentation"]})," explains pinned image references in detail."]}),"\n",(0,r.jsxs)(t.p,{children:["Policies can only verify what can be inferred at generation time.\nSome attributes of Kubernetes pods can't be predicted and thus can't be verified.\nParticularly the ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/downward-api/",children:"downward API"})," contains many fields that are dynamic or depend on the host environment, rendering it unsafe for process environment or arguments.\nThe same goes for ",(0,r.jsx)(t.code,{children:"ConfigMap"})," and ",(0,r.jsx)(t.code,{children:"Secret"})," resources, which can also be used to populate container fields.\nIf the application requires such external information, it should be injected as a mount point and carefully inspected before use."]}),"\n",(0,r.jsx)(t.p,{children:"Another type of dynamic content are persistent volumes.\nAny volumes mounted to the pod need to be scrutinized, and sensitive data must not be written to unprotected volumes.\nIdeally, a volume is mounted as a raw block device and authenticated encryption is added within the confidential container."}),"\n",(0,r.jsx)(t.h3,{id:"logs",children:"Logs"}),"\n",(0,r.jsx)(t.p,{children:"By default, container logs are visible to the host.\nSensitive information shouldn't be logged."}),"\n",(0,r.jsxs)(t.p,{children:["As of right now, hiding logs isn't natively supported.\nIf ",(0,r.jsx)(t.code,{children:"ReadStreamRequest"})," is denied in the policy, the Kata Agent stops reading the logs.\nThis causes the pipes used for standard out and standard error to fill up and potentially deadlock the container.\nIf absolutely required, standard out and standard error should be manually redirected to ",(0,r.jsx)(t.code,{children:"/dev/null"})," inside the container."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const r={},s=i.createContext(r);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6790.b101800c.js b/pr-preview/pr-976/assets/js/6790.b101800c.js new file mode 100644 index 0000000000..85b2f51ea9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6790.b101800c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6790],{96790:(t,e,s)=>{s.d(e,{Lh:()=>ot,_$:()=>l,tM:()=>at,z2:()=>ut});var n=s(79972),i=s(79740),u=s(85039),a=s(45567),r=s(20007),o=function(){var t=(0,a.K2)((function(t,e,s,n){for(s=s||{},n=t.length;n--;s[t[n]]=e);return s}),"o"),e=[1,18],s=[1,19],n=[1,20],i=[1,41],u=[1,42],r=[1,26],o=[1,24],l=[1,25],c=[1,32],h=[1,33],p=[1,34],d=[1,45],A=[1,35],y=[1,36],g=[1,37],m=[1,38],C=[1,27],f=[1,28],E=[1,29],b=[1,30],k=[1,31],T=[1,44],D=[1,46],F=[1,43],B=[1,47],_=[1,9],S=[1,8,9],N=[1,58],L=[1,59],$=[1,60],x=[1,61],O=[1,62],v=[1,63],I=[1,64],K=[1,8,9,41],w=[1,76],R=[1,8,9,12,13,22,39,41,44,66,67,68,69,70,71,72,77,79],P=[1,8,9,12,13,17,20,22,39,41,44,48,58,66,67,68,69,70,71,72,77,79,84,99,101,102],M=[13,58,84,99,101,102],G=[13,58,71,72,84,99,101,102],U=[13,58,66,67,68,69,70,84,99,101,102],Y=[1,98],z=[1,115],Q=[1,107],W=[1,113],X=[1,108],j=[1,109],V=[1,110],q=[1,111],H=[1,112],J=[1,114],Z=[22,58,59,80,84,85,86,87,88,89],tt=[1,8,9,39,41,44],et=[1,8,9,22],st=[1,143],nt=[1,8,9,59],it=[1,8,9,22,58,59,80,84,85,86,87,88,89],ut={trace:(0,a.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,DOT:17,className:18,classLiteralName:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,CLASS:46,ANNOTATION_START:47,ANNOTATION_END:48,MEMBER:49,SEPARATOR:50,relation:51,NOTE_FOR:52,noteText:53,NOTE:54,CLASSDEF:55,classList:56,stylesOpt:57,ALPHA:58,COMMA:59,direction_tb:60,direction_bt:61,direction_rl:62,direction_lr:63,relationType:64,lineType:65,AGGREGATION:66,EXTENSION:67,COMPOSITION:68,DEPENDENCY:69,LOLLIPOP:70,LINE:71,DOTTED_LINE:72,CALLBACK:73,LINK:74,LINK_TARGET:75,CLICK:76,CALLBACK_NAME:77,CALLBACK_ARGS:78,HREF:79,STYLE:80,CSSCLASS:81,style:82,styleComponent:83,NUM:84,COLON:85,UNIT:86,SPACE:87,BRKT:88,PCT:89,commentToken:90,textToken:91,graphCodeTokens:92,textNoTagsToken:93,TAGSTART:94,TAGEND:95,"==":96,"--":97,DEFAULT:98,MINUS:99,keywords:100,UNICODE_TEXT:101,BQUOTE_STR:102,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",17:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"CLASS",47:"ANNOTATION_START",48:"ANNOTATION_END",49:"MEMBER",50:"SEPARATOR",52:"NOTE_FOR",54:"NOTE",55:"CLASSDEF",58:"ALPHA",59:"COMMA",60:"direction_tb",61:"direction_bt",62:"direction_rl",63:"direction_lr",66:"AGGREGATION",67:"EXTENSION",68:"COMPOSITION",69:"DEPENDENCY",70:"LOLLIPOP",71:"LINE",72:"DOTTED_LINE",73:"CALLBACK",74:"LINK",75:"LINK_TARGET",76:"CLICK",77:"CALLBACK_NAME",78:"CALLBACK_ARGS",79:"HREF",80:"STYLE",81:"CSSCLASS",84:"NUM",85:"COLON",86:"UNIT",87:"SPACE",88:"BRKT",89:"PCT",92:"graphCodeTokens",94:"TAGSTART",95:"TAGEND",96:"==",97:"--",98:"DEFAULT",99:"MINUS",100:"keywords",101:"UNICODE_TEXT",102:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,3],[15,2],[18,1],[18,3],[18,1],[18,2],[18,2],[18,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,6],[43,2],[43,3],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[56,1],[56,3],[32,1],[32,1],[32,1],[32,1],[51,3],[51,2],[51,2],[51,1],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[57,1],[57,3],[82,1],[82,2],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[83,1],[90,1],[90,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[91,1],[93,1],[93,1],[93,1],[93,1],[16,1],[16,1],[16,1],[16,1],[19,1],[53,1]],performAction:(0,a.K2)((function(t,e,s,n,i,u,a){var r=u.length-1;switch(i){case 8:this.$=u[r-1];break;case 9:case 12:case 14:this.$=u[r];break;case 10:case 13:this.$=u[r-2]+"."+u[r];break;case 11:case 15:case 95:this.$=u[r-1]+u[r];break;case 16:case 17:this.$=u[r-1]+"~"+u[r]+"~";break;case 18:n.addRelation(u[r]);break;case 19:u[r-1].title=n.cleanupLabel(u[r]),n.addRelation(u[r-1]);break;case 30:this.$=u[r].trim(),n.setAccTitle(this.$);break;case 31:case 32:this.$=u[r].trim(),n.setAccDescription(this.$);break;case 33:n.addClassesToNamespace(u[r-3],u[r-1]);break;case 34:n.addClassesToNamespace(u[r-4],u[r-1]);break;case 35:this.$=u[r],n.addNamespace(u[r]);break;case 36:case 46:case 59:case 92:this.$=[u[r]];break;case 37:this.$=[u[r-1]];break;case 38:u[r].unshift(u[r-2]),this.$=u[r];break;case 40:n.setCssClass(u[r-2],u[r]);break;case 41:n.addMembers(u[r-3],u[r-1]);break;case 42:n.setCssClass(u[r-5],u[r-3]),n.addMembers(u[r-5],u[r-1]);break;case 43:this.$=u[r],n.addClass(u[r]);break;case 44:this.$=u[r-1],n.addClass(u[r-1]),n.setClassLabel(u[r-1],u[r]);break;case 45:n.addAnnotation(u[r],u[r-2]);break;case 47:u[r].push(u[r-1]),this.$=u[r];break;case 48:case 50:case 51:break;case 49:n.addMember(u[r-1],n.cleanupLabel(u[r]));break;case 52:this.$={id1:u[r-2],id2:u[r],relation:u[r-1],relationTitle1:"none",relationTitle2:"none"};break;case 53:this.$={id1:u[r-3],id2:u[r],relation:u[r-1],relationTitle1:u[r-2],relationTitle2:"none"};break;case 54:this.$={id1:u[r-3],id2:u[r],relation:u[r-2],relationTitle1:"none",relationTitle2:u[r-1]};break;case 55:this.$={id1:u[r-4],id2:u[r],relation:u[r-2],relationTitle1:u[r-3],relationTitle2:u[r-1]};break;case 56:n.addNote(u[r],u[r-1]);break;case 57:n.addNote(u[r]);break;case 58:this.$=u[r-2],n.defineClass(u[r-1],u[r]);break;case 60:this.$=u[r-2].concat([u[r]]);break;case 61:n.setDirection("TB");break;case 62:n.setDirection("BT");break;case 63:n.setDirection("RL");break;case 64:n.setDirection("LR");break;case 65:this.$={type1:u[r-2],type2:u[r],lineType:u[r-1]};break;case 66:this.$={type1:"none",type2:u[r],lineType:u[r-1]};break;case 67:this.$={type1:u[r-1],type2:"none",lineType:u[r]};break;case 68:this.$={type1:"none",type2:"none",lineType:u[r]};break;case 69:this.$=n.relationType.AGGREGATION;break;case 70:this.$=n.relationType.EXTENSION;break;case 71:this.$=n.relationType.COMPOSITION;break;case 72:this.$=n.relationType.DEPENDENCY;break;case 73:this.$=n.relationType.LOLLIPOP;break;case 74:this.$=n.lineType.LINE;break;case 75:this.$=n.lineType.DOTTED_LINE;break;case 76:case 82:this.$=u[r-2],n.setClickEvent(u[r-1],u[r]);break;case 77:case 83:this.$=u[r-3],n.setClickEvent(u[r-2],u[r-1]),n.setTooltip(u[r-2],u[r]);break;case 78:this.$=u[r-2],n.setLink(u[r-1],u[r]);break;case 79:this.$=u[r-3],n.setLink(u[r-2],u[r-1],u[r]);break;case 80:this.$=u[r-3],n.setLink(u[r-2],u[r-1]),n.setTooltip(u[r-2],u[r]);break;case 81:this.$=u[r-4],n.setLink(u[r-3],u[r-2],u[r]),n.setTooltip(u[r-3],u[r-1]);break;case 84:this.$=u[r-3],n.setClickEvent(u[r-2],u[r-1],u[r]);break;case 85:this.$=u[r-4],n.setClickEvent(u[r-3],u[r-2],u[r-1]),n.setTooltip(u[r-3],u[r]);break;case 86:this.$=u[r-3],n.setLink(u[r-2],u[r]);break;case 87:this.$=u[r-4],n.setLink(u[r-3],u[r-1],u[r]);break;case 88:this.$=u[r-4],n.setLink(u[r-3],u[r-1]),n.setTooltip(u[r-3],u[r]);break;case 89:this.$=u[r-5],n.setLink(u[r-4],u[r-2],u[r]),n.setTooltip(u[r-4],u[r-1]);break;case 90:this.$=u[r-2],n.setCssStyle(u[r-1],u[r]);break;case 91:n.setCssClass(u[r-1],u[r]);break;case 93:u[r-2].push(u[r]),this.$=u[r-2]}}),"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:s,37:n,38:22,42:i,43:23,46:u,47:r,49:o,50:l,52:c,54:h,55:p,58:d,60:A,61:y,62:g,63:m,73:C,74:f,76:E,80:b,81:k,84:T,99:D,101:F,102:B},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(_,[2,5],{8:[1,48]}),{8:[1,49]},t(S,[2,18],{22:[1,50]}),t(S,[2,20]),t(S,[2,21]),t(S,[2,22]),t(S,[2,23]),t(S,[2,24]),t(S,[2,25]),t(S,[2,26]),t(S,[2,27]),t(S,[2,28]),t(S,[2,29]),{34:[1,51]},{36:[1,52]},t(S,[2,32]),t(S,[2,48],{51:53,64:56,65:57,13:[1,54],22:[1,55],66:N,67:L,68:$,69:x,70:O,71:v,72:I}),{39:[1,65]},t(K,[2,39],{39:[1,67],44:[1,66]}),t(S,[2,50]),t(S,[2,51]),{16:68,58:d,84:T,99:D,101:F},{16:39,18:69,19:40,58:d,84:T,99:D,101:F,102:B},{16:39,18:70,19:40,58:d,84:T,99:D,101:F,102:B},{16:39,18:71,19:40,58:d,84:T,99:D,101:F,102:B},{58:[1,72]},{13:[1,73]},{16:39,18:74,19:40,58:d,84:T,99:D,101:F,102:B},{13:w,53:75},{56:77,58:[1,78]},t(S,[2,61]),t(S,[2,62]),t(S,[2,63]),t(S,[2,64]),t(R,[2,12],{16:39,19:40,18:80,17:[1,79],20:[1,81],58:d,84:T,99:D,101:F,102:B}),t(R,[2,14],{20:[1,82]}),{15:83,16:84,58:d,84:T,99:D,101:F},{16:39,18:85,19:40,58:d,84:T,99:D,101:F,102:B},t(P,[2,118]),t(P,[2,119]),t(P,[2,120]),t(P,[2,121]),t([1,8,9,12,13,20,22,39,41,44,66,67,68,69,70,71,72,77,79],[2,122]),t(_,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,18:21,38:22,43:23,16:39,19:40,5:86,33:e,35:s,37:n,42:i,46:u,47:r,49:o,50:l,52:c,54:h,55:p,58:d,60:A,61:y,62:g,63:m,73:C,74:f,76:E,80:b,81:k,84:T,99:D,101:F,102:B}),{5:87,10:5,16:39,18:21,19:40,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:e,35:s,37:n,38:22,42:i,43:23,46:u,47:r,49:o,50:l,52:c,54:h,55:p,58:d,60:A,61:y,62:g,63:m,73:C,74:f,76:E,80:b,81:k,84:T,99:D,101:F,102:B},t(S,[2,19]),t(S,[2,30]),t(S,[2,31]),{13:[1,89],16:39,18:88,19:40,58:d,84:T,99:D,101:F,102:B},{51:90,64:56,65:57,66:N,67:L,68:$,69:x,70:O,71:v,72:I},t(S,[2,49]),{65:91,71:v,72:I},t(M,[2,68],{64:92,66:N,67:L,68:$,69:x,70:O}),t(G,[2,69]),t(G,[2,70]),t(G,[2,71]),t(G,[2,72]),t(G,[2,73]),t(U,[2,74]),t(U,[2,75]),{8:[1,94],24:95,40:93,43:23,46:u},{16:96,58:d,84:T,99:D,101:F},{45:97,49:Y},{48:[1,99]},{13:[1,100]},{13:[1,101]},{77:[1,102],79:[1,103]},{22:z,57:104,58:Q,80:W,82:105,83:106,84:X,85:j,86:V,87:q,88:H,89:J},{58:[1,116]},{13:w,53:117},t(S,[2,57]),t(S,[2,123]),{22:z,57:118,58:Q,59:[1,119],80:W,82:105,83:106,84:X,85:j,86:V,87:q,88:H,89:J},t(Z,[2,59]),{16:39,18:120,19:40,58:d,84:T,99:D,101:F,102:B},t(R,[2,15]),t(R,[2,16]),t(R,[2,17]),{39:[2,35]},{15:122,16:84,17:[1,121],39:[2,9],58:d,84:T,99:D,101:F},t(tt,[2,43],{11:123,12:[1,124]}),t(_,[2,7]),{9:[1,125]},t(et,[2,52]),{16:39,18:126,19:40,58:d,84:T,99:D,101:F,102:B},{13:[1,128],16:39,18:127,19:40,58:d,84:T,99:D,101:F,102:B},t(M,[2,67],{64:129,66:N,67:L,68:$,69:x,70:O}),t(M,[2,66]),{41:[1,130]},{24:95,40:131,43:23,46:u},{8:[1,132],41:[2,36]},t(K,[2,40],{39:[1,133]}),{41:[1,134]},{41:[2,46],45:135,49:Y},{16:39,18:136,19:40,58:d,84:T,99:D,101:F,102:B},t(S,[2,76],{13:[1,137]}),t(S,[2,78],{13:[1,139],75:[1,138]}),t(S,[2,82],{13:[1,140],78:[1,141]}),{13:[1,142]},t(S,[2,90],{59:st}),t(nt,[2,92],{83:144,22:z,58:Q,80:W,84:X,85:j,86:V,87:q,88:H,89:J}),t(it,[2,94]),t(it,[2,96]),t(it,[2,97]),t(it,[2,98]),t(it,[2,99]),t(it,[2,100]),t(it,[2,101]),t(it,[2,102]),t(it,[2,103]),t(it,[2,104]),t(S,[2,91]),t(S,[2,56]),t(S,[2,58],{59:st}),{58:[1,145]},t(R,[2,13]),{15:146,16:84,58:d,84:T,99:D,101:F},{39:[2,11]},t(tt,[2,44]),{13:[1,147]},{1:[2,4]},t(et,[2,54]),t(et,[2,53]),{16:39,18:148,19:40,58:d,84:T,99:D,101:F,102:B},t(M,[2,65]),t(S,[2,33]),{41:[1,149]},{24:95,40:150,41:[2,37],43:23,46:u},{45:151,49:Y},t(K,[2,41]),{41:[2,47]},t(S,[2,45]),t(S,[2,77]),t(S,[2,79]),t(S,[2,80],{75:[1,152]}),t(S,[2,83]),t(S,[2,84],{13:[1,153]}),t(S,[2,86],{13:[1,155],75:[1,154]}),{22:z,58:Q,80:W,82:156,83:106,84:X,85:j,86:V,87:q,88:H,89:J},t(it,[2,95]),t(Z,[2,60]),{39:[2,10]},{14:[1,157]},t(et,[2,55]),t(S,[2,34]),{41:[2,38]},{41:[1,158]},t(S,[2,81]),t(S,[2,85]),t(S,[2,87]),t(S,[2,88],{75:[1,159]}),t(nt,[2,93],{83:144,22:z,58:Q,80:W,84:X,85:j,86:V,87:q,88:H,89:J}),t(tt,[2,8]),t(K,[2,42]),t(S,[2,89])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],83:[2,35],122:[2,11],125:[2,4],135:[2,47],146:[2,10],150:[2,38]},parseError:(0,a.K2)((function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)}),"parseError"),parse:(0,a.K2)((function(t){var e=this,s=[0],n=[],i=[null],u=[],r=this.table,o="",l=0,c=0,h=0,p=u.slice.call(arguments,1),d=Object.create(this.lexer),A={yy:{}};for(var y in this.yy)Object.prototype.hasOwnProperty.call(this.yy,y)&&(A.yy[y]=this.yy[y]);d.setInput(t,A.yy),A.yy.lexer=d,A.yy.parser=this,void 0===d.yylloc&&(d.yylloc={});var g=d.yylloc;u.push(g);var m=d.options&&d.options.ranges;function C(){var t;return"number"!=typeof(t=n.pop()||d.lex()||1)&&(t instanceof Array&&(t=(n=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof A.yy.parseError?this.parseError=A.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,a.K2)((function(t){s.length=s.length-2*t,i.length=i.length-t,u.length=u.length-t}),"popStack"),(0,a.K2)(C,"lex");for(var f,E,b,k,T,D,F,B,_,S={};;){if(b=s[s.length-1],this.defaultActions[b]?k=this.defaultActions[b]:(null==f&&(f=C()),k=r[b]&&r[b][f]),void 0===k||!k.length||!k[0]){var N="";for(D in _=[],r[b])this.terminals_[D]&&D>2&&_.push("'"+this.terminals_[D]+"'");N=d.showPosition?"Parse error on line "+(l+1)+":\n"+d.showPosition()+"\nExpecting "+_.join(", ")+", got '"+(this.terminals_[f]||f)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==f?"end of input":"'"+(this.terminals_[f]||f)+"'"),this.parseError(N,{text:d.match,token:this.terminals_[f]||f,line:d.yylineno,loc:g,expected:_})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+f);switch(k[0]){case 1:s.push(f),i.push(d.yytext),u.push(d.yylloc),s.push(k[1]),f=null,E?(f=E,E=null):(c=d.yyleng,o=d.yytext,l=d.yylineno,g=d.yylloc,h>0&&h--);break;case 2:if(F=this.productions_[k[1]][1],S.$=i[i.length-F],S._$={first_line:u[u.length-(F||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(F||1)].first_column,last_column:u[u.length-1].last_column},m&&(S._$.range=[u[u.length-(F||1)].range[0],u[u.length-1].range[1]]),void 0!==(T=this.performAction.apply(S,[o,c,l,A.yy,k[1],i,u].concat(p))))return T;F&&(s=s.slice(0,-1*F*2),i=i.slice(0,-1*F),u=u.slice(0,-1*F)),s.push(this.productions_[k[1]][0]),i.push(S.$),u.push(S._$),B=r[s[s.length-2]][s[s.length-1]],s.push(B);break;case 3:return!0}}return!0}),"parse")},at=function(){return{EOF:1,parseError:(0,a.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,a.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,a.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,a.K2)((function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===n.length?this.yylloc.first_column:0)+n[n.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,a.K2)((function(){return this._more=!0,this}),"more"),reject:(0,a.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,a.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,a.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,a.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,a.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,a.K2)((function(t,e){var s,n,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var u in i)this[u]=i[u];return!1}return!1}),"test_match"),next:(0,a.K2)((function(){if(this.done)return this.EOF;var t,e,s,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),u=0;ue[0].length)){if(e=s,n=u,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,i[u])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,a.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,a.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,a.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,a.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,a.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,a.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,a.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{},performAction:(0,a.K2)((function(t,e,s,n){switch(s){case 0:return 60;case 1:return 61;case 2:return 62;case 3:return 63;case 4:case 5:case 14:case 31:case 36:case 40:case 47:break;case 6:return this.begin("acc_title"),33;case 7:return this.popState(),"acc_title_value";case 8:return this.begin("acc_descr"),35;case 9:return this.popState(),"acc_descr_value";case 10:this.begin("acc_descr_multiline");break;case 11:case 19:case 22:case 24:case 58:case 61:this.popState();break;case 12:return"acc_descr_multiline_value";case 13:case 35:return 8;case 15:case 16:return 7;case 17:case 37:case 45:return"EDGE_STATE";case 18:this.begin("callback_name");break;case 20:this.popState(),this.begin("callback_args");break;case 21:return 77;case 23:return 78;case 25:return"STR";case 26:this.begin("string");break;case 27:return 80;case 28:return 55;case 29:return this.begin("namespace"),42;case 30:case 39:return this.popState(),8;case 32:return this.begin("namespace-body"),39;case 33:case 43:return this.popState(),41;case 34:case 44:return"EOF_IN_STRUCT";case 38:return this.begin("class"),46;case 41:return this.popState(),this.popState(),41;case 42:return this.begin("class-body"),39;case 46:return"OPEN_IN_STRUCT";case 48:return"MEMBER";case 49:return 81;case 50:return 73;case 51:return 74;case 52:return 76;case 53:return 52;case 54:return 54;case 55:return 47;case 56:return 48;case 57:return 79;case 59:return"GENERICTYPE";case 60:this.begin("generic");break;case 62:return"BQUOTE_STR";case 63:this.begin("bqstring");break;case 64:case 65:case 66:case 67:return 75;case 68:case 69:return 67;case 70:case 71:return 69;case 72:return 68;case 73:return 66;case 74:return 70;case 75:return 71;case 76:return 72;case 77:return 22;case 78:return 44;case 79:return 99;case 80:return 17;case 81:return"PLUS";case 82:return 85;case 83:return 59;case 84:case 85:return 88;case 86:return 89;case 87:case 88:return"EQUALS";case 89:return 58;case 90:return 12;case 91:return 14;case 92:return"PUNCTUATION";case 93:return 84;case 94:return 101;case 95:case 96:return 87;case 97:return 9}}),"anonymous"),rules:[/^(?:.*direction\s+TB[^\n]*)/,/^(?:.*direction\s+BT[^\n]*)/,/^(?:.*direction\s+RL[^\n]*)/,/^(?:.*direction\s+LR[^\n]*)/,/^(?:%%(?!\{)*[^\n]*(\r?\n?)+)/,/^(?:%%[^\n]*(\r?\n)*)/,/^(?:accTitle\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*:\s*)/,/^(?:(?!\n||)*[^\n]*)/,/^(?:accDescr\s*\{\s*)/,/^(?:[\}])/,/^(?:[^\}]*)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:classDiagram-v2\b)/,/^(?:classDiagram\b)/,/^(?:\[\*\])/,/^(?:call[\s]+)/,/^(?:\([\s]*\))/,/^(?:\()/,/^(?:[^(]*)/,/^(?:\))/,/^(?:[^)]*)/,/^(?:["])/,/^(?:[^"]*)/,/^(?:["])/,/^(?:style\b)/,/^(?:classDef\b)/,/^(?:namespace\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:\[\*\])/,/^(?:class\b)/,/^(?:\s*(\r?\n)+)/,/^(?:\s+)/,/^(?:[}])/,/^(?:[{])/,/^(?:[}])/,/^(?:$)/,/^(?:\[\*\])/,/^(?:[{])/,/^(?:[\n])/,/^(?:[^{}\n]*)/,/^(?:cssClass\b)/,/^(?:callback\b)/,/^(?:link\b)/,/^(?:click\b)/,/^(?:note for\b)/,/^(?:note\b)/,/^(?:<<)/,/^(?:>>)/,/^(?:href\b)/,/^(?:[~])/,/^(?:[^~]*)/,/^(?:~)/,/^(?:[`])/,/^(?:[^`]+)/,/^(?:[`])/,/^(?:_self\b)/,/^(?:_blank\b)/,/^(?:_parent\b)/,/^(?:_top\b)/,/^(?:\s*<\|)/,/^(?:\s*\|>)/,/^(?:\s*>)/,/^(?:\s*<)/,/^(?:\s*\*)/,/^(?:\s*o\b)/,/^(?:\s*\(\))/,/^(?:--)/,/^(?:\.\.)/,/^(?::{1}[^:\n;]+)/,/^(?::{3})/,/^(?:-)/,/^(?:\.)/,/^(?:\+)/,/^(?::)/,/^(?:,)/,/^(?:#)/,/^(?:#)/,/^(?:%)/,/^(?:=)/,/^(?:=)/,/^(?:\w+)/,/^(?:\[)/,/^(?:\])/,/^(?:[!"#$%&'*+,-.`?\\/])/,/^(?:[0-9]+)/,/^(?:[\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]|[\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]|[\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]|[\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA]|[\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE]|[\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA]|[\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0]|[\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977]|[\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2]|[\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A]|[\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39]|[\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8]|[\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C]|[\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C]|[\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99]|[\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0]|[\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D]|[\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3]|[\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10]|[\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1]|[\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81]|[\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3]|[\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6]|[\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A]|[\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081]|[\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D]|[\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0]|[\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310]|[\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C]|[\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u1700-\u170C\u170E-\u1711]|[\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7]|[\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C]|[\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16]|[\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF]|[\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC]|[\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D]|[\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D]|[\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3]|[\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F]|[\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128]|[\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184]|[\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3]|[\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6]|[\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE]|[\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C]|[\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D]|[\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC]|[\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B]|[\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788]|[\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805]|[\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB]|[\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28]|[\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5]|[\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4]|[\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E]|[\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D]|[\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36]|[\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D]|[\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC]|[\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF]|[\uFFD2-\uFFD7\uFFDA-\uFFDC])/,/^(?:\s)/,/^(?:\s)/,/^(?:$)/],conditions:{"namespace-body":{rules:[26,33,34,35,36,37,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},namespace:{rules:[26,29,30,31,32,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},"class-body":{rules:[26,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},class:{rules:[26,39,40,41,42,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr_multiline:{rules:[11,12,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_descr:{rules:[9,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},acc_title:{rules:[7,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_args:{rules:[22,23,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},callback_name:{rules:[19,20,21,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},href:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},struct:{rules:[26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},generic:{rules:[26,49,50,51,52,53,54,55,56,57,58,59,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},bqstring:{rules:[26,49,50,51,52,53,54,55,56,57,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},string:{rules:[24,25,26,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,86,87,88,89,90,91,92,93,94,95,97],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,8,10,13,14,15,16,17,18,26,27,28,29,38,49,50,51,52,53,54,55,56,57,60,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],inclusive:!0}}}}();function rt(){this.yy={}}return ut.lexer=at,(0,a.K2)(rt,"Parser"),rt.prototype=ut,ut.Parser=rt,new rt}();o.parser=o;var l=o,c=["#","+","~","-",""],h=class{static{(0,a.K2)(this,"ClassMember")}constructor(t,e){this.memberType=e,this.visibility="",this.classifier="",this.text="";const s=(0,a.jZ)(t,(0,a.D7)());this.parseMember(s)}getDisplayDetails(){let t=this.visibility+(0,a.QO)(this.id);"method"===this.memberType&&(t+=`(${(0,a.QO)(this.parameters.trim())})`,this.returnType&&(t+=" : "+(0,a.QO)(this.returnType))),t=t.trim();return{displayText:t,cssStyle:this.parseClassifier()}}parseMember(t){let e="";if("method"===this.memberType){const s=/([#+~-])?(.+)\((.*)\)([\s$*])?(.*)([$*])?/.exec(t);if(s){const t=s[1]?s[1].trim():"";if(c.includes(t)&&(this.visibility=t),this.id=s[2],this.parameters=s[3]?s[3].trim():"",e=s[4]?s[4].trim():"",this.returnType=s[5]?s[5].trim():"",""===e){const t=this.returnType.substring(this.returnType.length-1);/[$*]/.exec(t)&&(e=t,this.returnType=this.returnType.substring(0,this.returnType.length-1))}}}else{const s=t.length,n=t.substring(0,1),i=t.substring(s-1);c.includes(n)&&(this.visibility=n),/[$*]/.exec(i)&&(e=i),this.id=t.substring(""===this.visibility?0:1,""===e?s:s-1)}this.classifier=e,this.id=this.id.startsWith(" ")?" "+this.id.trim():this.id.trim();const s=`${this.visibility?"\\"+this.visibility:""}${(0,a.QO)(this.id)}${"method"===this.memberType?`(${(0,a.QO)(this.parameters)})${this.returnType?" : "+(0,a.QO)(this.returnType):""}`:""}`;this.text=s.replaceAll("<","<").replaceAll(">",">"),this.text.startsWith("\\<")&&(this.text=this.text.replace("\\<","~"))}parseClassifier(){switch(this.classifier){case"*":return"font-style:italic;";case"$":return"text-decoration:underline;";default:return""}}},p="classId-",d=[],A=new Map,y=new Map,g=[],m=[],C=0,f=new Map,E=0,b=[],k=(0,a.K2)((t=>a.Y2.sanitizeText(t,(0,a.D7)())),"sanitizeText"),T=(0,a.K2)((function(t){const e=a.Y2.sanitizeText(t,(0,a.D7)());let s="",n=e;if(e.indexOf("~")>0){const t=e.split("~");n=k(t[0]),s=k(t[1])}return{className:n,type:s}}),"splitClassNameAndType"),D=(0,a.K2)((function(t,e){const s=a.Y2.sanitizeText(t,(0,a.D7)());e&&(e=k(e));const{className:n}=T(s);A.get(n).label=e,A.get(n).text=`${e}${A.get(n).type?`<${A.get(n).type}>`:""}`}),"setClassLabel"),F=(0,a.K2)((function(t){const e=a.Y2.sanitizeText(t,(0,a.D7)()),{className:s,type:n}=T(e);if(A.has(s))return;const i=a.Y2.sanitizeText(s,(0,a.D7)());A.set(i,{id:i,type:n,label:i,text:`${i}${n?`<${n}>`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:p+i+"-"+C}),C++}),"addClass"),B=(0,a.K2)((function(t,e){const s={id:`interface${m.length}`,label:t,classId:e};m.push(s)}),"addInterface"),_=(0,a.K2)((function(t){const e=a.Y2.sanitizeText(t,(0,a.D7)());if(A.has(e))return A.get(e).domId;throw new Error("Class not found: "+e)}),"lookUpDomId"),S=(0,a.K2)((function(){d=[],A=new Map,g=[],m=[],(b=[]).push(j),f=new Map,E=0,V="TB",(0,a.IU)()}),"clear"),N=(0,a.K2)((function(t){return A.get(t)}),"getClass"),L=(0,a.K2)((function(){return A}),"getClasses"),$=(0,a.K2)((function(){return d}),"getRelations"),x=(0,a.K2)((function(){return g}),"getNotes"),O=(0,a.K2)((function(t){a.Rm.debug("Adding relation: "+JSON.stringify(t));const e=[X.LOLLIPOP,X.AGGREGATION,X.COMPOSITION,X.DEPENDENCY,X.EXTENSION];t.relation.type1!==X.LOLLIPOP||e.includes(t.relation.type2)?t.relation.type2!==X.LOLLIPOP||e.includes(t.relation.type1)?(F(t.id1),F(t.id2)):(F(t.id1),B(t.id2,t.id1),t.id2="interface"+(m.length-1)):(F(t.id2),B(t.id1,t.id2),t.id1="interface"+(m.length-1)),t.id1=T(t.id1).className,t.id2=T(t.id2).className,t.relationTitle1=a.Y2.sanitizeText(t.relationTitle1.trim(),(0,a.D7)()),t.relationTitle2=a.Y2.sanitizeText(t.relationTitle2.trim(),(0,a.D7)()),d.push(t)}),"addRelation"),v=(0,a.K2)((function(t,e){const s=T(t).className;A.get(s).annotations.push(e)}),"addAnnotation"),I=(0,a.K2)((function(t,e){F(t);const s=T(t).className,n=A.get(s);if("string"==typeof e){const t=e.trim();t.startsWith("<<")&&t.endsWith(">>")?n.annotations.push(k(t.substring(2,t.length-2))):t.indexOf(")")>0?n.methods.push(new h(t,"method")):t&&n.members.push(new h(t,"attribute"))}}),"addMember"),K=(0,a.K2)((function(t,e){Array.isArray(e)&&(e.reverse(),e.forEach((e=>I(t,e))))}),"addMembers"),w=(0,a.K2)((function(t,e){const s={id:`note${g.length}`,class:e,text:t};g.push(s)}),"addNote"),R=(0,a.K2)((function(t){return t.startsWith(":")&&(t=t.substring(1)),k(t.trim())}),"cleanupLabel"),P=(0,a.K2)((function(t,e){t.split(",").forEach((function(t){let s=t;/\d/.exec(t[0])&&(s=p+s);const n=A.get(s);n&&(n.cssClasses+=" "+e)}))}),"setCssClass"),M=(0,a.K2)((function(t,e){for(const s of t){let t=y.get(s);void 0===t&&(t={id:s,styles:[],textStyles:[]},y.set(s,t)),e&&e.forEach((function(e){if(/color/.exec(e)){const s=e.replace("fill","bgFill");t.textStyles.push(s)}t.styles.push(e)})),A.forEach((t=>{t.cssClasses.includes(s)&&t.styles.push(...e.flatMap((t=>t.split(","))))}))}}),"defineClass"),G=(0,a.K2)((function(t,e){t.split(",").forEach((function(t){void 0!==e&&(A.get(t).tooltip=k(e))}))}),"setTooltip"),U=(0,a.K2)((function(t,e){return e&&f.has(e)?f.get(e).classes.get(t).tooltip:A.get(t).tooltip}),"getTooltip"),Y=(0,a.K2)((function(t,e,s){const n=(0,a.D7)();t.split(",").forEach((function(t){let i=t;/\d/.exec(t[0])&&(i=p+i);const a=A.get(i);a&&(a.link=u._K.formatUrl(e,n),"sandbox"===n.securityLevel?a.linkTarget="_top":a.linkTarget="string"==typeof s?k(s):"_blank")})),P(t,"clickable")}),"setLink"),z=(0,a.K2)((function(t,e,s){t.split(",").forEach((function(t){Q(t,e,s),A.get(t).haveCallback=!0})),P(t,"clickable")}),"setClickEvent"),Q=(0,a.K2)((function(t,e,s){const n=a.Y2.sanitizeText(t,(0,a.D7)());if("loose"!==(0,a.D7)().securityLevel)return;if(void 0===e)return;const i=n;if(A.has(i)){const t=_(i);let n=[];if("string"==typeof s){n=s.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let t=0;t")),t.classed("hover",!0)})).on("mouseout",(function(){e.transition().duration(500).style("opacity",0);(0,r.Ltv)(this).classed("hover",!1)}))}),"setupToolTips");b.push(j);var V="TB",q=(0,a.K2)((()=>V),"getDirection"),H=(0,a.K2)((t=>{V=t}),"setDirection"),J=(0,a.K2)((function(t){f.has(t)||(f.set(t,{id:t,classes:new Map,children:{},domId:p+t+"-"+E}),E++)}),"addNamespace"),Z=(0,a.K2)((function(t){return f.get(t)}),"getNamespace"),tt=(0,a.K2)((function(){return f}),"getNamespaces"),et=(0,a.K2)((function(t,e){if(f.has(t))for(const s of e){const{className:e}=T(s);A.get(e).parent=t,f.get(t).classes.set(e,A.get(e))}}),"addClassesToNamespace"),st=(0,a.K2)((function(t,e){const s=A.get(t);if(e&&s)for(const n of e)n.includes(",")?s.styles.push(...n.split(",")):s.styles.push(n)}),"setCssStyle");function nt(t){let e;switch(t){case 0:e="aggregation";break;case 1:e="extension";break;case 2:e="composition";break;case 3:e="dependency";break;case 4:e="lollipop";break;default:e="none"}return e}(0,a.K2)(nt,"getArrowMarker");var it=(0,a.K2)((()=>{const t=[],e=[],s=(0,a.D7)();for(const i of f.keys()){const e=f.get(i);if(e){const n={id:e.id,label:e.id,isGroup:!0,padding:s.class.padding??16,shape:"rect",cssStyles:["fill: none","stroke: black"],look:s.look};t.push(n)}}for(const i of A.keys()){const e=A.get(i);if(e){const n=e;n.parentId=e.parent,n.look=s.look,t.push(n)}}let n=0;for(const i of g){n++;const u={id:i.id,label:i.text,isGroup:!1,shape:"note",padding:s.class.padding??6,cssStyles:["text-align: left","white-space: nowrap",`fill: ${s.themeVariables.noteBkgColor}`,`stroke: ${s.themeVariables.noteBorderColor}`],look:s.look};t.push(u);const a=A.get(i.class)?.id??"";if(a){const t={id:`edgeNote${n}`,start:i.id,end:a,type:"normal",thickness:"normal",classes:"relation",arrowTypeStart:"none",arrowTypeEnd:"none",arrowheadStyle:"",labelStyle:[""],style:["fill: none"],pattern:"dotted",look:s.look};e.push(t)}}for(const i of m){const e={id:i.id,label:i.label,isGroup:!1,shape:"rect",cssStyles:["opacity: 0;"],look:s.look};t.push(e)}n=0;for(const i of d){n++;const t={id:(0,u.rY)(i.id1,i.id2,{prefix:"id",counter:n}),start:i.id1,end:i.id2,type:"normal",label:i.title,labelpos:"c",thickness:"normal",classes:"relation",arrowTypeStart:nt(i.relation.type1),arrowTypeEnd:nt(i.relation.type2),startLabelRight:"none"===i.relationTitle1?"":i.relationTitle1,endLabelLeft:"none"===i.relationTitle2?"":i.relationTitle2,arrowheadStyle:"",labelStyle:["display: inline-block"],style:i.style||"",pattern:1==i.relation.lineType?"dashed":"solid",look:s.look};e.push(t)}return{nodes:t,edges:e,other:{},config:s,direction:q()}}),"getData"),ut={setAccTitle:a.SV,getAccTitle:a.iN,getAccDescription:a.m7,setAccDescription:a.EI,getConfig:(0,a.K2)((()=>(0,a.D7)().class),"getConfig"),addClass:F,bindFunctions:W,clear:S,getClass:N,getClasses:L,getNotes:x,addAnnotation:v,addNote:w,getRelations:$,addRelation:O,getDirection:q,setDirection:H,addMember:I,addMembers:K,cleanupLabel:R,lineType:{LINE:0,DOTTED_LINE:1},relationType:X,setClickEvent:z,setCssClass:P,defineClass:M,setLink:Y,getTooltip:U,setTooltip:G,lookUpDomId:_,setDiagramTitle:a.ke,getDiagramTitle:a.ab,setClassLabel:D,addNamespace:J,addClassesToNamespace:et,getNamespace:Z,getNamespaces:tt,setCssStyle:st,getData:it},at=(0,a.K2)((t=>`g.classGroup text {\n fill: ${t.nodeBorder||t.classText};\n stroke: none;\n font-family: ${t.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${t.classText};\n}\n.edgeLabel .label rect {\n fill: ${t.mainBkg};\n}\n.label text {\n fill: ${t.classText};\n}\n\n.labelBkg {\n background: ${t.mainBkg};\n}\n.edgeLabel .label span {\n background: ${t.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${t.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${t.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${t.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${t.lineColor} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${t.mainBkg} !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n line-height: initial;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`),"getStyles"),rt=(0,a.K2)(((t,e="TB")=>{if(!t.doc)return e;let s=e;for(const n of t.doc)"dir"===n.stmt&&(s=n.value);return s}),"getDir"),ot={getClasses:(0,a.K2)((function(t,e){return e.db.getClasses()}),"getClasses"),draw:(0,a.K2)((async function(t,e,s,r){a.Rm.info("REF0:"),a.Rm.info("Drawing class diagram (v3)",e);const{securityLevel:o,state:l,layout:c}=(0,a.D7)(),h=r.db.getData(),p=(0,n.A)(e,o);h.type=r.type,h.layoutAlgorithm=(0,i.q7)(c),h.nodeSpacing=l?.nodeSpacing||50,h.rankSpacing=l?.rankSpacing||50,h.markers=["aggregation","extension","composition","dependency","lollipop"],h.diagramId=e,await(0,i.XX)(h,p);u._K.insertTitle(p,"classDiagramTitleText",l?.titleTopMargin??25,r.db.getDiagramTitle()),(0,n.P)(p,8,"classDiagram",l?.useMaxWidth??!0)}),"draw"),getDir:rt}},79972:(t,e,s)=>{s.d(e,{A:()=>u,P:()=>a});var n=s(45567),i=s(20007),u=(0,n.K2)(((t,e)=>{let s;"sandbox"===e&&(s=(0,i.Ltv)("#i"+t));return("sandbox"===e?(0,i.Ltv)(s.nodes()[0].contentDocument.body):(0,i.Ltv)("body")).select(`[id="${t}"]`)}),"getDiagramElement"),a=(0,n.K2)(((t,e,s,i)=>{t.attr("class",s);const{width:u,height:a,x:l,y:c}=r(t,e);(0,n.a$)(t,a,u,i);const h=o(l,c,u,a,e);t.attr("viewBox",h),n.Rm.debug(`viewBox configured: ${h} with padding: ${e}`)}),"setupViewPortForSVG"),r=(0,n.K2)(((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}}),"calculateDimensionsWithPadding"),o=(0,n.K2)(((t,e,s,n,i)=>`${t-i} ${e-i} ${s} ${n}`),"createViewBox")}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/68be920e.9f8df8ee.js b/pr-preview/pr-976/assets/js/68be920e.9f8df8ee.js new file mode 100644 index 0000000000..3d18cd3061 --- /dev/null +++ b/pr-preview/pr-976/assets/js/68be920e.9f8df8ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7294],{11080:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/versioned_docs/version-1.1/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/architecture/observability.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Security considerations","permalink":"/contrast/pr-preview/pr-976/architecture/security-considerations"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/features-limitations"}}');var s=r(74848),i=r(28453);const o={},c="Observability",a={},d=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function h(e){const t={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator exports gRPC metrics under the prefix ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_"}),".\nThese metrics are labeled with the gRPC service name and method name.\nMetrics of interest include ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handled_total"}),", which counts\nthe number of requests by return code, and\n",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handling_seconds_bucket"}),", which produces a histogram of",(0,s.jsx)(t.br,{}),"\n","request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["The gRPC service ",(0,s.jsx)(t.code,{children:"userapi.UserAPI"})," records metrics for the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"meshapi.MeshAPI"})," service records metrics for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"}),", which\ngets called by the ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/overview#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures_total"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>c});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6903d0da.aed38602.js b/pr-preview/pr-976/assets/js/6903d0da.aed38602.js new file mode 100644 index 0000000000..c0bcb814a5 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6903d0da.aed38602.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[594],{43980:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product Features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-0.5/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/0.5/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/basics/features.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits"},"next":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/"}}');var r=n(74848),i=n(28453);const o={},a="Product Features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product Features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes Compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight Installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"../architecture",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote Attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service Mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6912.4cd2abc1.js b/pr-preview/pr-976/assets/js/6912.4cd2abc1.js new file mode 100644 index 0000000000..3885cc8eb1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6912.4cd2abc1.js @@ -0,0 +1,2 @@ +/*! For license information please see 6912.4cd2abc1.js.LICENSE.txt */ +(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6912],{69119:(t,e)=>{"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.BLANK_URL=e.relativeFirstCharacters=e.whitespaceEscapeCharsRegex=e.urlSchemeRegex=e.ctrlCharactersRegex=e.htmlCtrlEntityRegex=e.htmlEntitiesRegex=e.invalidProtocolRegex=void 0,e.invalidProtocolRegex=/^([^\w]*)(javascript|data|vbscript)/im,e.htmlEntitiesRegex=/&#(\w+)(^\w|;)?/g,e.htmlCtrlEntityRegex=/&(newline|tab);/gi,e.ctrlCharactersRegex=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,e.urlSchemeRegex=/^.+(:|:)/gim,e.whitespaceEscapeCharsRegex=/(\\|%5[cC])((%(6[eE]|72|74))|[nrt])/g,e.relativeFirstCharacters=[".","/"],e.BLANK_URL="about:blank"},16750:(t,e,r)=>{"use strict";e.J=void 0;var n=r(69119);function i(t){try{return decodeURIComponent(t)}catch(e){return t}}e.J=function(t){if(!t)return n.BLANK_URL;var e,r,a=i(t.trim());do{e=(a=i(a=(r=a,r.replace(n.ctrlCharactersRegex,"").replace(n.htmlEntitiesRegex,(function(t,e){return String.fromCharCode(e)}))).replace(n.htmlCtrlEntityRegex,"").replace(n.ctrlCharactersRegex,"").replace(n.whitespaceEscapeCharsRegex,"").trim())).match(n.ctrlCharactersRegex)||a.match(n.htmlEntitiesRegex)||a.match(n.htmlCtrlEntityRegex)||a.match(n.whitespaceEscapeCharsRegex)}while(e&&e.length>0);var o=a;if(!o)return n.BLANK_URL;if(function(t){return n.relativeFirstCharacters.indexOf(t[0])>-1}(o))return o;var s=o.trimStart(),l=s.match(n.urlSchemeRegex);if(!l)return o;var c=l[0].toLowerCase().trim();if(n.invalidProtocolRegex.test(c))return n.BLANK_URL;var h=s.replace(/\\/g,"/");if("mailto:"===c||c.includes("://"))return h;if("http:"===c||"https:"===c){if(!function(t){return URL.canParse(t)}(h))return n.BLANK_URL;var u=new URL(h);return u.protocol=u.protocol.toLowerCase(),u.hostname=u.hostname.toLowerCase(),u.toString()}return h}},37235:(t,e,r)=>{"use strict";r.d(e,{A:()=>B});var n=r(96540),i=r(74848);function a(t){const{mdxAdmonitionTitle:e,rest:r}=function(t){const e=n.Children.toArray(t),r=e.find((t=>n.isValidElement(t)&&"mdxAdmonitionTitle"===t.type)),a=e.filter((t=>t!==r)),o=r?.props.children;return{mdxAdmonitionTitle:o,rest:a.length>0?(0,i.jsx)(i.Fragment,{children:a}):null}}(t.children),a=t.title??e;return{...t,...a&&{title:a},children:r}}var o=r(34164),s=r(32032),l=r(74717);const c={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function h(t){let{type:e,className:r,children:n}=t;return(0,i.jsx)("div",{className:(0,o.A)(l.G.common.admonition,l.G.common.admonitionType(e),c.admonition,r),children:n})}function u(t){let{icon:e,title:r}=t;return(0,i.jsxs)("div",{className:c.admonitionHeading,children:[(0,i.jsx)("span",{className:c.admonitionIcon,children:e}),r]})}function d(t){let{children:e}=t;return e?(0,i.jsx)("div",{className:c.admonitionContent,children:e}):null}function p(t){const{type:e,icon:r,title:n,children:a,className:o}=t;return(0,i.jsxs)(h,{type:e,className:o,children:[n||r?(0,i.jsx)(u,{title:n,icon:r}):null,(0,i.jsx)(d,{children:a})]})}function f(t){return(0,i.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const g={icon:(0,i.jsx)(f,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function m(t){return(0,i.jsx)(p,{...g,...t,className:(0,o.A)("alert alert--secondary",t.className),children:t.children})}function y(t){return(0,i.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const x={icon:(0,i.jsx)(y,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function b(t){return(0,i.jsx)(p,{...x,...t,className:(0,o.A)("alert alert--success",t.className),children:t.children})}function k(t){return(0,i.jsx)("svg",{viewBox:"0 0 14 16",...t,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const C={icon:(0,i.jsx)(k,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function w(t){return(0,i.jsx)(p,{...C,...t,className:(0,o.A)("alert alert--info",t.className),children:t.children})}function _(t){return(0,i.jsx)("svg",{viewBox:"0 0 16 16",...t,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const v={icon:(0,i.jsx)(_,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function S(t){return(0,i.jsx)("svg",{viewBox:"0 0 12 16",...t,children:(0,i.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const A={icon:(0,i.jsx)(S,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const T={icon:(0,i.jsx)(_,{}),title:(0,i.jsx)(s.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const M={...{note:m,tip:b,info:w,warning:function(t){return(0,i.jsx)(p,{...v,...t,className:(0,o.A)("alert alert--warning",t.className),children:t.children})},danger:function(t){return(0,i.jsx)(p,{...A,...t,className:(0,o.A)("alert alert--danger",t.className),children:t.children})}},...{secondary:t=>(0,i.jsx)(m,{title:"secondary",...t}),important:t=>(0,i.jsx)(w,{title:"important",...t}),success:t=>(0,i.jsx)(b,{title:"success",...t}),caution:function(t){return(0,i.jsx)(p,{...T,...t,className:(0,o.A)("alert alert--warning",t.className),children:t.children})}}};function B(t){const e=a(t),r=(n=e.type,M[n]||(console.warn(`No admonition component found for admonition type "${n}". Using Info as fallback.`),M.info));var n;return(0,i.jsx)(r,{...e})}},14333:(t,e,r)=>{"use strict";r.d(e,{A:()=>y});r(96540);var n=r(34164),i=r(74717),a=r(85246),o=r(86707),s=r(57880),l=r(32032),c=r(24763),h=r(74848);function u(t){return(0,h.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,h.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const d={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function p(){const t=(0,c.Ay)("/");return(0,h.jsx)("li",{className:"breadcrumbs__item",children:(0,h.jsx)(s.A,{"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:t,children:(0,h.jsx)(u,{className:d.breadcrumbHomeIcon})})})}const f={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function g(t){let{children:e,href:r,isLast:n}=t;const i="breadcrumbs__link";return n?(0,h.jsx)("span",{className:i,itemProp:"name",children:e}):r?(0,h.jsx)(s.A,{className:i,href:r,itemProp:"item",children:(0,h.jsx)("span",{itemProp:"name",children:e})}):(0,h.jsx)("span",{className:i,children:e})}function m(t){let{children:e,active:r,index:i,addMicrodata:a}=t;return(0,h.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,n.A)("breadcrumbs__item",{"breadcrumbs__item--active":r}),children:[e,(0,h.jsx)("meta",{itemProp:"position",content:String(i+1)})]})}function y(){const t=(0,a.OF)(),e=(0,o.Dt)();return t?(0,h.jsx)("nav",{className:(0,n.A)(i.G.docs.docBreadcrumbs,f.breadcrumbsContainer),"aria-label":(0,l.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,h.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[e&&(0,h.jsx)(p,{}),t.map(((e,r)=>{const n=r===t.length-1,i="category"===e.type&&e.linkUnlisted?void 0:e.href;return(0,h.jsx)(m,{active:n,index:r,addMicrodata:!!i,children:(0,h.jsx)(g,{href:i,isLast:n,children:e.label})},r)}))]})}):null}},71350:(t,e,r)=>{"use strict";r.r(e),r.d(e,{default:()=>wt});var n=r(96540),i=r(63523),a=r(15302),o=r(74848);const s=n.createContext(null);function l(t){let{children:e,content:r}=t;const i=function(t){return(0,n.useMemo)((()=>({metadata:t.metadata,frontMatter:t.frontMatter,assets:t.assets,contentTitle:t.contentTitle,toc:t.toc})),[t])}(r);return(0,o.jsx)(s.Provider,{value:i,children:e})}function c(){const t=(0,n.useContext)(s);if(null===t)throw new a.dV("DocProvider");return t}function h(){const{metadata:t,frontMatter:e,assets:r}=c();return(0,o.jsx)(i.be,{title:t.title,description:t.description,keywords:e.keywords,image:r.image??e.image})}var u=r(34164),d=r(49607),p=r(86359);function f(){const{metadata:t}=c();return(0,o.jsx)(p.A,{previous:t.previous,next:t.next})}var g=r(43088),m=r(96073),y=r(74717),x=r(32032),b=r(57880);const k={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};function C(t){let{permalink:e,label:r,count:n,description:i}=t;return(0,o.jsxs)(b.A,{href:e,title:i,className:(0,u.A)(k.tag,n?k.tagWithCount:k.tagRegular),children:[r,n&&(0,o.jsx)("span",{children:n})]})}const w={tags:"tags_jXut",tag:"tag_QGVx"};function _(t){let{tags:e}=t;return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("b",{children:(0,o.jsx)(x.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,o.jsx)("ul",{className:(0,u.A)(w.tags,"padding--none","margin-left--sm"),children:e.map((t=>(0,o.jsx)("li",{className:w.tag,children:(0,o.jsx)(C,{...t})},t.permalink)))})]})}const v={iconEdit:"iconEdit_Z9Sw"};function S(t){let{className:e,...r}=t;return(0,o.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,u.A)(v.iconEdit,e),"aria-hidden":"true",...r,children:(0,o.jsx)("g",{children:(0,o.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function A(t){let{editUrl:e}=t;return(0,o.jsxs)(b.A,{to:e,className:y.G.common.editThisPage,children:[(0,o.jsx)(S,{}),(0,o.jsx)(x.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var T=r(25792);function M(t){void 0===t&&(t={});const{i18n:{currentLocale:e}}=(0,T.A)(),r=function(){const{i18n:{currentLocale:t,localeConfigs:e}}=(0,T.A)();return e[t].calendar}();return new Intl.DateTimeFormat(e,{calendar:r,...t})}function B(t){let{lastUpdatedAt:e}=t;const r=new Date(e),n=M({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(r);return(0,o.jsx)(x.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,o.jsx)("b",{children:(0,o.jsx)("time",{dateTime:r.toISOString(),itemProp:"dateModified",children:n})})},children:" on {date}"})}function L(t){let{lastUpdatedBy:e}=t;return(0,o.jsx)(x.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,o.jsx)("b",{children:e})},children:" by {user}"})}function F(t){let{lastUpdatedAt:e,lastUpdatedBy:r}=t;return(0,o.jsxs)("span",{className:y.G.common.lastUpdated,children:[(0,o.jsx)(x.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:e?(0,o.jsx)(B,{lastUpdatedAt:e}):"",byUser:r?(0,o.jsx)(L,{lastUpdatedBy:r}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const $={lastUpdated:"lastUpdated_JAkA"};function E(t){let{className:e,editUrl:r,lastUpdatedAt:n,lastUpdatedBy:i}=t;return(0,o.jsxs)("div",{className:(0,u.A)("row",e),children:[(0,o.jsx)("div",{className:"col",children:r&&(0,o.jsx)(A,{editUrl:r})}),(0,o.jsx)("div",{className:(0,u.A)("col",$.lastUpdated),children:(n||i)&&(0,o.jsx)(F,{lastUpdatedAt:n,lastUpdatedBy:i})})]})}function N(){const{metadata:t}=c(),{editUrl:e,lastUpdatedAt:r,lastUpdatedBy:n,tags:i}=t,a=i.length>0,s=!!(e||r||n);return a||s?(0,o.jsxs)("footer",{className:(0,u.A)(y.G.docs.docFooter,"docusaurus-mt-lg"),children:[a&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",y.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(_,{tags:i})})}),s&&(0,o.jsx)(E,{className:(0,u.A)("margin-top--sm",y.G.docs.docFooterEditMetaRow),editUrl:e,lastUpdatedAt:r,lastUpdatedBy:n})]}):null}var D=r(70936),j=r(31436);function I(t){const e=t.map((t=>({...t,parentIndex:-1,children:[]}))),r=Array(7).fill(-1);e.forEach(((t,e)=>{const n=r.slice(2,t.level);t.parentIndex=Math.max(...n),r[t.level]=e}));const n=[];return e.forEach((t=>{const{parentIndex:r,...i}=t;r>=0?e[r].children.push(i):n.push(i)})),n}function O(t){let{toc:e,minHeadingLevel:r,maxHeadingLevel:n}=t;return e.flatMap((t=>{const e=O({toc:t.children,minHeadingLevel:r,maxHeadingLevel:n});return function(t){return t.level>=r&&t.level<=n}(t)?[{...t,children:e}]:e}))}function R(t){const e=t.getBoundingClientRect();return e.top===e.bottom?R(t.parentNode):e}function P(t,e){let{anchorTopOffset:r}=e;const n=t.find((t=>R(t).top>=r));if(n){return function(t){return t.top>0&&t.bottom{t.current=e?0:document.querySelector(".navbar").clientHeight}),[e]),t}function K(t){const e=(0,n.useRef)(void 0),r=z();(0,n.useEffect)((()=>{if(!t)return()=>{};const{linkClassName:n,linkActiveClassName:i,minHeadingLevel:a,maxHeadingLevel:o}=t;function s(){const t=function(t){return Array.from(document.getElementsByClassName(t))}(n),s=function(t){let{minHeadingLevel:e,maxHeadingLevel:r}=t;const n=[];for(let i=e;i<=r;i+=1)n.push(`h${i}.anchor`);return Array.from(document.querySelectorAll(n.join()))}({minHeadingLevel:a,maxHeadingLevel:o}),l=P(s,{anchorTopOffset:r.current}),c=t.find((t=>l&&l.id===function(t){return decodeURIComponent(t.href.substring(t.href.indexOf("#")+1))}(t)));t.forEach((t=>{!function(t,r){r?(e.current&&e.current!==t&&e.current.classList.remove(i),t.classList.add(i),e.current=t):t.classList.remove(i)}(t,t===c)}))}return document.addEventListener("scroll",s),document.addEventListener("resize",s),s(),()=>{document.removeEventListener("scroll",s),document.removeEventListener("resize",s)}}),[t,r])}function q(t){let{toc:e,className:r,linkClassName:n,isChild:i}=t;return e.length?(0,o.jsx)("ul",{className:i?void 0:r,children:e.map((t=>(0,o.jsxs)("li",{children:[(0,o.jsx)(b.A,{to:`#${t.id}`,className:n??void 0,dangerouslySetInnerHTML:{__html:t.value}}),(0,o.jsx)(q,{isChild:!0,toc:t.children,className:r,linkClassName:n})]},t.id)))}):null}const W=n.memo(q);function H(t){let{toc:e,className:r="table-of-contents table-of-contents__left-border",linkClassName:i="table-of-contents__link",linkActiveClassName:a,minHeadingLevel:s,maxHeadingLevel:l,...c}=t;const h=(0,j.p)(),u=s??h.tableOfContents.minHeadingLevel,d=l??h.tableOfContents.maxHeadingLevel,p=function(t){let{toc:e,minHeadingLevel:r,maxHeadingLevel:i}=t;return(0,n.useMemo)((()=>O({toc:I(e),minHeadingLevel:r,maxHeadingLevel:i})),[e,r,i])}({toc:e,minHeadingLevel:u,maxHeadingLevel:d});return K((0,n.useMemo)((()=>{if(i&&a)return{linkClassName:i,linkActiveClassName:a,minHeadingLevel:u,maxHeadingLevel:d}}),[i,a,u,d])),(0,o.jsx)(W,{toc:p,className:r,linkClassName:i,...c})}const U={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function Y(t){let{collapsed:e,...r}=t;return(0,o.jsx)("button",{type:"button",...r,className:(0,u.A)("clean-btn",U.tocCollapsibleButton,!e&&U.tocCollapsibleButtonExpanded,r.className),children:(0,o.jsx)(x.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const V={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(t){let{toc:e,className:r,minHeadingLevel:n,maxHeadingLevel:i}=t;const{collapsed:a,toggleCollapsed:s}=(0,D.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(V.tocCollapsible,!a&&V.tocCollapsibleExpanded,r),children:[(0,o.jsx)(Y,{collapsed:a,onClick:s}),(0,o.jsx)(D.N,{lazy:!0,className:V.tocCollapsibleContent,collapsed:a,children:(0,o.jsx)(H,{toc:e,minHeadingLevel:n,maxHeadingLevel:i})})]})}const Z={tocMobile:"tocMobile_ITEo"};function X(){const{toc:t,frontMatter:e}=c();return(0,o.jsx)(G,{toc:t,minHeadingLevel:e.toc_min_heading_level,maxHeadingLevel:e.toc_max_heading_level,className:(0,u.A)(y.G.docs.docTocMobile,Z.tocMobile)})}const Q={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},J="table-of-contents__link toc-highlight",tt="table-of-contents__link--active";function et(t){let{className:e,...r}=t;return(0,o.jsx)("div",{className:(0,u.A)(Q.tableOfContents,"thin-scrollbar",e),children:(0,o.jsx)(H,{...r,linkClassName:J,linkActiveClassName:tt})})}function rt(){const{toc:t,frontMatter:e}=c();return(0,o.jsx)(et,{toc:t,minHeadingLevel:e.toc_min_heading_level,maxHeadingLevel:e.toc_max_heading_level,className:y.G.docs.docTocDesktop})}var nt=r(98445),it=r(28453),at=r(7084);function ot(t){let{children:e}=t;return(0,o.jsx)(it.x,{components:at.A,children:e})}function st(t){let{children:e}=t;const r=function(){const{metadata:t,frontMatter:e,contentTitle:r}=c();return e.hide_title||void 0!==r?null:t.title}();return(0,o.jsxs)("div",{className:(0,u.A)(y.G.docs.docMarkdown,"markdown"),children:[r&&(0,o.jsx)("header",{children:(0,o.jsx)(nt.A,{as:"h1",children:r})}),(0,o.jsx)(ot,{children:e})]})}var lt=r(14333),ct=r(24502);function ht(){return(0,o.jsx)(x.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function ut(){return(0,o.jsx)(x.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function dt(){return(0,o.jsx)(ct.A,{children:(0,o.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function pt(){return(0,o.jsx)(x.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function ft(){return(0,o.jsx)(x.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}var gt=r(37235);function mt(t){let{className:e}=t;return(0,o.jsx)(gt.A,{type:"caution",title:(0,o.jsx)(pt,{}),className:(0,u.A)(e,y.G.common.draftBanner),children:(0,o.jsx)(ft,{})})}function yt(t){let{className:e}=t;return(0,o.jsx)(gt.A,{type:"caution",title:(0,o.jsx)(ht,{}),className:(0,u.A)(e,y.G.common.unlistedBanner),children:(0,o.jsx)(ut,{})})}function xt(t){return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(dt,{}),(0,o.jsx)(yt,{...t})]})}function bt(t){let{metadata:e}=t;const{unlisted:r,frontMatter:n}=e;return(0,o.jsxs)(o.Fragment,{children:[(r||n.unlisted)&&(0,o.jsx)(xt,{}),n.draft&&(0,o.jsx)(mt,{})]})}const kt={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function Ct(t){let{children:e}=t;const r=function(){const{frontMatter:t,toc:e}=c(),r=(0,d.l)(),n=t.hide_table_of_contents,i=!n&&e.length>0;return{hidden:n,mobile:i?(0,o.jsx)(X,{}):void 0,desktop:!i||"desktop"!==r&&"ssr"!==r?void 0:(0,o.jsx)(rt,{})}}(),{metadata:n}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!r.hidden&&kt.docItemCol),children:[(0,o.jsx)(bt,{metadata:n}),(0,o.jsx)(g.A,{}),(0,o.jsxs)("div",{className:kt.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(lt.A,{}),(0,o.jsx)(m.A,{}),r.mobile,(0,o.jsx)(st,{children:e}),(0,o.jsx)(N,{})]}),(0,o.jsx)(f,{})]})]}),r.desktop&&(0,o.jsx)("div",{className:"col col--3",children:r.desktop})]})}function wt(t){const e=`docs-doc-id-${t.content.metadata.id}`,r=t.content;return(0,o.jsx)(l,{content:t.content,children:(0,o.jsxs)(i.e3,{className:e,children:[(0,o.jsx)(h,{}),(0,o.jsx)(Ct,{children:(0,o.jsx)(r,{})})]})})}},86359:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});r(96540);var n=r(32032),i=r(34164),a=r(57880),o=r(74848);function s(t){const{permalink:e,title:r,subLabel:n,isNext:s}=t;return(0,o.jsxs)(a.A,{className:(0,i.A)("pagination-nav__link",s?"pagination-nav__link--next":"pagination-nav__link--prev"),to:e,children:[n&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:n}),(0,o.jsx)("div",{className:"pagination-nav__label",children:r})]})}function l(t){const{previous:e,next:r}=t;return(0,o.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,n.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[e&&(0,o.jsx)(s,{...e,subLabel:(0,o.jsx)(n.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),r&&(0,o.jsx)(s,{...r,subLabel:(0,o.jsx)(n.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}},96073:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});r(96540);var n=r(34164),i=r(32032),a=r(74717),o=r(18875),s=r(74848);function l(t){let{className:e}=t;const r=(0,o.r)();return r.badge?(0,s.jsx)("span",{className:(0,n.A)(e,a.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,s.jsx)(i.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:r.label},children:"Version: {versionLabel}"})}):null}},43088:(t,e,r)=>{"use strict";r.d(e,{A:()=>m});r(96540);var n=r(34164),i=r(25792),a=r(57880),o=r(32032),s=r(80869),l=r(74717),c=r(36220),h=r(18875),u=r(74848);const d={unreleased:function(t){let{siteTitle:e,versionMetadata:r}=t;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:r.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(t){let{siteTitle:e,versionMetadata:r}=t;return(0,u.jsx)(o.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:e,versionLabel:(0,u.jsx)("b",{children:r.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function p(t){const e=d[t.versionMetadata.banner];return(0,u.jsx)(e,{...t})}function f(t){let{versionLabel:e,to:r,onClick:n}=t;return(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:e,latestVersionLink:(0,u.jsx)("b",{children:(0,u.jsx)(a.A,{to:r,onClick:n,children:(0,u.jsx)(o.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function g(t){let{className:e,versionMetadata:r}=t;const{siteConfig:{title:a}}=(0,i.A)(),{pluginId:o}=(0,s.vT)({failfast:!0}),{savePreferredVersionName:h}=(0,c.g1)(o),{latestDocSuggestion:d,latestVersionSuggestion:g}=(0,s.HW)(o),m=d??(y=g).docs.find((t=>t.id===y.mainDocId));var y;return(0,u.jsxs)("div",{className:(0,n.A)(e,l.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,u.jsx)("div",{children:(0,u.jsx)(p,{siteTitle:a,versionMetadata:r})}),(0,u.jsx)("div",{className:"margin-top--md",children:(0,u.jsx)(f,{versionLabel:g.label,to:m.path,onClick:()=>h(g.name)})})]})}function m(t){let{className:e}=t;const r=(0,h.r)();return r.banner?(0,u.jsx)(g,{className:e,versionMetadata:r}):null}},94763:(t,e,r)=>{"use strict";r.d(e,{A:()=>tn});var n=r(96540),i=r(24502),a=r(94753),o=r(34164),s=r(65331),l=r(31436);function c(){const{prism:t}=(0,l.p)(),{colorMode:e}=(0,s.G)(),r=t.theme,n=t.darkTheme||r;return"dark"===e?n:r}var h=r(74717),u=r(18426),d=r.n(u);const p=/title=(?["'])(?.*?)\1/,f=/\{(?<range>[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},m={...g,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},y=Object.keys(g);function x(t,e){const r=t.map((t=>{const{start:r,end:n}=m[t];return`(?:${r}\\s*(${e.flatMap((t=>[t.line,t.block?.start,t.block?.end].filter(Boolean))).join("|")})\\s*${n})`})).join("|");return new RegExp(`^\\s*(?:${r})\\s*$`)}function b(t,e){let r=t.replace(/\n$/,"");const{language:n,magicComments:i,metastring:a}=e;if(a&&f.test(a)){const t=a.match(f).groups.range;if(0===i.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${a}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const e=i[0].className,n=d()(t).filter((t=>t>0)).map((t=>[t-1,[e]]));return{lineClassNames:Object.fromEntries(n),code:r}}if(void 0===n)return{lineClassNames:{},code:r};const o=function(t,e){switch(t){case"js":case"javascript":case"ts":case"typescript":return x(["js","jsBlock"],e);case"jsx":case"tsx":return x(["js","jsBlock","jsx"],e);case"html":return x(["js","jsBlock","html"],e);case"python":case"py":case"bash":return x(["bash"],e);case"markdown":case"md":return x(["html","jsx","bash"],e);case"tex":case"latex":case"matlab":return x(["tex"],e);case"lua":case"haskell":case"sql":return x(["lua"],e);case"wasm":return x(["wasm"],e);case"vb":case"vba":case"visual-basic":return x(["vb","rem"],e);case"vbnet":return x(["vbnet","rem"],e);case"batch":return x(["rem"],e);case"basic":return x(["rem","f90"],e);case"fsharp":return x(["js","ml"],e);case"ocaml":case"sml":return x(["ml"],e);case"fortran":return x(["f90"],e);case"cobol":return x(["cobol"],e);default:return x(y,e)}}(n,i),s=r.split("\n"),l=Object.fromEntries(i.map((t=>[t.className,{start:0,range:""}]))),c=Object.fromEntries(i.filter((t=>t.line)).map((t=>{let{className:e,line:r}=t;return[r,e]}))),h=Object.fromEntries(i.filter((t=>t.block)).map((t=>{let{className:e,block:r}=t;return[r.start,e]}))),u=Object.fromEntries(i.filter((t=>t.block)).map((t=>{let{className:e,block:r}=t;return[r.end,e]})));for(let d=0;d<s.length;){const t=s[d].match(o);if(!t){d+=1;continue}const e=t.slice(1).find((t=>void 0!==t));c[e]?l[c[e]].range+=`${d},`:h[e]?l[h[e]].start=d:u[e]&&(l[u[e]].range+=`${l[u[e]].start}-${d-1},`),s.splice(d,1)}r=s.join("\n");const p={};return Object.entries(l).forEach((t=>{let[e,{range:r}]=t;d()(r).forEach((t=>{p[t]??=[],p[t].push(e)}))})),{lineClassNames:p,code:r}}const k={codeBlockContainer:"codeBlockContainer_Ckt0"};var C=r(74848);function w(t){let{as:e,...r}=t;const n=function(t){const e={color:"--prism-color",backgroundColor:"--prism-background-color"},r={};return Object.entries(t.plain).forEach((t=>{let[n,i]=t;const a=e[n];a&&"string"==typeof i&&(r[a]=i)})),r}(c());return(0,C.jsx)(e,{...r,style:n,className:(0,o.A)(r.className,k.codeBlockContainer,h.G.common.codeBlock)})}const _={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function v(t){let{children:e,className:r}=t;return(0,C.jsx)(w,{as:"pre",tabIndex:0,className:(0,o.A)(_.codeBlockStandalone,"thin-scrollbar",r),children:(0,C.jsx)("code",{className:_.codeBlockLines,children:e})})}var S=r(15302);const A={attributes:!0,characterData:!0,childList:!0,subtree:!0};function T(t,e){const[r,i]=(0,n.useState)(),a=(0,n.useCallback)((()=>{i(t.current?.closest("[role=tabpanel][hidden]"))}),[t,i]);(0,n.useEffect)((()=>{a()}),[a]),function(t,e,r){void 0===r&&(r=A);const i=(0,S._q)(e),a=(0,S.Be)(r);(0,n.useEffect)((()=>{const e=new MutationObserver(i);return t&&e.observe(t,a),()=>e.disconnect()}),[t,i,a])}(r,(t=>{t.forEach((t=>{"attributes"===t.type&&"hidden"===t.attributeName&&(e(),a())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var M=r(71765);const B={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function L(t){let{line:e,classNames:r,showLineNumbers:n,getLineProps:i,getTokenProps:a}=t;1===e.length&&"\n"===e[0].content&&(e[0].content="");const s=i({line:e,className:(0,o.A)(r,n&&B.codeLine)}),l=e.map(((t,e)=>(0,C.jsx)("span",{...a({token:t})},e)));return(0,C.jsxs)("span",{...s,children:[n?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)("span",{className:B.codeLineNumber}),(0,C.jsx)("span",{className:B.codeLineContent,children:l})]}):l,(0,C.jsx)("br",{})]})}var F=r(32032);function $(t){return(0,C.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,C.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function E(t){return(0,C.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,C.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const N={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function D(t){let{code:e,className:r}=t;const[i,a]=(0,n.useState)(!1),s=(0,n.useRef)(void 0),l=(0,n.useCallback)((()=>{!function(t,e){let{target:r=document.body}=void 0===e?{}:e;if("string"!=typeof t)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof t}\`.`);const n=document.createElement("textarea"),i=document.activeElement;n.value=t,n.setAttribute("readonly",""),n.style.contain="strict",n.style.position="absolute",n.style.left="-9999px",n.style.fontSize="12pt";const a=document.getSelection(),o=a.rangeCount>0&&a.getRangeAt(0);r.append(n),n.select(),n.selectionStart=0,n.selectionEnd=t.length;let s=!1;try{s=document.execCommand("copy")}catch{}n.remove(),o&&(a.removeAllRanges(),a.addRange(o)),i&&i.focus()}(e),a(!0),s.current=window.setTimeout((()=>{a(!1)}),1e3)}),[e]);return(0,n.useEffect)((()=>()=>window.clearTimeout(s.current)),[]),(0,C.jsx)("button",{type:"button","aria-label":i?(0,F.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,F.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,F.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,o.A)("clean-btn",r,N.copyButton,i&&N.copyButtonCopied),onClick:l,children:(0,C.jsxs)("span",{className:N.copyButtonIcons,"aria-hidden":"true",children:[(0,C.jsx)($,{className:N.copyButtonIcon}),(0,C.jsx)(E,{className:N.copyButtonSuccessIcon})]})})}function j(t){return(0,C.jsx)("svg",{viewBox:"0 0 24 24",...t,children:(0,C.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const I={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function O(t){let{className:e,onClick:r,isEnabled:n}=t;const i=(0,F.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,C.jsx)("button",{type:"button",onClick:r,className:(0,o.A)("clean-btn",e,n&&I.wordWrapButtonEnabled),"aria-label":i,title:i,children:(0,C.jsx)(j,{className:I.wordWrapButtonIcon,"aria-hidden":"true"})})}function R(t){let{children:e,className:r="",metastring:i,title:a,showLineNumbers:s,language:h}=t;const{prism:{defaultLanguage:u,magicComments:d}}=(0,l.p)(),f=function(t){return t?.toLowerCase()}(h??function(t){const e=t.split(" ").find((t=>t.startsWith("language-")));return e?.replace(/language-/,"")}(r)??u),g=c(),m=function(){const[t,e]=(0,n.useState)(!1),[r,i]=(0,n.useState)(!1),a=(0,n.useRef)(null),o=(0,n.useCallback)((()=>{const r=a.current.querySelector("code");t?r.removeAttribute("style"):(r.style.whiteSpace="pre-wrap",r.style.overflowWrap="anywhere"),e((t=>!t))}),[a,t]),s=(0,n.useCallback)((()=>{const{scrollWidth:t,clientWidth:e}=a.current,r=t>e||a.current.querySelector("code").hasAttribute("style");i(r)}),[a]);return T(a,s),(0,n.useEffect)((()=>{s()}),[t,s]),(0,n.useEffect)((()=>(window.addEventListener("resize",s,{passive:!0}),()=>{window.removeEventListener("resize",s)})),[s]),{codeBlockRef:a,isEnabled:t,isCodeScrollable:r,toggle:o}}(),y=function(t){return t?.match(p)?.groups.title??""}(i)||a,{lineClassNames:x,code:k}=b(e,{metastring:i,language:f,magicComments:d}),v=s??function(t){return Boolean(t?.includes("showLineNumbers"))}(i);return(0,C.jsxs)(w,{as:"div",className:(0,o.A)(r,f&&!r.includes(`language-${f}`)&&`language-${f}`),children:[y&&(0,C.jsx)("div",{className:_.codeBlockTitle,children:y}),(0,C.jsxs)("div",{className:_.codeBlockContent,children:[(0,C.jsx)(M.f4,{theme:g,code:k,language:f??"text",children:t=>{let{className:e,style:r,tokens:n,getLineProps:i,getTokenProps:a}=t;return(0,C.jsx)("pre",{tabIndex:0,ref:m.codeBlockRef,className:(0,o.A)(e,_.codeBlock,"thin-scrollbar"),style:r,children:(0,C.jsx)("code",{className:(0,o.A)(_.codeBlockLines,v&&_.codeBlockLinesWithNumbering),children:n.map(((t,e)=>(0,C.jsx)(L,{line:t,getLineProps:i,getTokenProps:a,classNames:x[e],showLineNumbers:v},e)))})})}}),(0,C.jsxs)("div",{className:_.buttonGroup,children:[(m.isEnabled||m.isCodeScrollable)&&(0,C.jsx)(O,{className:_.codeButton,onClick:()=>m.toggle(),isEnabled:m.isEnabled}),(0,C.jsx)(D,{className:_.codeButton,code:k})]})]})]})}function P(t){let{children:e,...r}=t;const i=(0,a.A)(),o=function(t){return n.Children.toArray(t).some((t=>(0,n.isValidElement)(t)))?t:Array.isArray(t)?t.join(""):t}(e),s="string"==typeof o?R:v;return(0,C.jsx)(s,{...r,children:o},String(i))}function z(t){return(0,C.jsx)("code",{...t})}var K=r(57880);var q=r(97756),W=r(70936);const H={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function U(t){return!!t&&("SUMMARY"===t.tagName||U(t.parentElement))}function Y(t,e){return!!t&&(t===e||Y(t.parentElement,e))}function V(t){let{summary:e,children:r,...i}=t;(0,q.A)().collectAnchor(i.id);const s=(0,a.A)(),l=(0,n.useRef)(null),{collapsed:c,setCollapsed:h}=(0,W.u)({initialState:!i.open}),[u,d]=(0,n.useState)(i.open),p=n.isValidElement(e)?e:(0,C.jsx)("summary",{children:e??"Details"});return(0,C.jsxs)("details",{...i,ref:l,open:u,"data-collapsed":c,className:(0,o.A)(H.details,s&&H.isBrowser,i.className),onMouseDown:t=>{U(t.target)&&t.detail>1&&t.preventDefault()},onClick:t=>{t.stopPropagation();const e=t.target;U(e)&&Y(e,l.current)&&(t.preventDefault(),c?(h(!1),d(!0)):h(!0))},children:[p,(0,C.jsx)(W.N,{lazy:!1,collapsed:c,disableSSRStyle:!0,onCollapseTransitionEnd:t=>{h(t),d(!t)},children:(0,C.jsx)("div",{className:H.collapsibleContent,children:r})})]})}const G={details:"details_b_Ee"},Z="alert alert--info";function X(t){let{...e}=t;return(0,C.jsx)(V,{...e,className:(0,o.A)(Z,G.details,e.className)})}function Q(t){const e=n.Children.toArray(t.children),r=e.find((t=>n.isValidElement(t)&&"summary"===t.type)),i=(0,C.jsx)(C.Fragment,{children:e.filter((t=>t!==r))});return(0,C.jsx)(X,{...t,summary:r,children:i})}var J=r(98445);function tt(t){return(0,C.jsx)(J.A,{...t})}const et={containsTaskList:"containsTaskList_mC6p"};function rt(t){if(void 0!==t)return(0,o.A)(t,t?.includes("contains-task-list")&&et.containsTaskList)}const nt={img:"img_ev3q"};var it=r(37235),at=r(50035),ot=r(71373),st=r(79515),lt=r(79740),ct=(r(6396),r(5081),r(34483)),ht=(r(52294),r(62392),r(86825),r(85039)),ut=r(29196),dt=r(61021),pt=r(45567),ft=r(60513),gt=r(20007),mt="comm",yt="rule",xt="decl",bt=Math.abs,kt=String.fromCharCode;Object.assign;function Ct(t){return t.trim()}function wt(t,e,r){return t.replace(e,r)}function _t(t,e,r){return t.indexOf(e,r)}function vt(t,e){return 0|t.charCodeAt(e)}function St(t,e,r){return t.slice(e,r)}function At(t){return t.length}function Tt(t,e){return e.push(t),t}function Mt(t,e){for(var r="",n=0;n<t.length;n++)r+=e(t[n],n,t,e)||"";return r}function Bt(t,e,r,n){switch(t.type){case"@layer":if(t.children.length)break;case"@import":case xt:return t.return=t.return||t.value;case mt:return"";case"@keyframes":return t.return=t.value+"{"+Mt(t.children,n)+"}";case yt:if(!At(t.value=t.props.join(",")))return""}return At(r=Mt(t.children,n))?t.return=t.value+"{"+r+"}":""}var Lt=1,Ft=1,$t=0,Et=0,Nt=0,Dt="";function jt(t,e,r,n,i,a,o,s){return{value:t,root:e,parent:r,type:n,props:i,children:a,line:Lt,column:Ft,length:o,return:"",siblings:s}}function It(){return Nt=Et>0?vt(Dt,--Et):0,Ft--,10===Nt&&(Ft=1,Lt--),Nt}function Ot(){return Nt=Et<$t?vt(Dt,Et++):0,Ft++,10===Nt&&(Ft=1,Lt++),Nt}function Rt(){return vt(Dt,Et)}function Pt(){return Et}function zt(t,e){return St(Dt,t,e)}function Kt(t){switch(t){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function qt(t){return Lt=Ft=1,$t=At(Dt=t),Et=0,[]}function Wt(t){return Dt="",t}function Ht(t){return Ct(zt(Et-1,Vt(91===t?t+2:40===t?t+1:t)))}function Ut(t){for(;(Nt=Rt())&&Nt<33;)Ot();return Kt(t)>2||Kt(Nt)>3?"":" "}function Yt(t,e){for(;--e&&Ot()&&!(Nt<48||Nt>102||Nt>57&&Nt<65||Nt>70&&Nt<97););return zt(t,Pt()+(e<6&&32==Rt()&&32==Ot()))}function Vt(t){for(;Ot();)switch(Nt){case t:return Et;case 34:case 39:34!==t&&39!==t&&Vt(Nt);break;case 40:41===t&&Vt(t);break;case 92:Ot()}return Et}function Gt(t,e){for(;Ot()&&t+Nt!==57&&(t+Nt!==84||47!==Rt()););return"/*"+zt(e,Et-1)+"*"+kt(47===t?t:Ot())}function Zt(t){for(;!Kt(Rt());)Ot();return zt(t,Et)}function Xt(t){return Wt(Qt("",null,null,null,[""],t=qt(t),0,[0],t))}function Qt(t,e,r,n,i,a,o,s,l){for(var c=0,h=0,u=o,d=0,p=0,f=0,g=1,m=1,y=1,x=0,b="",k=i,C=a,w=n,_=b;m;)switch(f=x,x=Ot()){case 40:if(108!=f&&58==vt(_,u-1)){-1!=_t(_+=wt(Ht(x),"&","&\f"),"&\f",bt(c?s[c-1]:0))&&(y=-1);break}case 34:case 39:case 91:_+=Ht(x);break;case 9:case 10:case 13:case 32:_+=Ut(f);break;case 92:_+=Yt(Pt()-1,7);continue;case 47:switch(Rt()){case 42:case 47:Tt(te(Gt(Ot(),Pt()),e,r,l),l),5!=Kt(f||1)&&5!=Kt(Rt()||1)||!At(_)||" "===St(_,-1,void 0)||(_+=" ");break;default:_+="/"}break;case 123*g:s[c++]=At(_)*y;case 125*g:case 59:case 0:switch(x){case 0:case 125:m=0;case 59+h:-1==y&&(_=wt(_,/\f/g,"")),p>0&&(At(_)-u||0===g&&47===f)&&Tt(p>32?ee(_+";",n,r,u-1,l):ee(wt(_," ","")+";",n,r,u-2,l),l);break;case 59:_+=";";default:if(Tt(w=Jt(_,e,r,c,h,i,s,b,k=[],C=[],u,a),a),123===x)if(0===h)Qt(_,e,w,w,k,a,u,s,C);else switch(99===d&&110===vt(_,3)?100:d){case 100:case 108:case 109:case 115:Qt(t,w,w,n&&Tt(Jt(t,w,w,0,0,i,s,b,i,k=[],u,C),C),i,C,u,s,n?k:C);break;default:Qt(_,w,w,w,[""],C,0,s,C)}}c=h=p=0,g=y=1,b=_="",u=o;break;case 58:u=1+At(_),p=f;default:if(g<1)if(123==x)--g;else if(125==x&&0==g++&&125==It())continue;switch(_+=kt(x),x*g){case 38:y=h>0?1:(_+="\f",-1);break;case 44:s[c++]=(At(_)-1)*y,y=1;break;case 64:45===Rt()&&(_+=Ht(Ot())),d=Rt(),h=u=At(b=_+=Zt(Pt())),x++;break;case 45:45===f&&2==At(_)&&(g=0)}}return a}function Jt(t,e,r,n,i,a,o,s,l,c,h,u){for(var d=i-1,p=0===i?a:[""],f=function(t){return t.length}(p),g=0,m=0,y=0;g<n;++g)for(var x=0,b=St(t,d+1,d=bt(m=o[g])),k=t;x<f;++x)(k=Ct(m>0?p[x]+" "+b:wt(b,/&\f/g,p[x])))&&(l[y++]=k);return jt(t,e,r,0===i?yt:s,l,c,h,u)}function te(t,e,r,n){return jt(t,e,r,mt,kt(Nt),St(t,2,-2),0,n)}function ee(t,e,r,n,i){return jt(t,e,r,xt,St(t,0,n),St(t,n+1,-1),n,i)}var re=r(42838),ne=r(66401),ie={id:"c4",detector:(0,pt.K2)((t=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(155).then(r.bind(r,60155));return{id:"c4",diagram:t}}),"loader")},ae="flowchart",oe={id:ae,detector:(0,pt.K2)(((t,e)=>"dagre-wrapper"!==e?.flowchart?.defaultRenderer&&"elk"!==e?.flowchart?.defaultRenderer&&/^\s*graph/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(1689).then(r.bind(r,71689));return{id:ae,diagram:t}}),"loader")},se="flowchart-v2",le={id:se,detector:(0,pt.K2)(((t,e)=>"dagre-d3"!==e?.flowchart?.defaultRenderer&&("elk"===e?.flowchart?.defaultRenderer&&(e.layout="elk"),!(!/^\s*graph/.test(t)||"dagre-wrapper"!==e?.flowchart?.defaultRenderer)||/^\s*flowchart/.test(t))),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(1689).then(r.bind(r,71689));return{id:se,diagram:t}}),"loader")},ce={id:"er",detector:(0,pt.K2)((t=>/^\s*erDiagram/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(2334),r.e(9368)]).then(r.bind(r,69368));return{id:"er",diagram:t}}),"loader")},he="gitGraph",ue={id:he,detector:(0,pt.K2)((t=>/^\s*gitGraph/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(8174)]).then(r.bind(r,78174));return{id:he,diagram:t}}),"loader")},de="gantt",pe={id:de,detector:(0,pt.K2)((t=>/^\s*gantt/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(1711).then(r.bind(r,81711));return{id:de,diagram:t}}),"loader")},fe="info",ge={id:fe,detector:(0,pt.K2)((t=>/^\s*info/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(8998)]).then(r.bind(r,68998));return{id:fe,diagram:t}}),"loader")},me={id:"pie",detector:(0,pt.K2)((t=>/^\s*pie/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(2763)]).then(r.bind(r,62763));return{id:"pie",diagram:t}}),"loader")},ye="quadrantChart",xe={id:ye,detector:(0,pt.K2)((t=>/^\s*quadrantChart/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(3364).then(r.bind(r,73364));return{id:ye,diagram:t}}),"loader")},be="xychart",ke={id:be,detector:(0,pt.K2)((t=>/^\s*xychart-beta/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(9802).then(r.bind(r,89802));return{id:be,diagram:t}}),"loader")},Ce="requirement",we={id:Ce,detector:(0,pt.K2)((t=>/^\s*requirement(Diagram)?/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(2334),r.e(8496)]).then(r.bind(r,8496));return{id:Ce,diagram:t}}),"loader")},_e="sequence",ve={id:_e,detector:(0,pt.K2)((t=>/^\s*sequenceDiagram/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(7032).then(r.bind(r,7032));return{id:_e,diagram:t}}),"loader")},Se="class",Ae={id:Se,detector:(0,pt.K2)(((t,e)=>"dagre-wrapper"!==e?.class?.defaultRenderer&&/^\s*classDiagram/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(6790),r.e(5606)]).then(r.bind(r,65606));return{id:Se,diagram:t}}),"loader")},Te="classDiagram",Me={id:Te,detector:(0,pt.K2)(((t,e)=>!(!/^\s*classDiagram/.test(t)||"dagre-wrapper"!==e?.class?.defaultRenderer)||/^\s*classDiagram-v2/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(6790),r.e(921)]).then(r.bind(r,80921));return{id:Te,diagram:t}}),"loader")},Be="state",Le={id:Be,detector:(0,pt.K2)(((t,e)=>"dagre-wrapper"!==e?.state?.defaultRenderer&&/^\s*stateDiagram/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(2334),r.e(9664),r.e(484)]).then(r.bind(r,50484));return{id:Be,diagram:t}}),"loader")},Fe="stateDiagram",$e={id:Fe,detector:(0,pt.K2)(((t,e)=>!!/^\s*stateDiagram-v2/.test(t)||!(!/^\s*stateDiagram/.test(t)||"dagre-wrapper"!==e?.state?.defaultRenderer)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(9664),r.e(9875)]).then(r.bind(r,29875));return{id:Fe,diagram:t}}),"loader")},Ee="journey",Ne={id:Ee,detector:(0,pt.K2)((t=>/^\s*journey/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(8379).then(r.bind(r,18379));return{id:Ee,diagram:t}}),"loader")},De={draw:(0,pt.K2)(((t,e,r)=>{pt.Rm.debug("rendering svg for syntax error\n");const n=(0,dt.D)(e),i=n.append("g");n.attr("viewBox","0 0 2412 512"),(0,pt.a$)(n,100,512,!0),i.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),i.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),i.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),i.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),i.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),i.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),i.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),i.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)}),"draw")},je=De,Ie={db:{},renderer:De,parser:{parse:(0,pt.K2)((()=>{}),"parse")}},Oe="flowchart-elk",Re={id:Oe,detector:(0,pt.K2)(((t,e={})=>!!(/^\s*flowchart-elk/.test(t)||/^\s*flowchart|graph/.test(t)&&"elk"===e?.flowchart?.defaultRenderer)&&(e.layout="elk",!0)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(1689).then(r.bind(r,71689));return{id:Oe,diagram:t}}),"loader")},Pe="timeline",ze={id:Pe,detector:(0,pt.K2)((t=>/^\s*timeline/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(7357).then(r.bind(r,77357));return{id:Pe,diagram:t}}),"loader")},Ke="mindmap",qe={id:Ke,detector:(0,pt.K2)((t=>/^\s*mindmap/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(165),r.e(4449)]).then(r.bind(r,14449));return{id:Ke,diagram:t}}),"loader")},We="kanban",He={id:We,detector:(0,pt.K2)((t=>/^\s*kanban/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(4445).then(r.bind(r,14445));return{id:We,diagram:t}}),"loader")},Ue="sankey",Ye={id:Ue,detector:(0,pt.K2)((t=>/^\s*sankey-beta/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await r.e(7060).then(r.bind(r,27060));return{id:Ue,diagram:t}}),"loader")},Ve="packet",Ge={id:Ve,detector:(0,pt.K2)((t=>/^\s*packet-beta/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(1186)]).then(r.bind(r,51186));return{id:Ve,diagram:t}}),"loader")},Ze="block",Xe={id:Ze,detector:(0,pt.K2)((t=>/^\s*block-beta/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(3840)]).then(r.bind(r,53840));return{id:Ze,diagram:t}}),"loader")},Qe="architecture",Je={id:Qe,detector:(0,pt.K2)((t=>/^\s*architecture/.test(t)),"detector"),loader:(0,pt.K2)((async()=>{const{diagram:t}=await Promise.all([r.e(3624),r.e(8731),r.e(165),r.e(2247)]).then(r.bind(r,22247));return{id:Qe,diagram:t}}),"loader")},tr=!1,er=(0,pt.K2)((()=>{tr||(tr=!0,(0,pt.Js)("error",Ie,(t=>"error"===t.toLowerCase().trim())),(0,pt.Js)("---",{db:{clear:(0,pt.K2)((()=>{}),"clear")},styles:{},renderer:{draw:(0,pt.K2)((()=>{}),"draw")},parser:{parse:(0,pt.K2)((()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")}),"parse")},init:(0,pt.K2)((()=>null),"init")},(t=>t.toLowerCase().trimStart().startsWith("---"))),(0,pt.Xd)(ie,He,Me,Ae,ce,pe,ge,me,we,ve,Re,le,oe,qe,ze,ue,$e,Le,Ne,xe,Ye,Ge,ke,Xe,Je))}),"addDiagrams"),rr=(0,pt.K2)((async()=>{pt.Rm.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(pt.mW).map((async([t,{detector:e,loader:r}])=>{if(r)try{(0,pt.Gs)(t)}catch{try{const{diagram:t,id:n}=await r();(0,pt.Js)(n,t,e)}catch(n){throw pt.Rm.error(`Failed to load external diagram with key ${t}. Removing from detectors.`),delete pt.mW[t],n}}})))).filter((t=>"rejected"===t.status));if(t.length>0){pt.Rm.error(`Failed to load ${t.length} external diagrams`);for(const e of t)pt.Rm.error(e);throw new Error(`Failed to load ${t.length} external diagrams`)}}),"loadRegisteredDiagrams"),nr="graphics-document document";function ir(t,e){t.attr("role",nr),""!==e&&t.attr("aria-roledescription",e)}function ar(t,e,r,n){if(void 0!==t.insert){if(r){const e=`chart-desc-${n}`;t.attr("aria-describedby",e),t.insert("desc",":first-child").attr("id",e).text(r)}if(e){const r=`chart-title-${n}`;t.attr("aria-labelledby",r),t.insert("title",":first-child").attr("id",r).text(e)}}}(0,pt.K2)(ir,"setA11yDiagramInfo"),(0,pt.K2)(ar,"addSVGa11yTitleDescription");var or=class t{constructor(t,e,r,n,i){this.type=t,this.text=e,this.db=r,this.parser=n,this.renderer=i}static{(0,pt.K2)(this,"Diagram")}static async fromText(e,r={}){const n=(0,pt.zj)(),i=(0,pt.Ch)(e,n);e=(0,ht.C4)(e)+"\n";try{(0,pt.Gs)(i)}catch{const t=(0,pt.J$)(i);if(!t)throw new pt.C0(`Diagram ${i} not found.`);const{id:e,diagram:r}=await t();(0,pt.Js)(e,r)}const{db:a,parser:o,renderer:s,init:l}=(0,pt.Gs)(i);return o.parser&&(o.parser.yy=a),a.clear?.(),l?.(n),r.title&&a.setDiagramTitle?.(r.title),await o.parse(e),new t(i,e,a,o,s)}async render(t,e){await this.renderer.draw(this.text,t,e,this)}getParser(){return this.parser}getType(){return this.type}},sr=[],lr=(0,pt.K2)((()=>{sr.forEach((t=>{t()})),sr=[]}),"attachFunctions"),cr=(0,pt.K2)((t=>t.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart()),"cleanupComments");function hr(t){const e=t.match(pt.EJ);if(!e)return{text:t,metadata:{}};let r=(0,st.H)(e[1],{schema:st.r})??{};r="object"!=typeof r||Array.isArray(r)?{}:r;const n={};return r.displayMode&&(n.displayMode=r.displayMode.toString()),r.title&&(n.title=r.title.toString()),r.config&&(n.config=r.config),{text:t.slice(e[0].length),metadata:n}}(0,pt.K2)(hr,"extractFrontMatter");var ur=(0,pt.K2)((t=>t.replace(/\r\n?/g,"\n").replace(/<(\w+)([^>]*)>/g,((t,e,r)=>"<"+e+r.replace(/="([^"]*)"/g,"='$1'")+">"))),"cleanupText"),dr=(0,pt.K2)((t=>{const{text:e,metadata:r}=hr(t),{displayMode:n,title:i,config:a={}}=r;return n&&(a.gantt||(a.gantt={}),a.gantt.displayMode=n),{title:i,config:a,text:e}}),"processFrontmatter"),pr=(0,pt.K2)((t=>{const e=ht._K.detectInit(t)??{},r=ht._K.detectDirective(t,"wrap");return Array.isArray(r)?e.wrap=r.some((({type:t})=>"wrap"===t)):"wrap"===r?.type&&(e.wrap=!0),{text:(0,ht.vU)(t),directive:e}}),"processDirectives");function fr(t){const e=ur(t),r=dr(e),n=pr(r.text),i=(0,ht.$t)(r.config,n.directive);return{code:t=cr(n.text),title:r.title,config:i}}function gr(t){const e=(new TextEncoder).encode(t),r=Array.from(e,(t=>String.fromCodePoint(t))).join("");return btoa(r)}(0,pt.K2)(fr,"preprocessDiagram"),(0,pt.K2)(gr,"toBase64");var mr=["foreignobject"],yr=["dominant-baseline"];function xr(t){const e=fr(t);return(0,pt.cL)(),(0,pt.xA)(e.config??{}),e}async function br(t,e){er();try{const{code:e,config:r}=xr(t);return{diagramType:(await Lr(e)).type,config:r}}catch(r){if(e?.suppressErrors)return!1;throw r}}(0,pt.K2)(xr,"processAndSetConfigs"),(0,pt.K2)(br,"parse");var kr=(0,pt.K2)(((t,e,r=[])=>`\n.${t} ${e} { ${r.join(" !important; ")} !important; }`),"cssImportantStyles"),Cr=(0,pt.K2)(((t,e=new Map)=>{let r="";if(void 0!==t.themeCSS&&(r+=`\n${t.themeCSS}`),void 0!==t.fontFamily&&(r+=`\n:root { --mermaid-font-family: ${t.fontFamily}}`),void 0!==t.altFontFamily&&(r+=`\n:root { --mermaid-alt-font-family: ${t.altFontFamily}}`),e instanceof Map){const n=t.htmlLabels??t.flowchart?.htmlLabels?["> *","span"]:["rect","polygon","ellipse","circle","path"];e.forEach((t=>{(0,ne.A)(t.styles)||n.forEach((e=>{r+=kr(t.id,e,t.styles)})),(0,ne.A)(t.textStyles)||(r+=kr(t.id,"tspan",(t?.textStyles||[]).map((t=>t.replace("color","fill")))))}))}return r}),"createCssStyles"),wr=(0,pt.K2)(((t,e,r,n)=>{const i=Cr(t,r);return Mt(Xt(`${n}{${(0,pt.tM)(e,i,t.themeVariables)}}`),Bt)}),"createUserStyles"),_r=(0,pt.K2)(((t="",e,r)=>{let n=t;return r||e||(n=n.replace(/marker-end="url\([\d+./:=?A-Za-z-]*?#/g,'marker-end="url(#')),n=(0,ht.Sm)(n),n=n.replace(/<br>/g,"<br/>"),n}),"cleanUpSvgCode"),vr=(0,pt.K2)(((t="",e)=>`<iframe style="width:100%;height:${e?.viewBox?.baseVal?.height?e.viewBox.baseVal.height+"px":"100%"};border:0;margin:0;" src="data:text/html;charset=UTF-8;base64,${gr(`<body style="margin:0">${t}</body>`)}" sandbox="allow-top-navigation-by-user-activation allow-popups">\n The "iframe" tag is not supported by your browser.\n</iframe>`),"putIntoIFrame"),Sr=(0,pt.K2)(((t,e,r,n,i)=>{const a=t.append("div");a.attr("id",r),n&&a.attr("style",n);const o=a.append("svg").attr("id",e).attr("width","100%").attr("xmlns","http://www.w3.org/2000/svg");return i&&o.attr("xmlns:xlink",i),o.append("g"),t}),"appendDivSvgG");function Ar(t,e){return t.append("iframe").attr("id",e).attr("style","width: 100%; height: 100%;").attr("sandbox","")}(0,pt.K2)(Ar,"sandboxedIframe");var Tr=(0,pt.K2)(((t,e,r,n)=>{t.getElementById(e)?.remove(),t.getElementById(r)?.remove(),t.getElementById(n)?.remove()}),"removeExistingElements"),Mr=(0,pt.K2)((async function(t,e,r){er();const n=xr(e);e=n.code;const i=(0,pt.zj)();pt.Rm.debug(i),e.length>(i?.maxTextSize??5e4)&&(e="graph TB;a[Maximum text size in diagram exceeded];style a fill:#faa");const a="#"+t,o="i"+t,s="#"+o,l="d"+t,c="#"+l,h=(0,pt.K2)((()=>{const t=d?s:c,e=(0,gt.Ltv)(t).node();e&&"remove"in e&&e.remove()}),"removeTempElements");let u=(0,gt.Ltv)("body");const d="sandbox"===i.securityLevel,p="loose"===i.securityLevel,f=i.fontFamily;if(void 0!==r){if(r&&(r.innerHTML=""),d){const t=Ar((0,gt.Ltv)(r),o);u=(0,gt.Ltv)(t.nodes()[0].contentDocument.body),u.node().style.margin=0}else u=(0,gt.Ltv)(r);Sr(u,t,l,`font-family: ${f}`,"http://www.w3.org/1999/xlink")}else{if(Tr(document,t,l,o),d){const t=Ar((0,gt.Ltv)("body"),o);u=(0,gt.Ltv)(t.nodes()[0].contentDocument.body),u.node().style.margin=0}else u=(0,gt.Ltv)("body");Sr(u,t,l)}let g,m;try{g=await or.fromText(e,{title:n.title})}catch(M){if(i.suppressErrorRendering)throw h(),M;g=await or.fromText("error"),m=M}const y=u.select(c).node(),x=g.type,b=y.firstChild,k=b.firstChild,C=g.renderer.getClasses?.(e,g),w=wr(i,x,C,a),_=document.createElement("style");_.innerHTML=w,b.insertBefore(_,k);try{await g.renderer.draw(e,t,ut.r,g)}catch(B){throw i.suppressErrorRendering?h():je.draw(e,t,ut.r),B}const v=u.select(`${c} svg`),S=g.db.getAccTitle?.(),A=g.db.getAccDescription?.();Fr(x,v,S,A),u.select(`[id="${t}"]`).selectAll("foreignobject > *").attr("xmlns","http://www.w3.org/1999/xhtml");let T=u.select(c).node().innerHTML;if(pt.Rm.debug("config.arrowMarkerAbsolute",i.arrowMarkerAbsolute),T=_r(T,d,(0,pt._3)(i.arrowMarkerAbsolute)),d){const t=u.select(c+" svg").node();T=vr(T,t)}else p||(T=re.sanitize(T,{ADD_TAGS:mr,ADD_ATTR:yr}));if(lr(),m)throw m;return h(),{diagramType:x,svg:T,bindFunctions:g.db.bindFunctions}}),"render");function Br(t={}){const e=(0,pt.hH)({},t);e?.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables||(e.themeVariables={}),e.themeVariables.fontFamily=e.fontFamily),(0,pt.wZ)(e),e?.theme&&e.theme in pt.H$?e.themeVariables=pt.H$[e.theme].getThemeVariables(e.themeVariables):e&&(e.themeVariables=pt.H$.default.getThemeVariables(e.themeVariables));const r="object"==typeof e?(0,pt.UU)(e):(0,pt.Q2)();(0,pt.He)(r.logLevel),er()}(0,pt.K2)(Br,"initialize");var Lr=(0,pt.K2)(((t,e={})=>{const{code:r}=fr(t);return or.fromText(r,e)}),"getDiagramFromText");function Fr(t,e,r,n){ir(e,t),ar(e,r,n,e.attr("id"))}(0,pt.K2)(Fr,"addA11yInfo");var $r=Object.freeze({render:Mr,parse:br,getDiagramFromText:Lr,initialize:Br,getConfig:pt.zj,setConfig:pt.Nk,getSiteConfig:pt.Q2,updateSiteConfig:pt.B6,reset:(0,pt.K2)((()=>{(0,pt.cL)()}),"reset"),globalReset:(0,pt.K2)((()=>{(0,pt.cL)(pt.sb)}),"globalReset"),defaultConfig:pt.sb});(0,pt.He)((0,pt.zj)().logLevel),(0,pt.cL)((0,pt.zj)());var Er=(0,pt.K2)(((t,e,r)=>{pt.Rm.warn(t),(0,ht.dq)(t)?(r&&r(t.str,t.hash),e.push({...t,message:t.str,error:t})):(r&&r(t),t instanceof Error&&e.push({str:t.message,message:t.message,hash:t.name,error:t}))}),"handleError"),Nr=(0,pt.K2)((async function(t={querySelector:".mermaid"}){try{await Dr(t)}catch(e){if((0,ht.dq)(e)&&pt.Rm.error(e.str),Ur.parseError&&Ur.parseError(e),!t.suppressErrors)throw pt.Rm.error("Use the suppressErrors option to suppress these errors"),e}}),"run"),Dr=(0,pt.K2)((async function({postRenderCallback:t,querySelector:e,nodes:r}={querySelector:".mermaid"}){const n=$r.getConfig();let i;if(pt.Rm.debug((t?"":"No ")+"Callback function found"),r)i=r;else{if(!e)throw new Error("Nodes and querySelector are both undefined");i=document.querySelectorAll(e)}pt.Rm.debug(`Found ${i.length} diagrams`),void 0!==n?.startOnLoad&&(pt.Rm.debug("Start On Load: "+n?.startOnLoad),$r.updateSiteConfig({startOnLoad:n?.startOnLoad}));const a=new ht._K.InitIDGenerator(n.deterministicIds,n.deterministicIDSeed);let o;const s=[];for(const c of Array.from(i)){if(pt.Rm.info("Rendering diagram: "+c.id),c.getAttribute("data-processed"))continue;c.setAttribute("data-processed","true");const e=`mermaid-${a.next()}`;o=c.innerHTML,o=(0,ft.T)(ht._K.entityDecode(o)).trim().replace(/<br\s*\/?>/gi,"<br/>");const r=ht._K.detectInit(o);r&&pt.Rm.debug("Detected early reinit: ",r);try{const{svg:r,bindFunctions:n}=await Hr(e,o,c);c.innerHTML=r,t&&await t(e),n&&n(c)}catch(l){Er(l,s,Ur.parseError)}}if(s.length>0)throw s[0]}),"runThrowsErrors"),jr=(0,pt.K2)((function(t){$r.initialize(t)}),"initialize"),Ir=(0,pt.K2)((async function(t,e,r){pt.Rm.warn("mermaid.init is deprecated. Please use run instead."),t&&jr(t);const n={postRenderCallback:r,querySelector:".mermaid"};"string"==typeof e?n.querySelector=e:e&&(e instanceof HTMLElement?n.nodes=[e]:n.nodes=e),await Nr(n)}),"init"),Or=(0,pt.K2)((async(t,{lazyLoad:e=!0}={})=>{er(),(0,pt.Xd)(...t),!1===e&&await rr()}),"registerExternalDiagrams"),Rr=(0,pt.K2)((function(){if(Ur.startOnLoad){const{startOnLoad:t}=$r.getConfig();t&&Ur.run().catch((t=>pt.Rm.error("Mermaid failed to initialize",t)))}}),"contentLoaded");"undefined"!=typeof document&&window.addEventListener("load",Rr,!1);var Pr=(0,pt.K2)((function(t){Ur.parseError=t}),"setParseErrorHandler"),zr=[],Kr=!1,qr=(0,pt.K2)((async()=>{if(!Kr){for(Kr=!0;zr.length>0;){const e=zr.shift();if(e)try{await e()}catch(t){pt.Rm.error("Error executing queue",t)}}Kr=!1}}),"executeQueue"),Wr=(0,pt.K2)((async(t,e)=>new Promise(((r,n)=>{const i=(0,pt.K2)((()=>new Promise(((i,a)=>{$r.parse(t,e).then((t=>{i(t),r(t)}),(t=>{pt.Rm.error("Error parsing",t),Ur.parseError?.(t),a(t),n(t)}))}))),"performCall");zr.push(i),qr().catch(n)}))),"parse"),Hr=(0,pt.K2)(((t,e,r)=>new Promise(((n,i)=>{const a=(0,pt.K2)((()=>new Promise(((a,o)=>{$r.render(t,e,r).then((t=>{a(t),n(t)}),(t=>{pt.Rm.error("Error parsing",t),Ur.parseError?.(t),o(t),i(t)}))}))),"performCall");zr.push(a),qr().catch(i)}))),"render"),Ur={startOnLoad:!0,mermaidAPI:$r,parse:Wr,render:Hr,init:Ir,run:Nr,registerExternalDiagrams:Or,registerLayoutLoaders:lt.sO,initialize:jr,parseError:void 0,contentLoaded:Rr,setParseErrorHandler:Pr,detectType:pt.Ch,registerIconPacks:ct.pC},Yr=Ur;const Vr="docusaurus-mermaid-container";function Gr(){const{colorMode:t}=(0,s.G)(),e=(0,l.p)().mermaid,r=e.theme[t],{options:i}=e;return(0,n.useMemo)((()=>({startOnLoad:!1,...i,theme:r})),[r,i])}function Zr(t){let{text:e,config:r}=t;const[i,a]=(0,n.useState)(null),o=(0,n.useRef)(`mermaid-svg-${Math.round(1e7*Math.random())}`).current,s=Gr(),l=r??s;return(0,n.useEffect)((()=>{(async function(t){let{id:e,text:r,config:n}=t;Yr.mermaidAPI.initialize(n);try{return await Yr.render(e,r)}catch(i){throw document.querySelector(`#d${e}`)?.remove(),i}})({id:o,text:e,config:l}).then(a).catch((t=>{a((()=>{throw t}))}))}),[o,e,l]),i}const Xr={container:"container_lyt7"};function Qr(t){let{renderResult:e}=t;const r=(0,n.useRef)(null);return(0,n.useEffect)((()=>{const t=r.current;e.bindFunctions?.(t)}),[e]),(0,C.jsx)("div",{ref:r,className:`${Vr} ${Xr.container}`,dangerouslySetInnerHTML:{__html:e.svg}})}function Jr(t){let{value:e}=t;const r=Zr({text:e});return null===r?null:(0,C.jsx)(Qr,{renderResult:r})}const tn={Head:i.A,details:Q,Details:Q,code:function(t){return function(t){return void 0!==t.children&&n.Children.toArray(t.children).every((t=>"string"==typeof t&&!t.includes("\n")))}(t)?(0,C.jsx)(z,{...t}):(0,C.jsx)(P,{...t})},a:function(t){return(0,C.jsx)(K.A,{...t})},pre:function(t){return(0,C.jsx)(C.Fragment,{children:t.children})},ul:function(t){return(0,C.jsx)("ul",{...t,className:rt(t.className)})},li:function(t){return(0,q.A)().collectAnchor(t.id),(0,C.jsx)("li",{...t})},img:function(t){return(0,C.jsx)("img",{decoding:"async",loading:"lazy",...t,className:(e=t.className,(0,o.A)(e,nt.img))});var e},h1:t=>(0,C.jsx)(tt,{as:"h1",...t}),h2:t=>(0,C.jsx)(tt,{as:"h2",...t}),h3:t=>(0,C.jsx)(tt,{as:"h3",...t}),h4:t=>(0,C.jsx)(tt,{as:"h4",...t}),h5:t=>(0,C.jsx)(tt,{as:"h5",...t}),h6:t=>(0,C.jsx)(tt,{as:"h6",...t}),admonition:it.A,mermaid:function(t){return(0,C.jsx)(at.A,{fallback:t=>(0,C.jsx)(ot.MN,{...t}),children:(0,C.jsx)(Jr,{...t})})}}},76487:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});r(96540);var n=r(34164);const i={tabItem:"tabItem_Ymn6"};var a=r(74848);function o(t){let{children:e,hidden:r,className:o}=t;return(0,a.jsx)("div",{role:"tabpanel",className:(0,n.A)(i.tabItem,o),hidden:r,children:e})}},87119:(t,e,r)=>{"use strict";r.d(e,{A:()=>w});var n=r(96540),i=r(34164),a=r(53622),o=r(56347),s=r(68963),l=r(9579),c=r(52808),h=r(45054);function u(t){return n.Children.toArray(t).filter((t=>"\n"!==t)).map((t=>{if(!t||(0,n.isValidElement)(t)&&function(t){const{props:e}=t;return!!e&&"object"==typeof e&&"value"in e}(t))return t;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof t.type?t.type:t.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function d(t){const{values:e,children:r}=t;return(0,n.useMemo)((()=>{const t=e??function(t){return u(t).map((t=>{let{props:{value:e,label:r,attributes:n,default:i}}=t;return{value:e,label:r,attributes:n,default:i}}))}(r);return function(t){const e=(0,c.XI)(t,((t,e)=>t.value===e.value));if(e.length>0)throw new Error(`Docusaurus error: Duplicate values "${e.map((t=>t.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(t),t}),[e,r])}function p(t){let{value:e,tabValues:r}=t;return r.some((t=>t.value===e))}function f(t){let{queryString:e=!1,groupId:r}=t;const i=(0,o.W6)(),a=function(t){let{queryString:e=!1,groupId:r}=t;if("string"==typeof e)return e;if(!1===e)return null;if(!0===e&&!r)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return r??null}({queryString:e,groupId:r});return[(0,l.aZ)(a),(0,n.useCallback)((t=>{if(!a)return;const e=new URLSearchParams(i.location.search);e.set(a,t),i.replace({...i.location,search:e.toString()})}),[a,i])]}function g(t){const{defaultValue:e,queryString:r=!1,groupId:i}=t,a=d(t),[o,l]=(0,n.useState)((()=>function(t){let{defaultValue:e,tabValues:r}=t;if(0===r.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(e){if(!p({value:e,tabValues:r}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${e}" but none of its children has the corresponding value. Available values are: ${r.map((t=>t.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return e}const n=r.find((t=>t.default))??r[0];if(!n)throw new Error("Unexpected error: 0 tabValues");return n.value}({defaultValue:e,tabValues:a}))),[c,u]=f({queryString:r,groupId:i}),[g,m]=function(t){let{groupId:e}=t;const r=function(t){return t?`docusaurus.tab.${t}`:null}(e),[i,a]=(0,h.Dv)(r);return[i,(0,n.useCallback)((t=>{r&&a.set(t)}),[r,a])]}({groupId:i}),y=(()=>{const t=c??g;return p({value:t,tabValues:a})?t:null})();(0,s.A)((()=>{y&&l(y)}),[y]);return{selectedValue:o,selectValue:(0,n.useCallback)((t=>{if(!p({value:t,tabValues:a}))throw new Error(`Can't select invalid tab value=${t}`);l(t),u(t),m(t)}),[u,m,a]),tabValues:a}}var m=r(94753);const y={tabList:"tabList__CuJ",tabItem:"tabItem_LNqP"};var x=r(74848);function b(t){let{className:e,block:r,selectedValue:n,selectValue:o,tabValues:s}=t;const l=[],{blockElementScrollPositionUntilNextRender:c}=(0,a.a_)(),h=t=>{const e=t.currentTarget,r=l.indexOf(e),i=s[r].value;i!==n&&(c(e),o(i))},u=t=>{let e=null;switch(t.key){case"Enter":h(t);break;case"ArrowRight":{const r=l.indexOf(t.currentTarget)+1;e=l[r]??l[0];break}case"ArrowLeft":{const r=l.indexOf(t.currentTarget)-1;e=l[r]??l[l.length-1];break}}e?.focus()};return(0,x.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,i.A)("tabs",{"tabs--block":r},e),children:s.map((t=>{let{value:e,label:r,attributes:a}=t;return(0,x.jsx)("li",{role:"tab",tabIndex:n===e?0:-1,"aria-selected":n===e,ref:t=>l.push(t),onKeyDown:u,onClick:h,...a,className:(0,i.A)("tabs__item",y.tabItem,a?.className,{"tabs__item--active":n===e}),children:r??e},e)}))})}function k(t){let{lazy:e,children:r,selectedValue:a}=t;const o=(Array.isArray(r)?r:[r]).filter(Boolean);if(e){const t=o.find((t=>t.props.value===a));return t?(0,n.cloneElement)(t,{className:(0,i.A)("margin-top--md",t.props.className)}):null}return(0,x.jsx)("div",{className:"margin-top--md",children:o.map(((t,e)=>(0,n.cloneElement)(t,{key:e,hidden:t.props.value!==a})))})}function C(t){const e=g(t);return(0,x.jsxs)("div",{className:(0,i.A)("tabs-container",y.tabList),children:[(0,x.jsx)(b,{...e,...t}),(0,x.jsx)(k,{...e,...t})]})}function w(t){const e=(0,m.A)();return(0,x.jsx)(C,{...t,children:u(t.children)},String(e))}},74353:function(t){t.exports=function(){"use strict";var t=1e3,e=6e4,r=36e5,n="millisecond",i="second",a="minute",o="hour",s="day",l="week",c="month",h="quarter",u="year",d="date",p="Invalid Date",f=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,g=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,m={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],r=t%100;return"["+t+(e[(r-20)%10]||e[r]||e[0])+"]"}},y=function(t,e,r){var n=String(t);return!n||n.length>=e?t:""+Array(e+1-n.length).join(r)+t},x={s:y,z:function(t){var e=-t.utcOffset(),r=Math.abs(e),n=Math.floor(r/60),i=r%60;return(e<=0?"+":"-")+y(n,2,"0")+":"+y(i,2,"0")},m:function t(e,r){if(e.date()<r.date())return-t(r,e);var n=12*(r.year()-e.year())+(r.month()-e.month()),i=e.clone().add(n,c),a=r-i<0,o=e.clone().add(n+(a?-1:1),c);return+(-(n+(r-i)/(a?i-o:o-i))||0)},a:function(t){return t<0?Math.ceil(t)||0:Math.floor(t)},p:function(t){return{M:c,y:u,w:l,d:s,D:d,h:o,m:a,s:i,ms:n,Q:h}[t]||String(t||"").toLowerCase().replace(/s$/,"")},u:function(t){return void 0===t}},b="en",k={};k[b]=m;var C="$isDayjsObject",w=function(t){return t instanceof A||!(!t||!t[C])},_=function t(e,r,n){var i;if(!e)return b;if("string"==typeof e){var a=e.toLowerCase();k[a]&&(i=a),r&&(k[a]=r,i=a);var o=e.split("-");if(!i&&o.length>1)return t(o[0])}else{var s=e.name;k[s]=e,i=s}return!n&&i&&(b=i),i||!n&&b},v=function(t,e){if(w(t))return t.clone();var r="object"==typeof e?e:{};return r.date=t,r.args=arguments,new A(r)},S=x;S.l=_,S.i=w,S.w=function(t,e){return v(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var A=function(){function m(t){this.$L=_(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[C]=!0}var y=m.prototype;return y.parse=function(t){this.$d=function(t){var e=t.date,r=t.utc;if(null===e)return new Date(NaN);if(S.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var n=e.match(f);if(n){var i=n[2]-1||0,a=(n[7]||"0").substring(0,3);return r?new Date(Date.UTC(n[1],i,n[3]||1,n[4]||0,n[5]||0,n[6]||0,a)):new Date(n[1],i,n[3]||1,n[4]||0,n[5]||0,n[6]||0,a)}}return new Date(e)}(t),this.init()},y.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},y.$utils=function(){return S},y.isValid=function(){return!(this.$d.toString()===p)},y.isSame=function(t,e){var r=v(t);return this.startOf(e)<=r&&r<=this.endOf(e)},y.isAfter=function(t,e){return v(t)<this.startOf(e)},y.isBefore=function(t,e){return this.endOf(e)<v(t)},y.$g=function(t,e,r){return S.u(t)?this[e]:this.set(r,t)},y.unix=function(){return Math.floor(this.valueOf()/1e3)},y.valueOf=function(){return this.$d.getTime()},y.startOf=function(t,e){var r=this,n=!!S.u(e)||e,h=S.p(t),p=function(t,e){var i=S.w(r.$u?Date.UTC(r.$y,e,t):new Date(r.$y,e,t),r);return n?i:i.endOf(s)},f=function(t,e){return S.w(r.toDate()[t].apply(r.toDate("s"),(n?[0,0,0,0]:[23,59,59,999]).slice(e)),r)},g=this.$W,m=this.$M,y=this.$D,x="set"+(this.$u?"UTC":"");switch(h){case u:return n?p(1,0):p(31,11);case c:return n?p(1,m):p(0,m+1);case l:var b=this.$locale().weekStart||0,k=(g<b?g+7:g)-b;return p(n?y-k:y+(6-k),m);case s:case d:return f(x+"Hours",0);case o:return f(x+"Minutes",1);case a:return f(x+"Seconds",2);case i:return f(x+"Milliseconds",3);default:return this.clone()}},y.endOf=function(t){return this.startOf(t,!1)},y.$set=function(t,e){var r,l=S.p(t),h="set"+(this.$u?"UTC":""),p=(r={},r[s]=h+"Date",r[d]=h+"Date",r[c]=h+"Month",r[u]=h+"FullYear",r[o]=h+"Hours",r[a]=h+"Minutes",r[i]=h+"Seconds",r[n]=h+"Milliseconds",r)[l],f=l===s?this.$D+(e-this.$W):e;if(l===c||l===u){var g=this.clone().set(d,1);g.$d[p](f),g.init(),this.$d=g.set(d,Math.min(this.$D,g.daysInMonth())).$d}else p&&this.$d[p](f);return this.init(),this},y.set=function(t,e){return this.clone().$set(t,e)},y.get=function(t){return this[S.p(t)]()},y.add=function(n,h){var d,p=this;n=Number(n);var f=S.p(h),g=function(t){var e=v(p);return S.w(e.date(e.date()+Math.round(t*n)),p)};if(f===c)return this.set(c,this.$M+n);if(f===u)return this.set(u,this.$y+n);if(f===s)return g(1);if(f===l)return g(7);var m=(d={},d[a]=e,d[o]=r,d[i]=t,d)[f]||1,y=this.$d.getTime()+n*m;return S.w(y,this)},y.subtract=function(t,e){return this.add(-1*t,e)},y.format=function(t){var e=this,r=this.$locale();if(!this.isValid())return r.invalidDate||p;var n=t||"YYYY-MM-DDTHH:mm:ssZ",i=S.z(this),a=this.$H,o=this.$m,s=this.$M,l=r.weekdays,c=r.months,h=r.meridiem,u=function(t,r,i,a){return t&&(t[r]||t(e,n))||i[r].slice(0,a)},d=function(t){return S.s(a%12||12,t,"0")},f=h||function(t,e,r){var n=t<12?"AM":"PM";return r?n.toLowerCase():n};return n.replace(g,(function(t,n){return n||function(t){switch(t){case"YY":return String(e.$y).slice(-2);case"YYYY":return S.s(e.$y,4,"0");case"M":return s+1;case"MM":return S.s(s+1,2,"0");case"MMM":return u(r.monthsShort,s,c,3);case"MMMM":return u(c,s);case"D":return e.$D;case"DD":return S.s(e.$D,2,"0");case"d":return String(e.$W);case"dd":return u(r.weekdaysMin,e.$W,l,2);case"ddd":return u(r.weekdaysShort,e.$W,l,3);case"dddd":return l[e.$W];case"H":return String(a);case"HH":return S.s(a,2,"0");case"h":return d(1);case"hh":return d(2);case"a":return f(a,o,!0);case"A":return f(a,o,!1);case"m":return String(o);case"mm":return S.s(o,2,"0");case"s":return String(e.$s);case"ss":return S.s(e.$s,2,"0");case"SSS":return S.s(e.$ms,3,"0");case"Z":return i}return null}(t)||i.replace(":","")}))},y.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},y.diff=function(n,d,p){var f,g=this,m=S.p(d),y=v(n),x=(y.utcOffset()-this.utcOffset())*e,b=this-y,k=function(){return S.m(g,y)};switch(m){case u:f=k()/12;break;case c:f=k();break;case h:f=k()/3;break;case l:f=(b-x)/6048e5;break;case s:f=(b-x)/864e5;break;case o:f=b/r;break;case a:f=b/e;break;case i:f=b/t;break;default:f=b}return p?f:S.a(f)},y.daysInMonth=function(){return this.endOf(c).$D},y.$locale=function(){return k[this.$L]},y.locale=function(t,e){if(!t)return this.$L;var r=this.clone(),n=_(t,e,!0);return n&&(r.$L=n),r},y.clone=function(){return S.w(this.$d,this)},y.toDate=function(){return new Date(this.valueOf())},y.toJSON=function(){return this.isValid()?this.toISOString():null},y.toISOString=function(){return this.$d.toISOString()},y.toString=function(){return this.$d.toUTCString()},m}(),T=A.prototype;return v.prototype=T,[["$ms",n],["$s",i],["$m",a],["$H",o],["$W",s],["$M",c],["$y",u],["$D",d]].forEach((function(t){T[t[1]]=function(e){return this.$g(e,t[0],t[1])}})),v.extend=function(t,e){return t.$i||(t(e,A,v),t.$i=!0),v},v.locale=_,v.isDayjs=w,v.unix=function(t){return v(1e3*t)},v.en=k[b],v.Ls=k,v.p={},v}()},42838:function(t){t.exports=function(){"use strict";const{entries:t,setPrototypeOf:e,isFrozen:r,getPrototypeOf:n,getOwnPropertyDescriptor:i}=Object;let{freeze:a,seal:o,create:s}=Object,{apply:l,construct:c}="undefined"!=typeof Reflect&&Reflect;a||(a=function(t){return t}),o||(o=function(t){return t}),l||(l=function(t,e,r){return t.apply(e,r)}),c||(c=function(t,e){return new t(...e)});const h=w(Array.prototype.forEach),u=w(Array.prototype.pop),d=w(Array.prototype.push),p=w(String.prototype.toLowerCase),f=w(String.prototype.toString),g=w(String.prototype.match),m=w(String.prototype.replace),y=w(String.prototype.indexOf),x=w(String.prototype.trim),b=w(Object.prototype.hasOwnProperty),k=w(RegExp.prototype.test),C=_(TypeError);function w(t){return function(e){for(var r=arguments.length,n=new Array(r>1?r-1:0),i=1;i<r;i++)n[i-1]=arguments[i];return l(t,e,n)}}function _(t){return function(){for(var e=arguments.length,r=new Array(e),n=0;n<e;n++)r[n]=arguments[n];return c(t,r)}}function v(t,n){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:p;e&&e(t,null);let a=n.length;for(;a--;){let e=n[a];if("string"==typeof e){const t=i(e);t!==e&&(r(n)||(n[a]=t),e=t)}t[e]=!0}return t}function S(t){for(let e=0;e<t.length;e++)b(t,e)||(t[e]=null);return t}function A(e){const r=s(null);for(const[n,i]of t(e))b(e,n)&&(Array.isArray(i)?r[n]=S(i):i&&"object"==typeof i&&i.constructor===Object?r[n]=A(i):r[n]=i);return r}function T(t,e){for(;null!==t;){const r=i(t,e);if(r){if(r.get)return w(r.get);if("function"==typeof r.value)return w(r.value)}t=n(t)}function r(){return null}return r}const M=a(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),B=a(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),L=a(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),F=a(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),$=a(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),E=a(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),N=a(["#text"]),D=a(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),j=a(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),I=a(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),O=a(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),R=o(/\{\{[\w\W]*|[\w\W]*\}\}/gm),P=o(/<%[\w\W]*|[\w\W]*%>/gm),z=o(/\${[\w\W]*}/gm),K=o(/^data-[\-\w.\u00B7-\uFFFF]/),q=o(/^aria-[\-\w]+$/),W=o(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),H=o(/^(?:\w+script|data):/i),U=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Y=o(/^html$/i),V=o(/^[a-z][.\w]*(-[.\w]+)+$/i);var G=Object.freeze({__proto__:null,MUSTACHE_EXPR:R,ERB_EXPR:P,TMPLIT_EXPR:z,DATA_ATTR:K,ARIA_ATTR:q,IS_ALLOWED_URI:W,IS_SCRIPT_OR_DATA:H,ATTR_WHITESPACE:U,DOCTYPE_NAME:Y,CUSTOM_ELEMENT:V});const Z={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,progressingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},X=function(){return"undefined"==typeof window?null:window},Q=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let r=null;const n="data-tt-policy-suffix";e&&e.hasAttribute(n)&&(r=e.getAttribute(n));const i="dompurify"+(r?"#"+r:"");try{return t.createPolicy(i,{createHTML:t=>t,createScriptURL:t=>t})}catch(a){return console.warn("TrustedTypes policy "+i+" could not be created."),null}};function J(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:X();const r=t=>J(t);if(r.version="3.1.6",r.removed=[],!e||!e.document||e.document.nodeType!==Z.document)return r.isSupported=!1,r;let{document:n}=e;const i=n,o=i.currentScript,{DocumentFragment:l,HTMLTemplateElement:c,Node:w,Element:_,NodeFilter:S,NamedNodeMap:R=e.NamedNodeMap||e.MozNamedAttrMap,HTMLFormElement:P,DOMParser:z,trustedTypes:K}=e,q=_.prototype,H=T(q,"cloneNode"),U=T(q,"remove"),V=T(q,"nextSibling"),tt=T(q,"childNodes"),et=T(q,"parentNode");if("function"==typeof c){const t=n.createElement("template");t.content&&t.content.ownerDocument&&(n=t.content.ownerDocument)}let rt,nt="";const{implementation:it,createNodeIterator:at,createDocumentFragment:ot,getElementsByTagName:st}=n,{importNode:lt}=i;let ct={};r.isSupported="function"==typeof t&&"function"==typeof et&&it&&void 0!==it.createHTMLDocument;const{MUSTACHE_EXPR:ht,ERB_EXPR:ut,TMPLIT_EXPR:dt,DATA_ATTR:pt,ARIA_ATTR:ft,IS_SCRIPT_OR_DATA:gt,ATTR_WHITESPACE:mt,CUSTOM_ELEMENT:yt}=G;let{IS_ALLOWED_URI:xt}=G,bt=null;const kt=v({},[...M,...B,...L,...$,...N]);let Ct=null;const wt=v({},[...D,...j,...I,...O]);let _t=Object.seal(s(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),vt=null,St=null,At=!0,Tt=!0,Mt=!1,Bt=!0,Lt=!1,Ft=!0,$t=!1,Et=!1,Nt=!1,Dt=!1,jt=!1,It=!1,Ot=!0,Rt=!1;const Pt="user-content-";let zt=!0,Kt=!1,qt={},Wt=null;const Ht=v({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Ut=null;const Yt=v({},["audio","video","img","source","image","track"]);let Vt=null;const Gt=v({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Zt="http://www.w3.org/1998/Math/MathML",Xt="http://www.w3.org/2000/svg",Qt="http://www.w3.org/1999/xhtml";let Jt=Qt,te=!1,ee=null;const re=v({},[Zt,Xt,Qt],f);let ne=null;const ie=["application/xhtml+xml","text/html"],ae="text/html";let oe=null,se=null;const le=n.createElement("form"),ce=function(t){return t instanceof RegExp||t instanceof Function},he=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!se||se!==t){if(t&&"object"==typeof t||(t={}),t=A(t),ne=-1===ie.indexOf(t.PARSER_MEDIA_TYPE)?ae:t.PARSER_MEDIA_TYPE,oe="application/xhtml+xml"===ne?f:p,bt=b(t,"ALLOWED_TAGS")?v({},t.ALLOWED_TAGS,oe):kt,Ct=b(t,"ALLOWED_ATTR")?v({},t.ALLOWED_ATTR,oe):wt,ee=b(t,"ALLOWED_NAMESPACES")?v({},t.ALLOWED_NAMESPACES,f):re,Vt=b(t,"ADD_URI_SAFE_ATTR")?v(A(Gt),t.ADD_URI_SAFE_ATTR,oe):Gt,Ut=b(t,"ADD_DATA_URI_TAGS")?v(A(Yt),t.ADD_DATA_URI_TAGS,oe):Yt,Wt=b(t,"FORBID_CONTENTS")?v({},t.FORBID_CONTENTS,oe):Ht,vt=b(t,"FORBID_TAGS")?v({},t.FORBID_TAGS,oe):{},St=b(t,"FORBID_ATTR")?v({},t.FORBID_ATTR,oe):{},qt=!!b(t,"USE_PROFILES")&&t.USE_PROFILES,At=!1!==t.ALLOW_ARIA_ATTR,Tt=!1!==t.ALLOW_DATA_ATTR,Mt=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Bt=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Lt=t.SAFE_FOR_TEMPLATES||!1,Ft=!1!==t.SAFE_FOR_XML,$t=t.WHOLE_DOCUMENT||!1,Dt=t.RETURN_DOM||!1,jt=t.RETURN_DOM_FRAGMENT||!1,It=t.RETURN_TRUSTED_TYPE||!1,Nt=t.FORCE_BODY||!1,Ot=!1!==t.SANITIZE_DOM,Rt=t.SANITIZE_NAMED_PROPS||!1,zt=!1!==t.KEEP_CONTENT,Kt=t.IN_PLACE||!1,xt=t.ALLOWED_URI_REGEXP||W,Jt=t.NAMESPACE||Qt,_t=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&ce(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(_t.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ce(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(_t.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(_t.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Lt&&(Tt=!1),jt&&(Dt=!0),qt&&(bt=v({},N),Ct=[],!0===qt.html&&(v(bt,M),v(Ct,D)),!0===qt.svg&&(v(bt,B),v(Ct,j),v(Ct,O)),!0===qt.svgFilters&&(v(bt,L),v(Ct,j),v(Ct,O)),!0===qt.mathMl&&(v(bt,$),v(Ct,I),v(Ct,O))),t.ADD_TAGS&&(bt===kt&&(bt=A(bt)),v(bt,t.ADD_TAGS,oe)),t.ADD_ATTR&&(Ct===wt&&(Ct=A(Ct)),v(Ct,t.ADD_ATTR,oe)),t.ADD_URI_SAFE_ATTR&&v(Vt,t.ADD_URI_SAFE_ATTR,oe),t.FORBID_CONTENTS&&(Wt===Ht&&(Wt=A(Wt)),v(Wt,t.FORBID_CONTENTS,oe)),zt&&(bt["#text"]=!0),$t&&v(bt,["html","head","body"]),bt.table&&(v(bt,["tbody"]),delete vt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw C('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw C('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');rt=t.TRUSTED_TYPES_POLICY,nt=rt.createHTML("")}else void 0===rt&&(rt=Q(K,o)),null!==rt&&"string"==typeof nt&&(nt=rt.createHTML(""));a&&a(t),se=t}},ue=v({},["mi","mo","mn","ms","mtext"]),de=v({},["foreignobject","annotation-xml"]),pe=v({},["title","style","font","a","script"]),fe=v({},[...B,...L,...F]),ge=v({},[...$,...E]),me=function(t){let e=et(t);e&&e.tagName||(e={namespaceURI:Jt,tagName:"template"});const r=p(t.tagName),n=p(e.tagName);return!!ee[t.namespaceURI]&&(t.namespaceURI===Xt?e.namespaceURI===Qt?"svg"===r:e.namespaceURI===Zt?"svg"===r&&("annotation-xml"===n||ue[n]):Boolean(fe[r]):t.namespaceURI===Zt?e.namespaceURI===Qt?"math"===r:e.namespaceURI===Xt?"math"===r&&de[n]:Boolean(ge[r]):t.namespaceURI===Qt?!(e.namespaceURI===Xt&&!de[n])&&!(e.namespaceURI===Zt&&!ue[n])&&!ge[r]&&(pe[r]||!fe[r]):!("application/xhtml+xml"!==ne||!ee[t.namespaceURI]))},ye=function(t){d(r.removed,{element:t});try{et(t).removeChild(t)}catch(e){U(t)}},xe=function(t,e){try{d(r.removed,{attribute:e.getAttributeNode(t),from:e})}catch(n){d(r.removed,{attribute:null,from:e})}if(e.removeAttribute(t),"is"===t&&!Ct[t])if(Dt||jt)try{ye(e)}catch(n){}else try{e.setAttribute(t,"")}catch(n){}},be=function(t){let e=null,r=null;if(Nt)t="<remove></remove>"+t;else{const e=g(t,/^[\r\n\t ]+/);r=e&&e[0]}"application/xhtml+xml"===ne&&Jt===Qt&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const i=rt?rt.createHTML(t):t;if(Jt===Qt)try{e=(new z).parseFromString(i,ne)}catch(o){}if(!e||!e.documentElement){e=it.createDocument(Jt,"template",null);try{e.documentElement.innerHTML=te?nt:i}catch(o){}}const a=e.body||e.documentElement;return t&&r&&a.insertBefore(n.createTextNode(r),a.childNodes[0]||null),Jt===Qt?st.call(e,$t?"html":"body")[0]:$t?e.documentElement:a},ke=function(t){return at.call(t.ownerDocument||t,t,S.SHOW_ELEMENT|S.SHOW_COMMENT|S.SHOW_TEXT|S.SHOW_PROCESSING_INSTRUCTION|S.SHOW_CDATA_SECTION,null)},Ce=function(t){return t instanceof P&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof R)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes)},we=function(t){return"function"==typeof w&&t instanceof w},_e=function(t,e,n){ct[t]&&h(ct[t],(t=>{t.call(r,e,n,se)}))},ve=function(t){let e=null;if(_e("beforeSanitizeElements",t,null),Ce(t))return ye(t),!0;const n=oe(t.nodeName);if(_e("uponSanitizeElement",t,{tagName:n,allowedTags:bt}),t.hasChildNodes()&&!we(t.firstElementChild)&&k(/<[/\w]/g,t.innerHTML)&&k(/<[/\w]/g,t.textContent))return ye(t),!0;if(t.nodeType===Z.progressingInstruction)return ye(t),!0;if(Ft&&t.nodeType===Z.comment&&k(/<[/\w]/g,t.data))return ye(t),!0;if(!bt[n]||vt[n]){if(!vt[n]&&Ae(n)){if(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,n))return!1;if(_t.tagNameCheck instanceof Function&&_t.tagNameCheck(n))return!1}if(zt&&!Wt[n]){const e=et(t)||t.parentNode,r=tt(t)||t.childNodes;if(r&&e)for(let n=r.length-1;n>=0;--n){const i=H(r[n],!0);i.__removalCount=(t.__removalCount||0)+1,e.insertBefore(i,V(t))}}return ye(t),!0}return t instanceof _&&!me(t)?(ye(t),!0):"noscript"!==n&&"noembed"!==n&&"noframes"!==n||!k(/<\/no(script|embed|frames)/i,t.innerHTML)?(Lt&&t.nodeType===Z.text&&(e=t.textContent,h([ht,ut,dt],(t=>{e=m(e,t," ")})),t.textContent!==e&&(d(r.removed,{element:t.cloneNode()}),t.textContent=e)),_e("afterSanitizeElements",t,null),!1):(ye(t),!0)},Se=function(t,e,r){if(Ot&&("id"===e||"name"===e)&&(r in n||r in le))return!1;if(Tt&&!St[e]&&k(pt,e));else if(At&&k(ft,e));else if(!Ct[e]||St[e]){if(!(Ae(t)&&(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,t)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(t))&&(_t.attributeNameCheck instanceof RegExp&&k(_t.attributeNameCheck,e)||_t.attributeNameCheck instanceof Function&&_t.attributeNameCheck(e))||"is"===e&&_t.allowCustomizedBuiltInElements&&(_t.tagNameCheck instanceof RegExp&&k(_t.tagNameCheck,r)||_t.tagNameCheck instanceof Function&&_t.tagNameCheck(r))))return!1}else if(Vt[e]);else if(k(xt,m(r,mt,"")));else if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==y(r,"data:")||!Ut[t])if(Mt&&!k(gt,m(r,mt,"")));else if(r)return!1;return!0},Ae=function(t){return"annotation-xml"!==t&&g(t,yt)},Te=function(t){_e("beforeSanitizeAttributes",t,null);const{attributes:e}=t;if(!e)return;const n={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Ct};let i=e.length;for(;i--;){const o=e[i],{name:s,namespaceURI:l,value:c}=o,d=oe(s);let p="value"===s?c:x(c);if(n.attrName=d,n.attrValue=p,n.keepAttr=!0,n.forceKeepAttr=void 0,_e("uponSanitizeAttribute",t,n),p=n.attrValue,Ft&&k(/((--!?|])>)|<\/(style|title)/i,p)){xe(s,t);continue}if(n.forceKeepAttr)continue;if(xe(s,t),!n.keepAttr)continue;if(!Bt&&k(/\/>/i,p)){xe(s,t);continue}Lt&&h([ht,ut,dt],(t=>{p=m(p,t," ")}));const f=oe(t.nodeName);if(Se(f,d,p)){if(!Rt||"id"!==d&&"name"!==d||(xe(s,t),p=Pt+p),rt&&"object"==typeof K&&"function"==typeof K.getAttributeType)if(l);else switch(K.getAttributeType(f,d)){case"TrustedHTML":p=rt.createHTML(p);break;case"TrustedScriptURL":p=rt.createScriptURL(p)}try{l?t.setAttributeNS(l,s,p):t.setAttribute(s,p),Ce(t)?ye(t):u(r.removed)}catch(a){}}}_e("afterSanitizeAttributes",t,null)},Me=function t(e){let r=null;const n=ke(e);for(_e("beforeSanitizeShadowDOM",e,null);r=n.nextNode();)_e("uponSanitizeShadowNode",r,null),ve(r)||(r.content instanceof l&&t(r.content),Te(r));_e("afterSanitizeShadowDOM",e,null)};return r.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=null,a=null,o=null,s=null;if(te=!t,te&&(t="\x3c!--\x3e"),"string"!=typeof t&&!we(t)){if("function"!=typeof t.toString)throw C("toString is not a function");if("string"!=typeof(t=t.toString()))throw C("dirty is not a string, aborting")}if(!r.isSupported)return t;if(Et||he(e),r.removed=[],"string"==typeof t&&(Kt=!1),Kt){if(t.nodeName){const e=oe(t.nodeName);if(!bt[e]||vt[e])throw C("root node is forbidden and cannot be sanitized in-place")}}else if(t instanceof w)n=be("\x3c!----\x3e"),a=n.ownerDocument.importNode(t,!0),a.nodeType===Z.element&&"BODY"===a.nodeName||"HTML"===a.nodeName?n=a:n.appendChild(a);else{if(!Dt&&!Lt&&!$t&&-1===t.indexOf("<"))return rt&&It?rt.createHTML(t):t;if(n=be(t),!n)return Dt?null:It?nt:""}n&&Nt&&ye(n.firstChild);const c=ke(Kt?t:n);for(;o=c.nextNode();)ve(o)||(o.content instanceof l&&Me(o.content),Te(o));if(Kt)return t;if(Dt){if(jt)for(s=ot.call(n.ownerDocument);n.firstChild;)s.appendChild(n.firstChild);else s=n;return(Ct.shadowroot||Ct.shadowrootmode)&&(s=lt.call(i,s,!0)),s}let u=$t?n.outerHTML:n.innerHTML;return $t&&bt["!doctype"]&&n.ownerDocument&&n.ownerDocument.doctype&&n.ownerDocument.doctype.name&&k(Y,n.ownerDocument.doctype.name)&&(u="<!DOCTYPE "+n.ownerDocument.doctype.name+">\n"+u),Lt&&h([ht,ut,dt],(t=>{u=m(u,t," ")})),rt&&It?rt.createHTML(u):u},r.setConfig=function(){he(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),Et=!0},r.clearConfig=function(){se=null,Et=!1},r.isValidAttribute=function(t,e,r){se||he({});const n=oe(t),i=oe(e);return Se(n,i,r)},r.addHook=function(t,e){"function"==typeof e&&(ct[t]=ct[t]||[],d(ct[t],e))},r.removeHook=function(t){if(ct[t])return u(ct[t])},r.removeHooks=function(t){ct[t]&&(ct[t]=[])},r.removeAllHooks=function(){ct={}},r}return J()}()},18426:(t,e)=>{function r(t){let e,r=[];for(let n of t.split(",").map((t=>t.trim())))if(/^-?\d+$/.test(n))r.push(parseInt(n,10));else if(e=n.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[t,n,i,a]=e;if(n&&a){n=parseInt(n),a=parseInt(a);const t=n<a?1:-1;"-"!==i&&".."!==i&&"\u2025"!==i||(a+=t);for(let e=n;e!==a;e+=t)r.push(e)}}return r}e.default=r,t.exports=r},29893:(t,e,r)=>{"use strict";function n(t,e,r){if(t&&t.length){const[n,i]=e,a=Math.PI/180*r,o=Math.cos(a),s=Math.sin(a);for(const e of t){const[t,r]=e;e[0]=(t-n)*o-(r-i)*s+n,e[1]=(t-n)*s+(r-i)*o+i}}}function i(t,e){return t[0]===e[0]&&t[1]===e[1]}function a(t,e,r,a=1){const o=r,s=Math.max(e,.1),l=t[0]&&t[0][0]&&"number"==typeof t[0][0]?[t]:t,c=[0,0];if(o)for(const i of l)n(i,c,o);const h=function(t,e,r){const n=[];for(const h of t){const t=[...h];i(t[0],t[t.length-1])||t.push([t[0][0],t[0][1]]),t.length>2&&n.push(t)}const a=[];e=Math.max(e,.1);const o=[];for(const i of n)for(let t=0;t<i.length-1;t++){const e=i[t],r=i[t+1];if(e[1]!==r[1]){const t=Math.min(e[1],r[1]);o.push({ymin:t,ymax:Math.max(e[1],r[1]),x:t===e[1]?e[0]:r[0],islope:(r[0]-e[0])/(r[1]-e[1])})}}if(o.sort(((t,e)=>t.ymin<e.ymin?-1:t.ymin>e.ymin?1:t.x<e.x?-1:t.x>e.x?1:t.ymax===e.ymax?0:(t.ymax-e.ymax)/Math.abs(t.ymax-e.ymax))),!o.length)return a;let s=[],l=o[0].ymin,c=0;for(;s.length||o.length;){if(o.length){let t=-1;for(let e=0;e<o.length&&!(o[e].ymin>l);e++)t=e;o.splice(0,t+1).forEach((t=>{s.push({s:l,edge:t})}))}if(s=s.filter((t=>!(t.edge.ymax<=l))),s.sort(((t,e)=>t.edge.x===e.edge.x?0:(t.edge.x-e.edge.x)/Math.abs(t.edge.x-e.edge.x))),(1!==r||c%e==0)&&s.length>1)for(let t=0;t<s.length;t+=2){const e=t+1;if(e>=s.length)break;const r=s[t].edge,n=s[e].edge;a.push([[Math.round(r.x),l],[Math.round(n.x),l]])}l+=r,s.forEach((t=>{t.edge.x=t.edge.x+r*t.edge.islope})),c++}return a}(l,s,a);if(o){for(const t of l)n(t,c,-o);!function(t,e,r){const i=[];t.forEach((t=>i.push(...t))),n(i,e,r)}(h,c,-o)}return h}function o(t,e){var r;const n=e.hachureAngle+90;let i=e.hachureGap;i<0&&(i=4*e.strokeWidth),i=Math.round(Math.max(i,.1));let o=1;return e.roughness>=1&&((null===(r=e.randomizer)||void 0===r?void 0:r.next())||Math.random())>.7&&(o=i),a(t,i,n,o||1)}r.d(e,{A:()=>st});class s{constructor(t){this.helper=t}fillPolygons(t,e){return this._fillPolygons(t,e)}_fillPolygons(t,e){const r=o(t,e);return{type:"fillSketch",ops:this.renderLines(r,e)}}renderLines(t,e){const r=[];for(const n of t)r.push(...this.helper.doubleLineOps(n[0][0],n[0][1],n[1][0],n[1][1],e));return r}}function l(t){const e=t[0],r=t[1];return Math.sqrt(Math.pow(e[0]-r[0],2)+Math.pow(e[1]-r[1],2))}class c extends s{fillPolygons(t,e){let r=e.hachureGap;r<0&&(r=4*e.strokeWidth),r=Math.max(r,.1);const n=o(t,Object.assign({},e,{hachureGap:r})),i=Math.PI/180*e.hachureAngle,a=[],s=.5*r*Math.cos(i),c=.5*r*Math.sin(i);for(const[o,h]of n)l([o,h])&&a.push([[o[0]-s,o[1]+c],[...h]],[[o[0]+s,o[1]-c],[...h]]);return{type:"fillSketch",ops:this.renderLines(a,e)}}}class h extends s{fillPolygons(t,e){const r=this._fillPolygons(t,e),n=Object.assign({},e,{hachureAngle:e.hachureAngle+90}),i=this._fillPolygons(t,n);return r.ops=r.ops.concat(i.ops),r}}class u{constructor(t){this.helper=t}fillPolygons(t,e){const r=o(t,e=Object.assign({},e,{hachureAngle:0}));return this.dotsOnLines(r,e)}dotsOnLines(t,e){const r=[];let n=e.hachureGap;n<0&&(n=4*e.strokeWidth),n=Math.max(n,.1);let i=e.fillWeight;i<0&&(i=e.strokeWidth/2);const a=n/4;for(const o of t){const t=l(o),s=t/n,c=Math.ceil(s)-1,h=t-c*n,u=(o[0][0]+o[1][0])/2-n/4,d=Math.min(o[0][1],o[1][1]);for(let o=0;o<c;o++){const t=d+h+o*n,s=u-a+2*Math.random()*a,l=t-a+2*Math.random()*a,c=this.helper.ellipse(s,l,i,i,e);r.push(...c.ops)}}return{type:"fillSketch",ops:r}}}class d{constructor(t){this.helper=t}fillPolygons(t,e){const r=o(t,e);return{type:"fillSketch",ops:this.dashedLine(r,e)}}dashedLine(t,e){const r=e.dashOffset<0?e.hachureGap<0?4*e.strokeWidth:e.hachureGap:e.dashOffset,n=e.dashGap<0?e.hachureGap<0?4*e.strokeWidth:e.hachureGap:e.dashGap,i=[];return t.forEach((t=>{const a=l(t),o=Math.floor(a/(r+n)),s=(a+n-o*(r+n))/2;let c=t[0],h=t[1];c[0]>h[0]&&(c=t[1],h=t[0]);const u=Math.atan((h[1]-c[1])/(h[0]-c[0]));for(let l=0;l<o;l++){const t=l*(r+n),a=t+r,o=[c[0]+t*Math.cos(u)+s*Math.cos(u),c[1]+t*Math.sin(u)+s*Math.sin(u)],h=[c[0]+a*Math.cos(u)+s*Math.cos(u),c[1]+a*Math.sin(u)+s*Math.sin(u)];i.push(...this.helper.doubleLineOps(o[0],o[1],h[0],h[1],e))}})),i}}class p{constructor(t){this.helper=t}fillPolygons(t,e){const r=e.hachureGap<0?4*e.strokeWidth:e.hachureGap,n=e.zigzagOffset<0?r:e.zigzagOffset,i=o(t,e=Object.assign({},e,{hachureGap:r+n}));return{type:"fillSketch",ops:this.zigzagLines(i,n,e)}}zigzagLines(t,e,r){const n=[];return t.forEach((t=>{const i=l(t),a=Math.round(i/(2*e));let o=t[0],s=t[1];o[0]>s[0]&&(o=t[1],s=t[0]);const c=Math.atan((s[1]-o[1])/(s[0]-o[0]));for(let l=0;l<a;l++){const t=2*l*e,i=2*(l+1)*e,a=Math.sqrt(2*Math.pow(e,2)),s=[o[0]+t*Math.cos(c),o[1]+t*Math.sin(c)],h=[o[0]+i*Math.cos(c),o[1]+i*Math.sin(c)],u=[s[0]+a*Math.cos(c+Math.PI/4),s[1]+a*Math.sin(c+Math.PI/4)];n.push(...this.helper.doubleLineOps(s[0],s[1],u[0],u[1],r),...this.helper.doubleLineOps(u[0],u[1],h[0],h[1],r))}})),n}}const f={};class g{constructor(t){this.seed=t}next(){return this.seed?(2**31-1&(this.seed=Math.imul(48271,this.seed)))/2**31:Math.random()}}const m=0,y=1,x=2,b={A:7,a:7,C:6,c:6,H:1,h:1,L:2,l:2,M:2,m:2,Q:4,q:4,S:4,s:4,T:2,t:2,V:1,v:1,Z:0,z:0};function k(t,e){return t.type===e}function C(t){const e=[],r=function(t){const e=new Array;for(;""!==t;)if(t.match(/^([ \t\r\n,]+)/))t=t.substr(RegExp.$1.length);else if(t.match(/^([aAcChHlLmMqQsStTvVzZ])/))e[e.length]={type:m,text:RegExp.$1},t=t.substr(RegExp.$1.length);else{if(!t.match(/^(([-+]?[0-9]+(\.[0-9]*)?|[-+]?\.[0-9]+)([eE][-+]?[0-9]+)?)/))return[];e[e.length]={type:y,text:`${parseFloat(RegExp.$1)}`},t=t.substr(RegExp.$1.length)}return e[e.length]={type:x,text:""},e}(t);let n="BOD",i=0,a=r[i];for(;!k(a,x);){let o=0;const s=[];if("BOD"===n){if("M"!==a.text&&"m"!==a.text)return C("M0,0"+t);i++,o=b[a.text],n=a.text}else k(a,y)?o=b[n]:(i++,o=b[a.text],n=a.text);if(!(i+o<r.length))throw new Error("Path data ended short");for(let t=i;t<i+o;t++){const e=r[t];if(!k(e,y))throw new Error("Param not a number: "+n+","+e.text);s[s.length]=+e.text}if("number"!=typeof b[n])throw new Error("Bad segment: "+n);{const t={key:n,data:s};e.push(t),i+=o,a=r[i],"M"===n&&(n="L"),"m"===n&&(n="l")}}return e}function w(t){let e=0,r=0,n=0,i=0;const a=[];for(const{key:o,data:s}of t)switch(o){case"M":a.push({key:"M",data:[...s]}),[e,r]=s,[n,i]=s;break;case"m":e+=s[0],r+=s[1],a.push({key:"M",data:[e,r]}),n=e,i=r;break;case"L":a.push({key:"L",data:[...s]}),[e,r]=s;break;case"l":e+=s[0],r+=s[1],a.push({key:"L",data:[e,r]});break;case"C":a.push({key:"C",data:[...s]}),e=s[4],r=s[5];break;case"c":{const t=s.map(((t,n)=>n%2?t+r:t+e));a.push({key:"C",data:t}),e=t[4],r=t[5];break}case"Q":a.push({key:"Q",data:[...s]}),e=s[2],r=s[3];break;case"q":{const t=s.map(((t,n)=>n%2?t+r:t+e));a.push({key:"Q",data:t}),e=t[2],r=t[3];break}case"A":a.push({key:"A",data:[...s]}),e=s[5],r=s[6];break;case"a":e+=s[5],r+=s[6],a.push({key:"A",data:[s[0],s[1],s[2],s[3],s[4],e,r]});break;case"H":a.push({key:"H",data:[...s]}),e=s[0];break;case"h":e+=s[0],a.push({key:"H",data:[e]});break;case"V":a.push({key:"V",data:[...s]}),r=s[0];break;case"v":r+=s[0],a.push({key:"V",data:[r]});break;case"S":a.push({key:"S",data:[...s]}),e=s[2],r=s[3];break;case"s":{const t=s.map(((t,n)=>n%2?t+r:t+e));a.push({key:"S",data:t}),e=t[2],r=t[3];break}case"T":a.push({key:"T",data:[...s]}),e=s[0],r=s[1];break;case"t":e+=s[0],r+=s[1],a.push({key:"T",data:[e,r]});break;case"Z":case"z":a.push({key:"Z",data:[]}),e=n,r=i}return a}function _(t){const e=[];let r="",n=0,i=0,a=0,o=0,s=0,l=0;for(const{key:c,data:h}of t){switch(c){case"M":e.push({key:"M",data:[...h]}),[n,i]=h,[a,o]=h;break;case"C":e.push({key:"C",data:[...h]}),n=h[4],i=h[5],s=h[2],l=h[3];break;case"L":e.push({key:"L",data:[...h]}),[n,i]=h;break;case"H":n=h[0],e.push({key:"L",data:[n,i]});break;case"V":i=h[0],e.push({key:"L",data:[n,i]});break;case"S":{let t=0,a=0;"C"===r||"S"===r?(t=n+(n-s),a=i+(i-l)):(t=n,a=i),e.push({key:"C",data:[t,a,...h]}),s=h[0],l=h[1],n=h[2],i=h[3];break}case"T":{const[t,a]=h;let o=0,c=0;"Q"===r||"T"===r?(o=n+(n-s),c=i+(i-l)):(o=n,c=i);const u=n+2*(o-n)/3,d=i+2*(c-i)/3,p=t+2*(o-t)/3,f=a+2*(c-a)/3;e.push({key:"C",data:[u,d,p,f,t,a]}),s=o,l=c,n=t,i=a;break}case"Q":{const[t,r,a,o]=h,c=n+2*(t-n)/3,u=i+2*(r-i)/3,d=a+2*(t-a)/3,p=o+2*(r-o)/3;e.push({key:"C",data:[c,u,d,p,a,o]}),s=t,l=r,n=a,i=o;break}case"A":{const t=Math.abs(h[0]),r=Math.abs(h[1]),a=h[2],o=h[3],s=h[4],l=h[5],c=h[6];0===t||0===r?(e.push({key:"C",data:[n,i,l,c,l,c]}),n=l,i=c):n===l&&i===c||(S(n,i,l,c,t,r,a,o,s).forEach((function(t){e.push({key:"C",data:t})})),n=l,i=c);break}case"Z":e.push({key:"Z",data:[]}),n=a,i=o}r=c}return e}function v(t,e,r){return[t*Math.cos(r)-e*Math.sin(r),t*Math.sin(r)+e*Math.cos(r)]}function S(t,e,r,n,i,a,o,s,l,c){const h=(u=o,Math.PI*u/180);var u;let d=[],p=0,f=0,g=0,m=0;if(c)[p,f,g,m]=c;else{[t,e]=v(t,e,-h),[r,n]=v(r,n,-h);const o=(t-r)/2,c=(e-n)/2;let u=o*o/(i*i)+c*c/(a*a);u>1&&(u=Math.sqrt(u),i*=u,a*=u);const d=i*i,y=a*a,x=d*y-d*c*c-y*o*o,b=d*c*c+y*o*o,k=(s===l?-1:1)*Math.sqrt(Math.abs(x/b));g=k*i*c/a+(t+r)/2,m=k*-a*o/i+(e+n)/2,p=Math.asin(parseFloat(((e-m)/a).toFixed(9))),f=Math.asin(parseFloat(((n-m)/a).toFixed(9))),t<g&&(p=Math.PI-p),r<g&&(f=Math.PI-f),p<0&&(p=2*Math.PI+p),f<0&&(f=2*Math.PI+f),l&&p>f&&(p-=2*Math.PI),!l&&f>p&&(f-=2*Math.PI)}let y=f-p;if(Math.abs(y)>120*Math.PI/180){const t=f,e=r,s=n;f=l&&f>p?p+120*Math.PI/180*1:p+120*Math.PI/180*-1,d=S(r=g+i*Math.cos(f),n=m+a*Math.sin(f),e,s,i,a,o,0,l,[f,t,g,m])}y=f-p;const x=Math.cos(p),b=Math.sin(p),k=Math.cos(f),C=Math.sin(f),w=Math.tan(y/4),_=4/3*i*w,A=4/3*a*w,T=[t,e],M=[t+_*b,e-A*x],B=[r+_*C,n-A*k],L=[r,n];if(M[0]=2*T[0]-M[0],M[1]=2*T[1]-M[1],c)return[M,B,L].concat(d);{d=[M,B,L].concat(d);const t=[];for(let e=0;e<d.length;e+=3){const r=v(d[e][0],d[e][1],h),n=v(d[e+1][0],d[e+1][1],h),i=v(d[e+2][0],d[e+2][1],h);t.push([r[0],r[1],n[0],n[1],i[0],i[1]])}return t}}const A={randOffset:function(t,e){return R(t,e)},randOffsetWithRange:function(t,e,r){return O(t,e,r)},ellipse:function(t,e,r,n,i){return F(t,e,i,L(r,n,i)).opset},doubleLineOps:function(t,e,r,n,i){return P(t,e,r,n,i,!0)}};function T(t,e,r,n,i){return{type:"path",ops:P(t,e,r,n,i)}}function M(t,e,r){const n=(t||[]).length;if(n>2){const i=[];for(let e=0;e<n-1;e++)i.push(...P(t[e][0],t[e][1],t[e+1][0],t[e+1][1],r));return e&&i.push(...P(t[n-1][0],t[n-1][1],t[0][0],t[0][1],r)),{type:"path",ops:i}}return 2===n?T(t[0][0],t[0][1],t[1][0],t[1][1],r):{type:"path",ops:[]}}function B(t,e){if(t.length){const r="number"==typeof t[0][0]?[t]:t,n=K(r[0],1*(1+.2*e.roughness),e),i=e.disableMultiStroke?[]:K(r[0],1.5*(1+.22*e.roughness),j(e));for(let t=1;t<r.length;t++){const a=r[t];if(a.length){const t=K(a,1*(1+.2*e.roughness),e),r=e.disableMultiStroke?[]:K(a,1.5*(1+.22*e.roughness),j(e));for(const e of t)"move"!==e.op&&n.push(e);for(const e of r)"move"!==e.op&&i.push(e)}}return{type:"path",ops:n.concat(i)}}return{type:"path",ops:[]}}function L(t,e,r){const n=Math.sqrt(2*Math.PI*Math.sqrt((Math.pow(t/2,2)+Math.pow(e/2,2))/2)),i=Math.ceil(Math.max(r.curveStepCount,r.curveStepCount/Math.sqrt(200)*n)),a=2*Math.PI/i;let o=Math.abs(t/2),s=Math.abs(e/2);const l=1-r.curveFitting;return o+=R(o*l,r),s+=R(s*l,r),{increment:a,rx:o,ry:s}}function F(t,e,r,n){const[i,a]=W(n.increment,t,e,n.rx,n.ry,1,n.increment*O(.1,O(.4,1,r),r),r);let o=q(i,null,r);if(!r.disableMultiStroke&&0!==r.roughness){const[i]=W(n.increment,t,e,n.rx,n.ry,1.5,0,r),a=q(i,null,r);o=o.concat(a)}return{estimatedPoints:a,opset:{type:"path",ops:o}}}function $(t,e,r,n,i,a,o,s,l){const c=t,h=e;let u=Math.abs(r/2),d=Math.abs(n/2);u+=R(.01*u,l),d+=R(.01*d,l);let p=i,f=a;for(;p<0;)p+=2*Math.PI,f+=2*Math.PI;f-p>2*Math.PI&&(p=0,f=2*Math.PI);const g=2*Math.PI/l.curveStepCount,m=Math.min(g/2,(f-p)/2),y=H(m,c,h,u,d,p,f,1,l);if(!l.disableMultiStroke){const t=H(m,c,h,u,d,p,f,1.5,l);y.push(...t)}return o&&(s?y.push(...P(c,h,c+u*Math.cos(p),h+d*Math.sin(p),l),...P(c,h,c+u*Math.cos(f),h+d*Math.sin(f),l)):y.push({op:"lineTo",data:[c,h]},{op:"lineTo",data:[c+u*Math.cos(p),h+d*Math.sin(p)]})),{type:"path",ops:y}}function E(t,e){const r=_(w(C(t))),n=[];let i=[0,0],a=[0,0];for(const{key:o,data:s}of r)switch(o){case"M":a=[s[0],s[1]],i=[s[0],s[1]];break;case"L":n.push(...P(a[0],a[1],s[0],s[1],e)),a=[s[0],s[1]];break;case"C":{const[t,r,i,o,l,c]=s;n.push(...U(t,r,i,o,l,c,a,e)),a=[l,c];break}case"Z":n.push(...P(a[0],a[1],i[0],i[1],e)),a=[i[0],i[1]]}return{type:"path",ops:n}}function N(t,e){const r=[];for(const n of t)if(n.length){const t=e.maxRandomnessOffset||0,i=n.length;if(i>2){r.push({op:"move",data:[n[0][0]+R(t,e),n[0][1]+R(t,e)]});for(let a=1;a<i;a++)r.push({op:"lineTo",data:[n[a][0]+R(t,e),n[a][1]+R(t,e)]})}}return{type:"fillPath",ops:r}}function D(t,e){return function(t,e){let r=t.fillStyle||"hachure";if(!f[r])switch(r){case"zigzag":f[r]||(f[r]=new c(e));break;case"cross-hatch":f[r]||(f[r]=new h(e));break;case"dots":f[r]||(f[r]=new u(e));break;case"dashed":f[r]||(f[r]=new d(e));break;case"zigzag-line":f[r]||(f[r]=new p(e));break;default:r="hachure",f[r]||(f[r]=new s(e))}return f[r]}(e,A).fillPolygons(t,e)}function j(t){const e=Object.assign({},t);return e.randomizer=void 0,t.seed&&(e.seed=t.seed+1),e}function I(t){return t.randomizer||(t.randomizer=new g(t.seed||0)),t.randomizer.next()}function O(t,e,r,n=1){return r.roughness*n*(I(r)*(e-t)+t)}function R(t,e,r=1){return O(-t,t,e,r)}function P(t,e,r,n,i,a=!1){const o=a?i.disableMultiStrokeFill:i.disableMultiStroke,s=z(t,e,r,n,i,!0,!1);if(o)return s;const l=z(t,e,r,n,i,!0,!0);return s.concat(l)}function z(t,e,r,n,i,a,o){const s=Math.pow(t-r,2)+Math.pow(e-n,2),l=Math.sqrt(s);let c=1;c=l<200?1:l>500?.4:-.0016668*l+1.233334;let h=i.maxRandomnessOffset||0;h*h*100>s&&(h=l/10);const u=h/2,d=.2+.2*I(i);let p=i.bowing*i.maxRandomnessOffset*(n-e)/200,f=i.bowing*i.maxRandomnessOffset*(t-r)/200;p=R(p,i,c),f=R(f,i,c);const g=[],m=()=>R(u,i,c),y=()=>R(h,i,c),x=i.preserveVertices;return a&&(o?g.push({op:"move",data:[t+(x?0:m()),e+(x?0:m())]}):g.push({op:"move",data:[t+(x?0:R(h,i,c)),e+(x?0:R(h,i,c))]})),o?g.push({op:"bcurveTo",data:[p+t+(r-t)*d+m(),f+e+(n-e)*d+m(),p+t+2*(r-t)*d+m(),f+e+2*(n-e)*d+m(),r+(x?0:m()),n+(x?0:m())]}):g.push({op:"bcurveTo",data:[p+t+(r-t)*d+y(),f+e+(n-e)*d+y(),p+t+2*(r-t)*d+y(),f+e+2*(n-e)*d+y(),r+(x?0:y()),n+(x?0:y())]}),g}function K(t,e,r){if(!t.length)return[];const n=[];n.push([t[0][0]+R(e,r),t[0][1]+R(e,r)]),n.push([t[0][0]+R(e,r),t[0][1]+R(e,r)]);for(let i=1;i<t.length;i++)n.push([t[i][0]+R(e,r),t[i][1]+R(e,r)]),i===t.length-1&&n.push([t[i][0]+R(e,r),t[i][1]+R(e,r)]);return q(n,null,r)}function q(t,e,r){const n=t.length,i=[];if(n>3){const a=[],o=1-r.curveTightness;i.push({op:"move",data:[t[1][0],t[1][1]]});for(let e=1;e+2<n;e++){const r=t[e];a[0]=[r[0],r[1]],a[1]=[r[0]+(o*t[e+1][0]-o*t[e-1][0])/6,r[1]+(o*t[e+1][1]-o*t[e-1][1])/6],a[2]=[t[e+1][0]+(o*t[e][0]-o*t[e+2][0])/6,t[e+1][1]+(o*t[e][1]-o*t[e+2][1])/6],a[3]=[t[e+1][0],t[e+1][1]],i.push({op:"bcurveTo",data:[a[1][0],a[1][1],a[2][0],a[2][1],a[3][0],a[3][1]]})}if(e&&2===e.length){const t=r.maxRandomnessOffset;i.push({op:"lineTo",data:[e[0]+R(t,r),e[1]+R(t,r)]})}}else 3===n?(i.push({op:"move",data:[t[1][0],t[1][1]]}),i.push({op:"bcurveTo",data:[t[1][0],t[1][1],t[2][0],t[2][1],t[2][0],t[2][1]]})):2===n&&i.push(...z(t[0][0],t[0][1],t[1][0],t[1][1],r,!0,!0));return i}function W(t,e,r,n,i,a,o,s){const l=[],c=[];if(0===s.roughness){t/=4,c.push([e+n*Math.cos(-t),r+i*Math.sin(-t)]);for(let a=0;a<=2*Math.PI;a+=t){const t=[e+n*Math.cos(a),r+i*Math.sin(a)];l.push(t),c.push(t)}c.push([e+n*Math.cos(0),r+i*Math.sin(0)]),c.push([e+n*Math.cos(t),r+i*Math.sin(t)])}else{const h=R(.5,s)-Math.PI/2;c.push([R(a,s)+e+.9*n*Math.cos(h-t),R(a,s)+r+.9*i*Math.sin(h-t)]);const u=2*Math.PI+h-.01;for(let o=h;o<u;o+=t){const t=[R(a,s)+e+n*Math.cos(o),R(a,s)+r+i*Math.sin(o)];l.push(t),c.push(t)}c.push([R(a,s)+e+n*Math.cos(h+2*Math.PI+.5*o),R(a,s)+r+i*Math.sin(h+2*Math.PI+.5*o)]),c.push([R(a,s)+e+.98*n*Math.cos(h+o),R(a,s)+r+.98*i*Math.sin(h+o)]),c.push([R(a,s)+e+.9*n*Math.cos(h+.5*o),R(a,s)+r+.9*i*Math.sin(h+.5*o)])}return[c,l]}function H(t,e,r,n,i,a,o,s,l){const c=a+R(.1,l),h=[];h.push([R(s,l)+e+.9*n*Math.cos(c-t),R(s,l)+r+.9*i*Math.sin(c-t)]);for(let u=c;u<=o;u+=t)h.push([R(s,l)+e+n*Math.cos(u),R(s,l)+r+i*Math.sin(u)]);return h.push([e+n*Math.cos(o),r+i*Math.sin(o)]),h.push([e+n*Math.cos(o),r+i*Math.sin(o)]),q(h,null,l)}function U(t,e,r,n,i,a,o,s){const l=[],c=[s.maxRandomnessOffset||1,(s.maxRandomnessOffset||1)+.3];let h=[0,0];const u=s.disableMultiStroke?1:2,d=s.preserveVertices;for(let p=0;p<u;p++)0===p?l.push({op:"move",data:[o[0],o[1]]}):l.push({op:"move",data:[o[0]+(d?0:R(c[0],s)),o[1]+(d?0:R(c[0],s))]}),h=d?[i,a]:[i+R(c[p],s),a+R(c[p],s)],l.push({op:"bcurveTo",data:[t+R(c[p],s),e+R(c[p],s),r+R(c[p],s),n+R(c[p],s),h[0],h[1]]});return l}function Y(t){return[...t]}function V(t,e=0){const r=t.length;if(r<3)throw new Error("A curve must have at least three points.");const n=[];if(3===r)n.push(Y(t[0]),Y(t[1]),Y(t[2]),Y(t[2]));else{const r=[];r.push(t[0],t[0]);for(let e=1;e<t.length;e++)r.push(t[e]),e===t.length-1&&r.push(t[e]);const i=[],a=1-e;n.push(Y(r[0]));for(let t=1;t+2<r.length;t++){const e=r[t];i[0]=[e[0],e[1]],i[1]=[e[0]+(a*r[t+1][0]-a*r[t-1][0])/6,e[1]+(a*r[t+1][1]-a*r[t-1][1])/6],i[2]=[r[t+1][0]+(a*r[t][0]-a*r[t+2][0])/6,r[t+1][1]+(a*r[t][1]-a*r[t+2][1])/6],i[3]=[r[t+1][0],r[t+1][1]],n.push(i[1],i[2],i[3])}}return n}function G(t,e){return Math.pow(t[0]-e[0],2)+Math.pow(t[1]-e[1],2)}function Z(t,e,r){const n=G(e,r);if(0===n)return G(t,e);let i=((t[0]-e[0])*(r[0]-e[0])+(t[1]-e[1])*(r[1]-e[1]))/n;return i=Math.max(0,Math.min(1,i)),G(t,X(e,r,i))}function X(t,e,r){return[t[0]+(e[0]-t[0])*r,t[1]+(e[1]-t[1])*r]}function Q(t,e,r,n){const i=n||[];if(function(t,e){const r=t[e+0],n=t[e+1],i=t[e+2],a=t[e+3];let o=3*n[0]-2*r[0]-a[0];o*=o;let s=3*n[1]-2*r[1]-a[1];s*=s;let l=3*i[0]-2*a[0]-r[0];l*=l;let c=3*i[1]-2*a[1]-r[1];return c*=c,o<l&&(o=l),s<c&&(s=c),o+s}(t,e)<r){const r=t[e+0];i.length?(a=i[i.length-1],o=r,Math.sqrt(G(a,o))>1&&i.push(r)):i.push(r),i.push(t[e+3])}else{const n=.5,a=t[e+0],o=t[e+1],s=t[e+2],l=t[e+3],c=X(a,o,n),h=X(o,s,n),u=X(s,l,n),d=X(c,h,n),p=X(h,u,n),f=X(d,p,n);Q([a,c,d,f],0,r,i),Q([f,p,u,l],0,r,i)}var a,o;return i}function J(t,e){return tt(t,0,t.length,e)}function tt(t,e,r,n,i){const a=i||[],o=t[e],s=t[r-1];let l=0,c=1;for(let h=e+1;h<r-1;++h){const e=Z(t[h],o,s);e>l&&(l=e,c=h)}return Math.sqrt(l)>n?(tt(t,e,c+1,n,a),tt(t,c,r,n,a)):(a.length||a.push(o),a.push(s)),a}function et(t,e=.15,r){const n=[],i=(t.length-1)/3;for(let a=0;a<i;a++)Q(t,3*a,e,n);return r&&r>0?tt(n,0,n.length,r):n}const rt="none";class nt{constructor(t){this.defaultOptions={maxRandomnessOffset:2,roughness:1,bowing:1,stroke:"#000",strokeWidth:1,curveTightness:0,curveFitting:.95,curveStepCount:9,fillStyle:"hachure",fillWeight:-1,hachureAngle:-41,hachureGap:-1,dashOffset:-1,dashGap:-1,zigzagOffset:-1,seed:0,disableMultiStroke:!1,disableMultiStrokeFill:!1,preserveVertices:!1,fillShapeRoughnessGain:.8},this.config=t||{},this.config.options&&(this.defaultOptions=this._o(this.config.options))}static newSeed(){return Math.floor(Math.random()*2**31)}_o(t){return t?Object.assign({},this.defaultOptions,t):this.defaultOptions}_d(t,e,r){return{shape:t,sets:e||[],options:r||this.defaultOptions}}line(t,e,r,n,i){const a=this._o(i);return this._d("line",[T(t,e,r,n,a)],a)}rectangle(t,e,r,n,i){const a=this._o(i),o=[],s=function(t,e,r,n,i){return function(t,e){return M(t,!0,e)}([[t,e],[t+r,e],[t+r,e+n],[t,e+n]],i)}(t,e,r,n,a);if(a.fill){const i=[[t,e],[t+r,e],[t+r,e+n],[t,e+n]];"solid"===a.fillStyle?o.push(N([i],a)):o.push(D([i],a))}return a.stroke!==rt&&o.push(s),this._d("rectangle",o,a)}ellipse(t,e,r,n,i){const a=this._o(i),o=[],s=L(r,n,a),l=F(t,e,a,s);if(a.fill)if("solid"===a.fillStyle){const r=F(t,e,a,s).opset;r.type="fillPath",o.push(r)}else o.push(D([l.estimatedPoints],a));return a.stroke!==rt&&o.push(l.opset),this._d("ellipse",o,a)}circle(t,e,r,n){const i=this.ellipse(t,e,r,r,n);return i.shape="circle",i}linearPath(t,e){const r=this._o(e);return this._d("linearPath",[M(t,!1,r)],r)}arc(t,e,r,n,i,a,o=!1,s){const l=this._o(s),c=[],h=$(t,e,r,n,i,a,o,!0,l);if(o&&l.fill)if("solid"===l.fillStyle){const o=Object.assign({},l);o.disableMultiStroke=!0;const s=$(t,e,r,n,i,a,!0,!1,o);s.type="fillPath",c.push(s)}else c.push(function(t,e,r,n,i,a,o){const s=t,l=e;let c=Math.abs(r/2),h=Math.abs(n/2);c+=R(.01*c,o),h+=R(.01*h,o);let u=i,d=a;for(;u<0;)u+=2*Math.PI,d+=2*Math.PI;d-u>2*Math.PI&&(u=0,d=2*Math.PI);const p=(d-u)/o.curveStepCount,f=[];for(let g=u;g<=d;g+=p)f.push([s+c*Math.cos(g),l+h*Math.sin(g)]);return f.push([s+c*Math.cos(d),l+h*Math.sin(d)]),f.push([s,l]),D([f],o)}(t,e,r,n,i,a,l));return l.stroke!==rt&&c.push(h),this._d("arc",c,l)}curve(t,e){const r=this._o(e),n=[],i=B(t,r);if(r.fill&&r.fill!==rt)if("solid"===r.fillStyle){const e=B(t,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));n.push({type:"fillPath",ops:this._mergedShape(e.ops)})}else{const e=[],i=t;if(i.length){const t="number"==typeof i[0][0]?[i]:i;for(const n of t)n.length<3?e.push(...n):3===n.length?e.push(...et(V([n[0],n[0],n[1],n[2]]),10,(1+r.roughness)/2)):e.push(...et(V(n),10,(1+r.roughness)/2))}e.length&&n.push(D([e],r))}return r.stroke!==rt&&n.push(i),this._d("curve",n,r)}polygon(t,e){const r=this._o(e),n=[],i=M(t,!0,r);return r.fill&&("solid"===r.fillStyle?n.push(N([t],r)):n.push(D([t],r))),r.stroke!==rt&&n.push(i),this._d("polygon",n,r)}path(t,e){const r=this._o(e),n=[];if(!t)return this._d("path",n,r);t=(t||"").replace(/\n/g," ").replace(/(-\s)/g,"-").replace("/(ss)/g"," ");const i=r.fill&&"transparent"!==r.fill&&r.fill!==rt,a=r.stroke!==rt,o=!!(r.simplification&&r.simplification<1),s=function(t,e,r){const n=_(w(C(t))),i=[];let a=[],o=[0,0],s=[];const l=()=>{s.length>=4&&a.push(...et(s,1)),s=[]},c=()=>{l(),a.length&&(i.push(a),a=[])};for(const{key:u,data:d}of n)switch(u){case"M":c(),o=[d[0],d[1]],a.push(o);break;case"L":l(),a.push([d[0],d[1]]);break;case"C":if(!s.length){const t=a.length?a[a.length-1]:o;s.push([t[0],t[1]])}s.push([d[0],d[1]]),s.push([d[2],d[3]]),s.push([d[4],d[5]]);break;case"Z":l(),a.push([o[0],o[1]])}if(c(),!r)return i;const h=[];for(const u of i){const t=J(u,r);t.length&&h.push(t)}return h}(t,0,o?4-4*(r.simplification||1):(1+r.roughness)/2),l=E(t,r);if(i)if("solid"===r.fillStyle)if(1===s.length){const e=E(t,Object.assign(Object.assign({},r),{disableMultiStroke:!0,roughness:r.roughness?r.roughness+r.fillShapeRoughnessGain:0}));n.push({type:"fillPath",ops:this._mergedShape(e.ops)})}else n.push(N(s,r));else n.push(D(s,r));return a&&(o?s.forEach((t=>{n.push(M(t,!1,r))})):n.push(l)),this._d("path",n,r)}opsToPath(t,e){let r="";for(const n of t.ops){const t="number"==typeof e&&e>=0?n.data.map((t=>+t.toFixed(e))):n.data;switch(n.op){case"move":r+=`M${t[0]} ${t[1]} `;break;case"bcurveTo":r+=`C${t[0]} ${t[1]}, ${t[2]} ${t[3]}, ${t[4]} ${t[5]} `;break;case"lineTo":r+=`L${t[0]} ${t[1]} `}}return r.trim()}toPaths(t){const e=t.sets||[],r=t.options||this.defaultOptions,n=[];for(const i of e){let t=null;switch(i.type){case"path":t={d:this.opsToPath(i),stroke:r.stroke,strokeWidth:r.strokeWidth,fill:rt};break;case"fillPath":t={d:this.opsToPath(i),stroke:rt,strokeWidth:0,fill:r.fill||rt};break;case"fillSketch":t=this.fillSketch(i,r)}t&&n.push(t)}return n}fillSketch(t,e){let r=e.fillWeight;return r<0&&(r=e.strokeWidth/2),{d:this.opsToPath(t),stroke:e.fill||rt,strokeWidth:r,fill:rt}}_mergedShape(t){return t.filter(((t,e)=>0===e||"move"!==t.op))}}class it{constructor(t,e){this.canvas=t,this.ctx=this.canvas.getContext("2d"),this.gen=new nt(e)}draw(t){const e=t.sets||[],r=t.options||this.getDefaultOptions(),n=this.ctx,i=t.options.fixedDecimalPlaceDigits;for(const a of e)switch(a.type){case"path":n.save(),n.strokeStyle="none"===r.stroke?"transparent":r.stroke,n.lineWidth=r.strokeWidth,r.strokeLineDash&&n.setLineDash(r.strokeLineDash),r.strokeLineDashOffset&&(n.lineDashOffset=r.strokeLineDashOffset),this._drawToContext(n,a,i),n.restore();break;case"fillPath":{n.save(),n.fillStyle=r.fill||"";const e="curve"===t.shape||"polygon"===t.shape||"path"===t.shape?"evenodd":"nonzero";this._drawToContext(n,a,i,e),n.restore();break}case"fillSketch":this.fillSketch(n,a,r)}}fillSketch(t,e,r){let n=r.fillWeight;n<0&&(n=r.strokeWidth/2),t.save(),r.fillLineDash&&t.setLineDash(r.fillLineDash),r.fillLineDashOffset&&(t.lineDashOffset=r.fillLineDashOffset),t.strokeStyle=r.fill||"",t.lineWidth=n,this._drawToContext(t,e,r.fixedDecimalPlaceDigits),t.restore()}_drawToContext(t,e,r,n="nonzero"){t.beginPath();for(const i of e.ops){const e="number"==typeof r&&r>=0?i.data.map((t=>+t.toFixed(r))):i.data;switch(i.op){case"move":t.moveTo(e[0],e[1]);break;case"bcurveTo":t.bezierCurveTo(e[0],e[1],e[2],e[3],e[4],e[5]);break;case"lineTo":t.lineTo(e[0],e[1])}}"fillPath"===e.type?t.fill(n):t.stroke()}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}line(t,e,r,n,i){const a=this.gen.line(t,e,r,n,i);return this.draw(a),a}rectangle(t,e,r,n,i){const a=this.gen.rectangle(t,e,r,n,i);return this.draw(a),a}ellipse(t,e,r,n,i){const a=this.gen.ellipse(t,e,r,n,i);return this.draw(a),a}circle(t,e,r,n){const i=this.gen.circle(t,e,r,n);return this.draw(i),i}linearPath(t,e){const r=this.gen.linearPath(t,e);return this.draw(r),r}polygon(t,e){const r=this.gen.polygon(t,e);return this.draw(r),r}arc(t,e,r,n,i,a,o=!1,s){const l=this.gen.arc(t,e,r,n,i,a,o,s);return this.draw(l),l}curve(t,e){const r=this.gen.curve(t,e);return this.draw(r),r}path(t,e){const r=this.gen.path(t,e);return this.draw(r),r}}const at="http://www.w3.org/2000/svg";class ot{constructor(t,e){this.svg=t,this.gen=new nt(e)}draw(t){const e=t.sets||[],r=t.options||this.getDefaultOptions(),n=this.svg.ownerDocument||window.document,i=n.createElementNS(at,"g"),a=t.options.fixedDecimalPlaceDigits;for(const o of e){let e=null;switch(o.type){case"path":e=n.createElementNS(at,"path"),e.setAttribute("d",this.opsToPath(o,a)),e.setAttribute("stroke",r.stroke),e.setAttribute("stroke-width",r.strokeWidth+""),e.setAttribute("fill","none"),r.strokeLineDash&&e.setAttribute("stroke-dasharray",r.strokeLineDash.join(" ").trim()),r.strokeLineDashOffset&&e.setAttribute("stroke-dashoffset",`${r.strokeLineDashOffset}`);break;case"fillPath":e=n.createElementNS(at,"path"),e.setAttribute("d",this.opsToPath(o,a)),e.setAttribute("stroke","none"),e.setAttribute("stroke-width","0"),e.setAttribute("fill",r.fill||""),"curve"!==t.shape&&"polygon"!==t.shape||e.setAttribute("fill-rule","evenodd");break;case"fillSketch":e=this.fillSketch(n,o,r)}e&&i.appendChild(e)}return i}fillSketch(t,e,r){let n=r.fillWeight;n<0&&(n=r.strokeWidth/2);const i=t.createElementNS(at,"path");return i.setAttribute("d",this.opsToPath(e,r.fixedDecimalPlaceDigits)),i.setAttribute("stroke",r.fill||""),i.setAttribute("stroke-width",n+""),i.setAttribute("fill","none"),r.fillLineDash&&i.setAttribute("stroke-dasharray",r.fillLineDash.join(" ").trim()),r.fillLineDashOffset&&i.setAttribute("stroke-dashoffset",`${r.fillLineDashOffset}`),i}get generator(){return this.gen}getDefaultOptions(){return this.gen.defaultOptions}opsToPath(t,e){return this.gen.opsToPath(t,e)}line(t,e,r,n,i){const a=this.gen.line(t,e,r,n,i);return this.draw(a)}rectangle(t,e,r,n,i){const a=this.gen.rectangle(t,e,r,n,i);return this.draw(a)}ellipse(t,e,r,n,i){const a=this.gen.ellipse(t,e,r,n,i);return this.draw(a)}circle(t,e,r,n){const i=this.gen.circle(t,e,r,n);return this.draw(i)}linearPath(t,e){const r=this.gen.linearPath(t,e);return this.draw(r)}polygon(t,e){const r=this.gen.polygon(t,e);return this.draw(r)}arc(t,e,r,n,i,a,o=!1,s){const l=this.gen.arc(t,e,r,n,i,a,o,s);return this.draw(l)}curve(t,e){const r=this.gen.curve(t,e);return this.draw(r)}path(t,e){const r=this.gen.path(t,e);return this.draw(r)}}var st={canvas:(t,e)=>new it(t,e),svg:(t,e)=>new ot(t,e),generator:t=>new nt(t),newSeed:()=>nt.newSeed()}},60513:(t,e,r)=>{"use strict";function n(t){for(var e=[],r=1;r<arguments.length;r++)e[r-1]=arguments[r];var n=Array.from("string"==typeof t?[t]:t);n[n.length-1]=n[n.length-1].replace(/\r?\n([\t ]*)$/,"");var i=n.reduce((function(t,e){var r=e.match(/\n([\t ]+|(?!\s).)/g);return r?t.concat(r.map((function(t){var e,r;return null!==(r=null===(e=t.match(/[\t ]/g))||void 0===e?void 0:e.length)&&void 0!==r?r:0}))):t}),[]);if(i.length){var a=new RegExp("\n[\t ]{"+Math.min.apply(Math,i)+"}","g");n=n.map((function(t){return t.replace(a,"\n")}))}n[0]=n[0].replace(/^\r?\n/,"");var o=n[0];return e.forEach((function(t,e){var r=o.match(/(?:^|\n)( *)$/),i=r?r[1]:"",a=t;"string"==typeof t&&t.includes("\n")&&(a=String(t).split("\n").map((function(t,e){return 0===e?t:""+i+t})).join("\n")),o+=a+n[e+1]})),o}r.d(e,{T:()=>n})},28453:(t,e,r)=>{"use strict";r.d(e,{R:()=>o,x:()=>s});var n=r(96540);const i={},a=n.createContext(i);function o(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(i):t.components||i:o(t.components),n.createElement(a.Provider,{value:e},t.children)}},20007:(t,e,r)=>{"use strict";function n(t,e){let r;if(void 0===e)for(const n of t)null!=n&&(r<n||void 0===r&&n>=n)&&(r=n);else{let n=-1;for(let i of t)null!=(i=e(i,++n,t))&&(r<i||void 0===r&&i>=i)&&(r=i)}return r}function i(t,e){let r;if(void 0===e)for(const n of t)null!=n&&(r>n||void 0===r&&n>=n)&&(r=n);else{let n=-1;for(let i of t)null!=(i=e(i,++n,t))&&(r>i||void 0===r&&i>=i)&&(r=i)}return r}function a(t){return t}r.d(e,{JLW:()=>as,l78:()=>x,tlR:()=>y,qrM:()=>xs,Yu4:()=>ks,IA3:()=>ws,Wi0:()=>vs,PGM:()=>Ss,OEq:()=>Ts,y8u:()=>Ls,olC:()=>$s,IrU:()=>Ns,oDi:()=>Is,Q7f:()=>Rs,cVp:()=>zs,lUB:()=>ls,Lx9:()=>qs,nVG:()=>Xs,uxU:()=>Qs,Xf2:()=>el,GZz:()=>nl,UPb:()=>al,dyv:()=>il,bEH:()=>dn,n8j:()=>us,T9B:()=>n,jkA:()=>i,rLf:()=>fs,WH:()=>Cn,m4Y:()=>pi,UMr:()=>kn,w7C:()=>Lo,zt:()=>Fo,Ltv:()=>$o,UAC:()=>Li,DCK:()=>la,TUC:()=>Ri,Agd:()=>Mi,t6C:()=>vi,wXd:()=>Ai,ABi:()=>Di,Ui6:()=>Gi,rGn:()=>Pi,ucG:()=>Si,YPH:()=>Ni,Mol:()=>Oi,PGu:()=>ji,GuW:()=>Ii});var o=1,s=2,l=3,c=4,h=1e-6;function u(t){return"translate("+t+",0)"}function d(t){return"translate(0,"+t+")"}function p(t){return e=>+t(e)}function f(t,e){return e=Math.max(0,t.bandwidth()-2*e)/2,t.round()&&(e=Math.round(e)),r=>+t(r)+e}function g(){return!this.__axis}function m(t,e){var r=[],n=null,i=null,m=6,y=6,x=3,b="undefined"!=typeof window&&window.devicePixelRatio>1?0:.5,k=t===o||t===c?-1:1,C=t===c||t===s?"x":"y",w=t===o||t===l?u:d;function _(u){var d=null==n?e.ticks?e.ticks.apply(e,r):e.domain():n,_=null==i?e.tickFormat?e.tickFormat.apply(e,r):a:i,v=Math.max(m,0)+x,S=e.range(),A=+S[0]+b,T=+S[S.length-1]+b,M=(e.bandwidth?f:p)(e.copy(),b),B=u.selection?u.selection():u,L=B.selectAll(".domain").data([null]),F=B.selectAll(".tick").data(d,e).order(),$=F.exit(),E=F.enter().append("g").attr("class","tick"),N=F.select("line"),D=F.select("text");L=L.merge(L.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),F=F.merge(E),N=N.merge(E.append("line").attr("stroke","currentColor").attr(C+"2",k*m)),D=D.merge(E.append("text").attr("fill","currentColor").attr(C,k*v).attr("dy",t===o?"0em":t===l?"0.71em":"0.32em")),u!==B&&(L=L.transition(u),F=F.transition(u),N=N.transition(u),D=D.transition(u),$=$.transition(u).attr("opacity",h).attr("transform",(function(t){return isFinite(t=M(t))?w(t+b):this.getAttribute("transform")})),E.attr("opacity",h).attr("transform",(function(t){var e=this.parentNode.__axis;return w((e&&isFinite(e=e(t))?e:M(t))+b)}))),$.remove(),L.attr("d",t===c||t===s?y?"M"+k*y+","+A+"H"+b+"V"+T+"H"+k*y:"M"+b+","+A+"V"+T:y?"M"+A+","+k*y+"V"+b+"H"+T+"V"+k*y:"M"+A+","+b+"H"+T),F.attr("opacity",1).attr("transform",(function(t){return w(M(t)+b)})),N.attr(C+"2",k*m),D.attr(C,k*v).text(_),B.filter(g).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===s?"start":t===c?"end":"middle"),B.each((function(){this.__axis=M}))}return _.scale=function(t){return arguments.length?(e=t,_):e},_.ticks=function(){return r=Array.from(arguments),_},_.tickArguments=function(t){return arguments.length?(r=null==t?[]:Array.from(t),_):r.slice()},_.tickValues=function(t){return arguments.length?(n=null==t?null:Array.from(t),_):n&&n.slice()},_.tickFormat=function(t){return arguments.length?(i=t,_):i},_.tickSize=function(t){return arguments.length?(m=y=+t,_):m},_.tickSizeInner=function(t){return arguments.length?(m=+t,_):m},_.tickSizeOuter=function(t){return arguments.length?(y=+t,_):y},_.tickPadding=function(t){return arguments.length?(x=+t,_):x},_.offset=function(t){return arguments.length?(b=+t,_):b},_}function y(t){return m(o,t)}function x(t){return m(l,t)}function b(){}function k(t){return null==t?b:function(){return this.querySelector(t)}}function C(){return[]}function w(t){return null==t?C:function(){return this.querySelectorAll(t)}}function _(t){return function(){return null==(e=t.apply(this,arguments))?[]:Array.isArray(e)?e:Array.from(e);var e}}function v(t){return function(){return this.matches(t)}}function S(t){return function(e){return e.matches(t)}}var A=Array.prototype.find;function T(){return this.firstElementChild}var M=Array.prototype.filter;function B(){return Array.from(this.children)}function L(t){return new Array(t.length)}function F(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}function $(t,e,r,n,i,a){for(var o,s=0,l=e.length,c=a.length;s<c;++s)(o=e[s])?(o.__data__=a[s],n[s]=o):r[s]=new F(t,a[s]);for(;s<l;++s)(o=e[s])&&(i[s]=o)}function E(t,e,r,n,i,a,o){var s,l,c,h=new Map,u=e.length,d=a.length,p=new Array(u);for(s=0;s<u;++s)(l=e[s])&&(p[s]=c=o.call(l,l.__data__,s,e)+"",h.has(c)?i[s]=l:h.set(c,l));for(s=0;s<d;++s)c=o.call(t,a[s],s,a)+"",(l=h.get(c))?(n[s]=l,l.__data__=a[s],h.delete(c)):r[s]=new F(t,a[s]);for(s=0;s<u;++s)(l=e[s])&&h.get(p[s])===l&&(i[s]=l)}function N(t){return t.__data__}function D(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function j(t,e){return t<e?-1:t>e?1:t>=e?0:NaN}F.prototype={constructor:F,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var I="http://www.w3.org/1999/xhtml";const O={svg:"http://www.w3.org/2000/svg",xhtml:I,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function R(t){var e=t+="",r=e.indexOf(":");return r>=0&&"xmlns"!==(e=t.slice(0,r))&&(t=t.slice(r+1)),O.hasOwnProperty(e)?{space:O[e],local:t}:t}function P(t){return function(){this.removeAttribute(t)}}function z(t){return function(){this.removeAttributeNS(t.space,t.local)}}function K(t,e){return function(){this.setAttribute(t,e)}}function q(t,e){return function(){this.setAttributeNS(t.space,t.local,e)}}function W(t,e){return function(){var r=e.apply(this,arguments);null==r?this.removeAttribute(t):this.setAttribute(t,r)}}function H(t,e){return function(){var r=e.apply(this,arguments);null==r?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,r)}}function U(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function Y(t){return function(){this.style.removeProperty(t)}}function V(t,e,r){return function(){this.style.setProperty(t,e,r)}}function G(t,e,r){return function(){var n=e.apply(this,arguments);null==n?this.style.removeProperty(t):this.style.setProperty(t,n,r)}}function Z(t,e){return t.style.getPropertyValue(e)||U(t).getComputedStyle(t,null).getPropertyValue(e)}function X(t){return function(){delete this[t]}}function Q(t,e){return function(){this[t]=e}}function J(t,e){return function(){var r=e.apply(this,arguments);null==r?delete this[t]:this[t]=r}}function tt(t){return t.trim().split(/^|\s+/)}function et(t){return t.classList||new rt(t)}function rt(t){this._node=t,this._names=tt(t.getAttribute("class")||"")}function nt(t,e){for(var r=et(t),n=-1,i=e.length;++n<i;)r.add(e[n])}function it(t,e){for(var r=et(t),n=-1,i=e.length;++n<i;)r.remove(e[n])}function at(t){return function(){nt(this,t)}}function ot(t){return function(){it(this,t)}}function st(t,e){return function(){(e.apply(this,arguments)?nt:it)(this,t)}}function lt(){this.textContent=""}function ct(t){return function(){this.textContent=t}}function ht(t){return function(){var e=t.apply(this,arguments);this.textContent=null==e?"":e}}function ut(){this.innerHTML=""}function dt(t){return function(){this.innerHTML=t}}function pt(t){return function(){var e=t.apply(this,arguments);this.innerHTML=null==e?"":e}}function ft(){this.nextSibling&&this.parentNode.appendChild(this)}function gt(){this.previousSibling&&this.parentNode.insertBefore(this,this.parentNode.firstChild)}function mt(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===I&&e.documentElement.namespaceURI===I?e.createElement(t):e.createElementNS(r,t)}}function yt(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function xt(t){var e=R(t);return(e.local?yt:mt)(e)}function bt(){return null}function kt(){var t=this.parentNode;t&&t.removeChild(this)}function Ct(){var t=this.cloneNode(!1),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function wt(){var t=this.cloneNode(!0),e=this.parentNode;return e?e.insertBefore(t,this.nextSibling):t}function _t(t){return function(){var e=this.__on;if(e){for(var r,n=0,i=-1,a=e.length;n<a;++n)r=e[n],t.type&&r.type!==t.type||r.name!==t.name?e[++i]=r:this.removeEventListener(r.type,r.listener,r.options);++i?e.length=i:delete this.__on}}}function vt(t,e,r){return function(){var n,i=this.__on,a=function(t){return function(e){t.call(this,e,this.__data__)}}(e);if(i)for(var o=0,s=i.length;o<s;++o)if((n=i[o]).type===t.type&&n.name===t.name)return this.removeEventListener(n.type,n.listener,n.options),this.addEventListener(n.type,n.listener=a,n.options=r),void(n.value=e);this.addEventListener(t.type,a,r),n={type:t.type,name:t.name,value:e,listener:a,options:r},i?i.push(n):this.__on=[n]}}function St(t,e,r){var n=U(t),i=n.CustomEvent;"function"==typeof i?i=new i(e,r):(i=n.document.createEvent("Event"),r?(i.initEvent(e,r.bubbles,r.cancelable),i.detail=r.detail):i.initEvent(e,!1,!1)),t.dispatchEvent(i)}function At(t,e){return function(){return St(this,t,e)}}function Tt(t,e){return function(){return St(this,t,e.apply(this,arguments))}}rt.prototype={add:function(t){this._names.indexOf(t)<0&&(this._names.push(t),this._node.setAttribute("class",this._names.join(" ")))},remove:function(t){var e=this._names.indexOf(t);e>=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var Mt=[null];function Bt(t,e){this._groups=t,this._parents=e}function Lt(){return new Bt([[document.documentElement]],Mt)}Bt.prototype=Lt.prototype={constructor:Bt,select:function(t){"function"!=typeof t&&(t=k(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a,o,s=e[i],l=s.length,c=n[i]=new Array(l),h=0;h<l;++h)(a=s[h])&&(o=t.call(a,a.__data__,h,s))&&("__data__"in a&&(o.__data__=a.__data__),c[h]=o);return new Bt(n,this._parents)},selectAll:function(t){t="function"==typeof t?_(t):w(t);for(var e=this._groups,r=e.length,n=[],i=[],a=0;a<r;++a)for(var o,s=e[a],l=s.length,c=0;c<l;++c)(o=s[c])&&(n.push(t.call(o,o.__data__,c,s)),i.push(o));return new Bt(n,i)},selectChild:function(t){return this.select(null==t?T:function(t){return function(){return A.call(this.children,t)}}("function"==typeof t?t:S(t)))},selectChildren:function(t){return this.selectAll(null==t?B:function(t){return function(){return M.call(this.children,t)}}("function"==typeof t?t:S(t)))},filter:function(t){"function"!=typeof t&&(t=v(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a,o=e[i],s=o.length,l=n[i]=[],c=0;c<s;++c)(a=o[c])&&t.call(a,a.__data__,c,o)&&l.push(a);return new Bt(n,this._parents)},data:function(t,e){if(!arguments.length)return Array.from(this,N);var r,n=e?E:$,i=this._parents,a=this._groups;"function"!=typeof t&&(r=t,t=function(){return r});for(var o=a.length,s=new Array(o),l=new Array(o),c=new Array(o),h=0;h<o;++h){var u=i[h],d=a[h],p=d.length,f=D(t.call(u,u&&u.__data__,h,i)),g=f.length,m=l[h]=new Array(g),y=s[h]=new Array(g);n(u,d,m,y,c[h]=new Array(p),f,e);for(var x,b,k=0,C=0;k<g;++k)if(x=m[k]){for(k>=C&&(C=k+1);!(b=y[C])&&++C<g;);x._next=b||null}}return(s=new Bt(s,i))._enter=l,s._exit=c,s},enter:function(){return new Bt(this._enter||this._groups.map(L),this._parents)},exit:function(){return new Bt(this._exit||this._groups.map(L),this._parents)},join:function(t,e,r){var n=this.enter(),i=this,a=this.exit();return"function"==typeof t?(n=t(n))&&(n=n.selection()):n=n.append(t+""),null!=e&&(i=e(i))&&(i=i.selection()),null==r?a.remove():r(a),n&&i?n.merge(i).order():i},merge:function(t){for(var e=t.selection?t.selection():t,r=this._groups,n=e._groups,i=r.length,a=n.length,o=Math.min(i,a),s=new Array(i),l=0;l<o;++l)for(var c,h=r[l],u=n[l],d=h.length,p=s[l]=new Array(d),f=0;f<d;++f)(c=h[f]||u[f])&&(p[f]=c);for(;l<i;++l)s[l]=r[l];return new Bt(s,this._parents)},selection:function(){return this},order:function(){for(var t=this._groups,e=-1,r=t.length;++e<r;)for(var n,i=t[e],a=i.length-1,o=i[a];--a>=0;)(n=i[a])&&(o&&4^n.compareDocumentPosition(o)&&o.parentNode.insertBefore(n,o),o=n);return this},sort:function(t){function e(e,r){return e&&r?t(e.__data__,r.__data__):!e-!r}t||(t=j);for(var r=this._groups,n=r.length,i=new Array(n),a=0;a<n;++a){for(var o,s=r[a],l=s.length,c=i[a]=new Array(l),h=0;h<l;++h)(o=s[h])&&(c[h]=o);c.sort(e)}return new Bt(i,this._parents).order()},call:function(){var t=arguments[0];return arguments[0]=this,t.apply(null,arguments),this},nodes:function(){return Array.from(this)},node:function(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var n=t[e],i=0,a=n.length;i<a;++i){var o=n[i];if(o)return o}return null},size:function(){let t=0;for(const e of this)++t;return t},empty:function(){return!this.node()},each:function(t){for(var e=this._groups,r=0,n=e.length;r<n;++r)for(var i,a=e[r],o=0,s=a.length;o<s;++o)(i=a[o])&&t.call(i,i.__data__,o,a);return this},attr:function(t,e){var r=R(t);if(arguments.length<2){var n=this.node();return r.local?n.getAttributeNS(r.space,r.local):n.getAttribute(r)}return this.each((null==e?r.local?z:P:"function"==typeof e?r.local?H:W:r.local?q:K)(r,e))},style:function(t,e,r){return arguments.length>1?this.each((null==e?Y:"function"==typeof e?G:V)(t,e,null==r?"":r)):Z(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?X:"function"==typeof e?J:Q)(t,e)):this.node()[t]},classed:function(t,e){var r=tt(t+"");if(arguments.length<2){for(var n=et(this.node()),i=-1,a=r.length;++i<a;)if(!n.contains(r[i]))return!1;return!0}return this.each(("function"==typeof e?st:e?at:ot)(r,e))},text:function(t){return arguments.length?this.each(null==t?lt:("function"==typeof t?ht:ct)(t)):this.node().textContent},html:function(t){return arguments.length?this.each(null==t?ut:("function"==typeof t?pt:dt)(t)):this.node().innerHTML},raise:function(){return this.each(ft)},lower:function(){return this.each(gt)},append:function(t){var e="function"==typeof t?t:xt(t);return this.select((function(){return this.appendChild(e.apply(this,arguments))}))},insert:function(t,e){var r="function"==typeof t?t:xt(t),n=null==e?bt:"function"==typeof e?e:k(e);return this.select((function(){return this.insertBefore(r.apply(this,arguments),n.apply(this,arguments)||null)}))},remove:function(){return this.each(kt)},clone:function(t){return this.select(t?wt:Ct)},datum:function(t){return arguments.length?this.property("__data__",t):this.node().__data__},on:function(t,e,r){var n,i,a=function(t){return t.trim().split(/^|\s+/).map((function(t){var e="",r=t.indexOf(".");return r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),{type:t,name:e}}))}(t+""),o=a.length;if(!(arguments.length<2)){for(s=e?vt:_t,n=0;n<o;++n)this.each(s(a[n],e,r));return this}var s=this.node().__on;if(s)for(var l,c=0,h=s.length;c<h;++c)for(n=0,l=s[c];n<o;++n)if((i=a[n]).type===l.type&&i.name===l.name)return l.value},dispatch:function(t,e){return this.each(("function"==typeof e?Tt:At)(t,e))},[Symbol.iterator]:function*(){for(var t=this._groups,e=0,r=t.length;e<r;++e)for(var n,i=t[e],a=0,o=i.length;a<o;++a)(n=i[a])&&(yield n)}};const Ft=Lt;var $t={value:()=>{}};function Et(){for(var t,e=0,r=arguments.length,n={};e<r;++e){if(!(t=arguments[e]+"")||t in n||/[\s.]/.test(t))throw new Error("illegal type: "+t);n[t]=[]}return new Nt(n)}function Nt(t){this._=t}function Dt(t,e){for(var r,n=0,i=t.length;n<i;++n)if((r=t[n]).name===e)return r.value}function jt(t,e,r){for(var n=0,i=t.length;n<i;++n)if(t[n].name===e){t[n]=$t,t=t.slice(0,n).concat(t.slice(n+1));break}return null!=r&&t.push({name:e,value:r}),t}Nt.prototype=Et.prototype={constructor:Nt,on:function(t,e){var r,n,i=this._,a=(n=i,(t+"").trim().split(/^|\s+/).map((function(t){var e="",r=t.indexOf(".");if(r>=0&&(e=t.slice(r+1),t=t.slice(0,r)),t&&!n.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}}))),o=-1,s=a.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++o<s;)if(r=(t=a[o]).type)i[r]=jt(i[r],t.name,e);else if(null==e)for(r in i)i[r]=jt(i[r],t.name,null);return this}for(;++o<s;)if((r=(t=a[o]).type)&&(r=Dt(i[r],t.name)))return r},copy:function(){var t={},e=this._;for(var r in e)t[r]=e[r].slice();return new Nt(t)},call:function(t,e){if((r=arguments.length-2)>0)for(var r,n,i=new Array(r),a=0;a<r;++a)i[a]=arguments[a+2];if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(a=0,r=(n=this._[t]).length;a<r;++a)n[a].value.apply(e,i)},apply:function(t,e,r){if(!this._.hasOwnProperty(t))throw new Error("unknown type: "+t);for(var n=this._[t],i=0,a=n.length;i<a;++i)n[i].value.apply(e,r)}};const It=Et;var Ot,Rt,Pt=0,zt=0,Kt=0,qt=1e3,Wt=0,Ht=0,Ut=0,Yt="object"==typeof performance&&performance.now?performance:Date,Vt="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function Gt(){return Ht||(Vt(Zt),Ht=Yt.now()+Ut)}function Zt(){Ht=0}function Xt(){this._call=this._time=this._next=null}function Qt(t,e,r){var n=new Xt;return n.restart(t,e,r),n}function Jt(){Ht=(Wt=Yt.now())+Ut,Pt=zt=0;try{!function(){Gt(),++Pt;for(var t,e=Ot;e;)(t=Ht-e._time)>=0&&e._call.call(void 0,t),e=e._next;--Pt}()}finally{Pt=0,function(){var t,e,r=Ot,n=1/0;for(;r;)r._call?(n>r._time&&(n=r._time),t=r,r=r._next):(e=r._next,r._next=null,r=t?t._next=e:Ot=e);Rt=t,ee(n)}(),Ht=0}}function te(){var t=Yt.now(),e=t-Wt;e>qt&&(Ut-=e,Wt=t)}function ee(t){Pt||(zt&&(zt=clearTimeout(zt)),t-Ht>24?(t<1/0&&(zt=setTimeout(Jt,t-Yt.now()-Ut)),Kt&&(Kt=clearInterval(Kt))):(Kt||(Wt=Yt.now(),Kt=setInterval(te,qt)),Pt=1,Vt(Jt)))}function re(t,e,r){var n=new Xt;return e=null==e?0:+e,n.restart((r=>{n.stop(),t(r+e)}),e,r),n}Xt.prototype=Qt.prototype={constructor:Xt,restart:function(t,e,r){if("function"!=typeof t)throw new TypeError("callback is not a function");r=(null==r?Gt():+r)+(null==e?0:+e),this._next||Rt===this||(Rt?Rt._next=this:Ot=this,Rt=this),this._call=t,this._time=r,ee()},stop:function(){this._call&&(this._call=null,this._time=1/0,ee())}};var ne=It("start","end","cancel","interrupt"),ie=[],ae=0,oe=1,se=2,le=3,ce=4,he=5,ue=6;function de(t,e,r,n,i,a){var o=t.__transition;if(o){if(r in o)return}else t.__transition={};!function(t,e,r){var n,i=t.__transition;function a(t){r.state=oe,r.timer.restart(o,r.delay,r.time),r.delay<=t&&o(t-r.delay)}function o(a){var c,h,u,d;if(r.state!==oe)return l();for(c in i)if((d=i[c]).name===r.name){if(d.state===le)return re(o);d.state===ce?(d.state=ue,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete i[c]):+c<e&&(d.state=ue,d.timer.stop(),d.on.call("cancel",t,t.__data__,d.index,d.group),delete i[c])}if(re((function(){r.state===le&&(r.state=ce,r.timer.restart(s,r.delay,r.time),s(a))})),r.state=se,r.on.call("start",t,t.__data__,r.index,r.group),r.state===se){for(r.state=le,n=new Array(u=r.tween.length),c=0,h=-1;c<u;++c)(d=r.tween[c].value.call(t,t.__data__,r.index,r.group))&&(n[++h]=d);n.length=h+1}}function s(e){for(var i=e<r.duration?r.ease.call(null,e/r.duration):(r.timer.restart(l),r.state=he,1),a=-1,o=n.length;++a<o;)n[a].call(t,i);r.state===he&&(r.on.call("end",t,t.__data__,r.index,r.group),l())}function l(){for(var n in r.state=ue,r.timer.stop(),delete i[e],i)return;delete t.__transition}i[e]=r,r.timer=Qt(a,0,r.time)}(t,r,{name:e,index:n,group:i,on:ne,tween:ie,time:a.time,delay:a.delay,duration:a.duration,ease:a.ease,timer:null,state:ae})}function pe(t,e){var r=ge(t,e);if(r.state>ae)throw new Error("too late; already scheduled");return r}function fe(t,e){var r=ge(t,e);if(r.state>le)throw new Error("too late; already running");return r}function ge(t,e){var r=t.__transition;if(!r||!(r=r[e]))throw new Error("transition not found");return r}function me(t,e){return t=+t,e=+e,function(r){return t*(1-r)+e*r}}var ye,xe=180/Math.PI,be={translateX:0,translateY:0,rotate:0,skewX:0,scaleX:1,scaleY:1};function ke(t,e,r,n,i,a){var o,s,l;return(o=Math.sqrt(t*t+e*e))&&(t/=o,e/=o),(l=t*r+e*n)&&(r-=t*l,n-=e*l),(s=Math.sqrt(r*r+n*n))&&(r/=s,n/=s,l/=s),t*n<e*r&&(t=-t,e=-e,l=-l,o=-o),{translateX:i,translateY:a,rotate:Math.atan2(e,t)*xe,skewX:Math.atan(l)*xe,scaleX:o,scaleY:s}}function Ce(t,e,r,n){function i(t){return t.length?t.pop()+" ":""}return function(a,o){var s=[],l=[];return a=t(a),o=t(o),function(t,n,i,a,o,s){if(t!==i||n!==a){var l=o.push("translate(",null,e,null,r);s.push({i:l-4,x:me(t,i)},{i:l-2,x:me(n,a)})}else(i||a)&&o.push("translate("+i+e+a+r)}(a.translateX,a.translateY,o.translateX,o.translateY,s,l),function(t,e,r,a){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),a.push({i:r.push(i(r)+"rotate(",null,n)-2,x:me(t,e)})):e&&r.push(i(r)+"rotate("+e+n)}(a.rotate,o.rotate,s,l),function(t,e,r,a){t!==e?a.push({i:r.push(i(r)+"skewX(",null,n)-2,x:me(t,e)}):e&&r.push(i(r)+"skewX("+e+n)}(a.skewX,o.skewX,s,l),function(t,e,r,n,a,o){if(t!==r||e!==n){var s=a.push(i(a)+"scale(",null,",",null,")");o.push({i:s-4,x:me(t,r)},{i:s-2,x:me(e,n)})}else 1===r&&1===n||a.push(i(a)+"scale("+r+","+n+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,s,l),a=o=null,function(t){for(var e,r=-1,n=l.length;++r<n;)s[(e=l[r]).i]=e.x(t);return s.join("")}}}var we=Ce((function(t){const e=new("function"==typeof DOMMatrix?DOMMatrix:WebKitCSSMatrix)(t+"");return e.isIdentity?be:ke(e.a,e.b,e.c,e.d,e.e,e.f)}),"px, ","px)","deg)"),_e=Ce((function(t){return null==t?be:(ye||(ye=document.createElementNS("http://www.w3.org/2000/svg","g")),ye.setAttribute("transform",t),(t=ye.transform.baseVal.consolidate())?ke((t=t.matrix).a,t.b,t.c,t.d,t.e,t.f):be)}),", ",")",")");function ve(t,e){var r,n;return function(){var i=fe(this,t),a=i.tween;if(a!==r)for(var o=0,s=(n=r=a).length;o<s;++o)if(n[o].name===e){(n=n.slice()).splice(o,1);break}i.tween=n}}function Se(t,e,r){var n,i;if("function"!=typeof r)throw new Error;return function(){var a=fe(this,t),o=a.tween;if(o!==n){i=(n=o).slice();for(var s={name:e,value:r},l=0,c=i.length;l<c;++l)if(i[l].name===e){i[l]=s;break}l===c&&i.push(s)}a.tween=i}}function Ae(t,e,r){var n=t._id;return t.each((function(){var t=fe(this,n);(t.value||(t.value={}))[e]=r.apply(this,arguments)})),function(t){return ge(t,n).value[e]}}function Te(t,e,r){t.prototype=e.prototype=r,r.constructor=t}function Me(t,e){var r=Object.create(t.prototype);for(var n in e)r[n]=e[n];return r}function Be(){}var Le=.7,Fe=1/Le,$e="\\s*([+-]?\\d+)\\s*",Ee="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",Ne="\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",De=/^#([0-9a-f]{3,8})$/,je=new RegExp(`^rgb\\(${$e},${$e},${$e}\\)$`),Ie=new RegExp(`^rgb\\(${Ne},${Ne},${Ne}\\)$`),Oe=new RegExp(`^rgba\\(${$e},${$e},${$e},${Ee}\\)$`),Re=new RegExp(`^rgba\\(${Ne},${Ne},${Ne},${Ee}\\)$`),Pe=new RegExp(`^hsl\\(${Ee},${Ne},${Ne}\\)$`),ze=new RegExp(`^hsla\\(${Ee},${Ne},${Ne},${Ee}\\)$`),Ke={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074};function qe(){return this.rgb().formatHex()}function We(){return this.rgb().formatRgb()}function He(t){var e,r;return t=(t+"").trim().toLowerCase(),(e=De.exec(t))?(r=e[1].length,e=parseInt(e[1],16),6===r?Ue(e):3===r?new Ze(e>>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):8===r?Ye(e>>24&255,e>>16&255,e>>8&255,(255&e)/255):4===r?Ye(e>>12&15|e>>8&240,e>>8&15|e>>4&240,e>>4&15|240&e,((15&e)<<4|15&e)/255):null):(e=je.exec(t))?new Ze(e[1],e[2],e[3],1):(e=Ie.exec(t))?new Ze(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Oe.exec(t))?Ye(e[1],e[2],e[3],e[4]):(e=Re.exec(t))?Ye(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=Pe.exec(t))?rr(e[1],e[2]/100,e[3]/100,1):(e=ze.exec(t))?rr(e[1],e[2]/100,e[3]/100,e[4]):Ke.hasOwnProperty(t)?Ue(Ke[t]):"transparent"===t?new Ze(NaN,NaN,NaN,0):null}function Ue(t){return new Ze(t>>16&255,t>>8&255,255&t,1)}function Ye(t,e,r,n){return n<=0&&(t=e=r=NaN),new Ze(t,e,r,n)}function Ve(t){return t instanceof Be||(t=He(t)),t?new Ze((t=t.rgb()).r,t.g,t.b,t.opacity):new Ze}function Ge(t,e,r,n){return 1===arguments.length?Ve(t):new Ze(t,e,r,null==n?1:n)}function Ze(t,e,r,n){this.r=+t,this.g=+e,this.b=+r,this.opacity=+n}function Xe(){return`#${er(this.r)}${er(this.g)}${er(this.b)}`}function Qe(){const t=Je(this.opacity);return`${1===t?"rgb(":"rgba("}${tr(this.r)}, ${tr(this.g)}, ${tr(this.b)}${1===t?")":`, ${t})`}`}function Je(t){return isNaN(t)?1:Math.max(0,Math.min(1,t))}function tr(t){return Math.max(0,Math.min(255,Math.round(t)||0))}function er(t){return((t=tr(t))<16?"0":"")+t.toString(16)}function rr(t,e,r,n){return n<=0?t=e=r=NaN:r<=0||r>=1?t=e=NaN:e<=0&&(t=NaN),new ir(t,e,r,n)}function nr(t){if(t instanceof ir)return new ir(t.h,t.s,t.l,t.opacity);if(t instanceof Be||(t=He(t)),!t)return new ir;if(t instanceof ir)return t;var e=(t=t.rgb()).r/255,r=t.g/255,n=t.b/255,i=Math.min(e,r,n),a=Math.max(e,r,n),o=NaN,s=a-i,l=(a+i)/2;return s?(o=e===a?(r-n)/s+6*(r<n):r===a?(n-e)/s+2:(e-r)/s+4,s/=l<.5?a+i:2-a-i,o*=60):s=l>0&&l<1?0:o,new ir(o,s,l,t.opacity)}function ir(t,e,r,n){this.h=+t,this.s=+e,this.l=+r,this.opacity=+n}function ar(t){return(t=(t||0)%360)<0?t+360:t}function or(t){return Math.max(0,Math.min(1,t||0))}function sr(t,e,r){return 255*(t<60?e+(r-e)*t/60:t<180?r:t<240?e+(r-e)*(240-t)/60:e)}function lr(t,e,r,n,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*r+(1+3*t+3*a-3*o)*n+o*i)/6}Te(Be,He,{copy(t){return Object.assign(new this.constructor,this,t)},displayable(){return this.rgb().displayable()},hex:qe,formatHex:qe,formatHex8:function(){return this.rgb().formatHex8()},formatHsl:function(){return nr(this).formatHsl()},formatRgb:We,toString:We}),Te(Ze,Ge,Me(Be,{brighter(t){return t=null==t?Fe:Math.pow(Fe,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new Ze(this.r*t,this.g*t,this.b*t,this.opacity)},rgb(){return this},clamp(){return new Ze(tr(this.r),tr(this.g),tr(this.b),Je(this.opacity))},displayable(){return-.5<=this.r&&this.r<255.5&&-.5<=this.g&&this.g<255.5&&-.5<=this.b&&this.b<255.5&&0<=this.opacity&&this.opacity<=1},hex:Xe,formatHex:Xe,formatHex8:function(){return`#${er(this.r)}${er(this.g)}${er(this.b)}${er(255*(isNaN(this.opacity)?1:this.opacity))}`},formatRgb:Qe,toString:Qe})),Te(ir,(function(t,e,r,n){return 1===arguments.length?nr(t):new ir(t,e,r,null==n?1:n)}),Me(Be,{brighter(t){return t=null==t?Fe:Math.pow(Fe,t),new ir(this.h,this.s,this.l*t,this.opacity)},darker(t){return t=null==t?Le:Math.pow(Le,t),new ir(this.h,this.s,this.l*t,this.opacity)},rgb(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,r=this.l,n=r+(r<.5?r:1-r)*e,i=2*r-n;return new Ze(sr(t>=240?t-240:t+120,i,n),sr(t,i,n),sr(t<120?t+240:t-120,i,n),this.opacity)},clamp(){return new ir(ar(this.h),or(this.s),or(this.l),Je(this.opacity))},displayable(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1},formatHsl(){const t=Je(this.opacity);return`${1===t?"hsl(":"hsla("}${ar(this.h)}, ${100*or(this.s)}%, ${100*or(this.l)}%${1===t?")":`, ${t})`}`}}));const cr=t=>()=>t;function hr(t,e){return function(r){return t+r*e}}function ur(t){return 1==(t=+t)?dr:function(e,r){return r-e?function(t,e,r){return t=Math.pow(t,r),e=Math.pow(e,r)-t,r=1/r,function(n){return Math.pow(t+n*e,r)}}(e,r,t):cr(isNaN(e)?r:e)}}function dr(t,e){var r=e-t;return r?hr(t,r):cr(isNaN(t)?e:t)}const pr=function t(e){var r=ur(e);function n(t,e){var n=r((t=Ge(t)).r,(e=Ge(e)).r),i=r(t.g,e.g),a=r(t.b,e.b),o=dr(t.opacity,e.opacity);return function(e){return t.r=n(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return n.gamma=t,n}(1);function fr(t){return function(e){var r,n,i=e.length,a=new Array(i),o=new Array(i),s=new Array(i);for(r=0;r<i;++r)n=Ge(e[r]),a[r]=n.r||0,o[r]=n.g||0,s[r]=n.b||0;return a=t(a),o=t(o),s=t(s),n.opacity=1,function(t){return n.r=a(t),n.g=o(t),n.b=s(t),n+""}}}fr((function(t){var e=t.length-1;return function(r){var n=r<=0?r=0:r>=1?(r=1,e-1):Math.floor(r*e),i=t[n],a=t[n+1],o=n>0?t[n-1]:2*i-a,s=n<e-1?t[n+2]:2*a-i;return lr((r-n/e)*e,o,i,a,s)}})),fr((function(t){var e=t.length;return function(r){var n=Math.floor(((r%=1)<0?++r:r)*e),i=t[(n+e-1)%e],a=t[n%e],o=t[(n+1)%e],s=t[(n+2)%e];return lr((r-n/e)*e,i,a,o,s)}}));var gr=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,mr=new RegExp(gr.source,"g");function yr(t,e){var r,n,i,a=gr.lastIndex=mr.lastIndex=0,o=-1,s=[],l=[];for(t+="",e+="";(r=gr.exec(t))&&(n=mr.exec(e));)(i=n.index)>a&&(i=e.slice(a,i),s[o]?s[o]+=i:s[++o]=i),(r=r[0])===(n=n[0])?s[o]?s[o]+=n:s[++o]=n:(s[++o]=null,l.push({i:o,x:me(r,n)})),a=mr.lastIndex;return a<e.length&&(i=e.slice(a),s[o]?s[o]+=i:s[++o]=i),s.length<2?l[0]?function(t){return function(e){return t(e)+""}}(l[0].x):function(t){return function(){return t}}(e):(e=l.length,function(t){for(var r,n=0;n<e;++n)s[(r=l[n]).i]=r.x(t);return s.join("")})}function xr(t,e){var r;return("number"==typeof e?me:e instanceof He?pr:(r=He(e))?(e=r,pr):yr)(t,e)}function br(t){return function(){this.removeAttribute(t)}}function kr(t){return function(){this.removeAttributeNS(t.space,t.local)}}function Cr(t,e,r){var n,i,a=r+"";return function(){var o=this.getAttribute(t);return o===a?null:o===n?i:i=e(n=o,r)}}function wr(t,e,r){var n,i,a=r+"";return function(){var o=this.getAttributeNS(t.space,t.local);return o===a?null:o===n?i:i=e(n=o,r)}}function _r(t,e,r){var n,i,a;return function(){var o,s,l=r(this);if(null!=l)return(o=this.getAttribute(t))===(s=l+"")?null:o===n&&s===i?a:(i=s,a=e(n=o,l));this.removeAttribute(t)}}function vr(t,e,r){var n,i,a;return function(){var o,s,l=r(this);if(null!=l)return(o=this.getAttributeNS(t.space,t.local))===(s=l+"")?null:o===n&&s===i?a:(i=s,a=e(n=o,l));this.removeAttributeNS(t.space,t.local)}}function Sr(t,e){var r,n;function i(){var i=e.apply(this,arguments);return i!==n&&(r=(n=i)&&function(t,e){return function(r){this.setAttributeNS(t.space,t.local,e.call(this,r))}}(t,i)),r}return i._value=e,i}function Ar(t,e){var r,n;function i(){var i=e.apply(this,arguments);return i!==n&&(r=(n=i)&&function(t,e){return function(r){this.setAttribute(t,e.call(this,r))}}(t,i)),r}return i._value=e,i}function Tr(t,e){return function(){pe(this,t).delay=+e.apply(this,arguments)}}function Mr(t,e){return e=+e,function(){pe(this,t).delay=e}}function Br(t,e){return function(){fe(this,t).duration=+e.apply(this,arguments)}}function Lr(t,e){return e=+e,function(){fe(this,t).duration=e}}var Fr=Ft.prototype.constructor;function $r(t){return function(){this.style.removeProperty(t)}}var Er=0;function Nr(t,e,r,n){this._groups=t,this._parents=e,this._name=r,this._id=n}function Dr(){return++Er}var jr=Ft.prototype;Nr.prototype=function(t){return Ft().transition(t)}.prototype={constructor:Nr,select:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=k(t));for(var n=this._groups,i=n.length,a=new Array(i),o=0;o<i;++o)for(var s,l,c=n[o],h=c.length,u=a[o]=new Array(h),d=0;d<h;++d)(s=c[d])&&(l=t.call(s,s.__data__,d,c))&&("__data__"in s&&(l.__data__=s.__data__),u[d]=l,de(u[d],e,r,d,u,ge(s,r)));return new Nr(a,this._parents,e,r)},selectAll:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=w(t));for(var n=this._groups,i=n.length,a=[],o=[],s=0;s<i;++s)for(var l,c=n[s],h=c.length,u=0;u<h;++u)if(l=c[u]){for(var d,p=t.call(l,l.__data__,u,c),f=ge(l,r),g=0,m=p.length;g<m;++g)(d=p[g])&&de(d,e,r,g,p,f);a.push(p),o.push(l)}return new Nr(a,o,e,r)},selectChild:jr.selectChild,selectChildren:jr.selectChildren,filter:function(t){"function"!=typeof t&&(t=v(t));for(var e=this._groups,r=e.length,n=new Array(r),i=0;i<r;++i)for(var a,o=e[i],s=o.length,l=n[i]=[],c=0;c<s;++c)(a=o[c])&&t.call(a,a.__data__,c,o)&&l.push(a);return new Nr(n,this._parents,this._name,this._id)},merge:function(t){if(t._id!==this._id)throw new Error;for(var e=this._groups,r=t._groups,n=e.length,i=r.length,a=Math.min(n,i),o=new Array(n),s=0;s<a;++s)for(var l,c=e[s],h=r[s],u=c.length,d=o[s]=new Array(u),p=0;p<u;++p)(l=c[p]||h[p])&&(d[p]=l);for(;s<n;++s)o[s]=e[s];return new Nr(o,this._parents,this._name,this._id)},selection:function(){return new Fr(this._groups,this._parents)},transition:function(){for(var t=this._name,e=this._id,r=Dr(),n=this._groups,i=n.length,a=0;a<i;++a)for(var o,s=n[a],l=s.length,c=0;c<l;++c)if(o=s[c]){var h=ge(o,e);de(o,t,r,c,s,{time:h.time+h.delay+h.duration,delay:0,duration:h.duration,ease:h.ease})}return new Nr(n,this._parents,t,r)},call:jr.call,nodes:jr.nodes,node:jr.node,size:jr.size,empty:jr.empty,each:jr.each,on:function(t,e){var r=this._id;return arguments.length<2?ge(this.node(),r).on.on(t):this.each(function(t,e,r){var n,i,a=function(t){return(t+"").trim().split(/^|\s+/).every((function(t){var e=t.indexOf(".");return e>=0&&(t=t.slice(0,e)),!t||"start"===t}))}(e)?pe:fe;return function(){var o=a(this,t),s=o.on;s!==n&&(i=(n=s).copy()).on(e,r),o.on=i}}(r,t,e))},attr:function(t,e){var r=R(t),n="transform"===r?_e:xr;return this.attrTween(t,"function"==typeof e?(r.local?vr:_r)(r,n,Ae(this,"attr."+t,e)):null==e?(r.local?kr:br)(r):(r.local?wr:Cr)(r,n,e))},attrTween:function(t,e){var r="attr."+t;if(arguments.length<2)return(r=this.tween(r))&&r._value;if(null==e)return this.tween(r,null);if("function"!=typeof e)throw new Error;var n=R(t);return this.tween(r,(n.local?Sr:Ar)(n,e))},style:function(t,e,r){var n="transform"==(t+="")?we:xr;return null==e?this.styleTween(t,function(t,e){var r,n,i;return function(){var a=Z(this,t),o=(this.style.removeProperty(t),Z(this,t));return a===o?null:a===r&&o===n?i:i=e(r=a,n=o)}}(t,n)).on("end.style."+t,$r(t)):"function"==typeof e?this.styleTween(t,function(t,e,r){var n,i,a;return function(){var o=Z(this,t),s=r(this),l=s+"";return null==s&&(this.style.removeProperty(t),l=s=Z(this,t)),o===l?null:o===n&&l===i?a:(i=l,a=e(n=o,s))}}(t,n,Ae(this,"style."+t,e))).each(function(t,e){var r,n,i,a,o="style."+e,s="end."+o;return function(){var l=fe(this,t),c=l.on,h=null==l.value[o]?a||(a=$r(e)):void 0;c===r&&i===h||(n=(r=c).copy()).on(s,i=h),l.on=n}}(this._id,t)):this.styleTween(t,function(t,e,r){var n,i,a=r+"";return function(){var o=Z(this,t);return o===a?null:o===n?i:i=e(n=o,r)}}(t,n,e),r).on("end.style."+t,null)},styleTween:function(t,e,r){var n="style."+(t+="");if(arguments.length<2)return(n=this.tween(n))&&n._value;if(null==e)return this.tween(n,null);if("function"!=typeof e)throw new Error;return this.tween(n,function(t,e,r){var n,i;function a(){var a=e.apply(this,arguments);return a!==i&&(n=(i=a)&&function(t,e,r){return function(n){this.style.setProperty(t,e.call(this,n),r)}}(t,a,r)),n}return a._value=e,a}(t,e,null==r?"":r))},text:function(t){return this.tween("text","function"==typeof t?function(t){return function(){var e=t(this);this.textContent=null==e?"":e}}(Ae(this,"text",t)):function(t){return function(){this.textContent=t}}(null==t?"":t+""))},textTween:function(t){var e="text";if(arguments.length<1)return(e=this.tween(e))&&e._value;if(null==t)return this.tween(e,null);if("function"!=typeof t)throw new Error;return this.tween(e,function(t){var e,r;function n(){var n=t.apply(this,arguments);return n!==r&&(e=(r=n)&&function(t){return function(e){this.textContent=t.call(this,e)}}(n)),e}return n._value=t,n}(t))},remove:function(){return this.on("end.remove",function(t){return function(){var e=this.parentNode;for(var r in this.__transition)if(+r!==t)return;e&&e.removeChild(this)}}(this._id))},tween:function(t,e){var r=this._id;if(t+="",arguments.length<2){for(var n,i=ge(this.node(),r).tween,a=0,o=i.length;a<o;++a)if((n=i[a]).name===t)return n.value;return null}return this.each((null==e?ve:Se)(r,t,e))},delay:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Tr:Mr)(e,t)):ge(this.node(),e).delay},duration:function(t){var e=this._id;return arguments.length?this.each(("function"==typeof t?Br:Lr)(e,t)):ge(this.node(),e).duration},ease:function(t){var e=this._id;return arguments.length?this.each(function(t,e){if("function"!=typeof e)throw new Error;return function(){fe(this,t).ease=e}}(e,t)):ge(this.node(),e).ease},easeVarying:function(t){if("function"!=typeof t)throw new Error;return this.each(function(t,e){return function(){var r=e.apply(this,arguments);if("function"!=typeof r)throw new Error;fe(this,t).ease=r}}(this._id,t))},end:function(){var t,e,r=this,n=r._id,i=r.size();return new Promise((function(a,o){var s={value:o},l={value:function(){0==--i&&a()}};r.each((function(){var r=fe(this,n),i=r.on;i!==t&&((e=(t=i).copy())._.cancel.push(s),e._.interrupt.push(s),e._.end.push(l)),r.on=e})),0===i&&a()}))},[Symbol.iterator]:jr[Symbol.iterator]};var Ir={time:null,delay:0,duration:250,ease:function(t){return((t*=2)<=1?t*t*t:(t-=2)*t*t+2)/2}};function Or(t,e){for(var r;!(r=t.__transition)||!(r=r[e]);)if(!(t=t.parentNode))throw new Error(`transition ${e} not found`);return r}Ft.prototype.interrupt=function(t){return this.each((function(){!function(t,e){var r,n,i,a=t.__transition,o=!0;if(a){for(i in e=null==e?null:e+"",a)(r=a[i]).name===e?(n=r.state>se&&r.state<he,r.state=ue,r.timer.stop(),r.on.call(n?"interrupt":"cancel",t,t.__data__,r.index,r.group),delete a[i]):o=!1;o&&delete t.__transition}}(this,t)}))},Ft.prototype.transition=function(t){var e,r;t instanceof Nr?(e=t._id,t=t._name):(e=Dr(),(r=Ir).time=Gt(),t=null==t?null:t+"");for(var n=this._groups,i=n.length,a=0;a<i;++a)for(var o,s=n[a],l=s.length,c=0;c<l;++c)(o=s[c])&&de(o,t,e,c,s,r||Or(o,e));return new Nr(n,this._parents,t,e)};const{abs:Rr,max:Pr,min:zr}=Math;function Kr(t){return[+t[0],+t[1]]}function qr(t){return[Kr(t[0]),Kr(t[1])]}["w","e"].map(Wr),["n","s"].map(Wr),["n","w","e","s","nw","ne","sw","se"].map(Wr);function Wr(t){return{type:t}}const Hr=Math.PI/180,Ur=180/Math.PI,Yr=.96422,Vr=1,Gr=.82521,Zr=4/29,Xr=6/29,Qr=3*Xr*Xr,Jr=Xr*Xr*Xr;function tn(t){if(t instanceof en)return new en(t.l,t.a,t.b,t.opacity);if(t instanceof cn)return hn(t);t instanceof Ze||(t=Ve(t));var e,r,n=on(t.r),i=on(t.g),a=on(t.b),o=rn((.2225045*n+.7168786*i+.0606169*a)/Vr);return n===i&&i===a?e=r=o:(e=rn((.4360747*n+.3850649*i+.1430804*a)/Yr),r=rn((.0139322*n+.0971045*i+.7141733*a)/Gr)),new en(116*o-16,500*(e-o),200*(o-r),t.opacity)}function en(t,e,r,n){this.l=+t,this.a=+e,this.b=+r,this.opacity=+n}function rn(t){return t>Jr?Math.pow(t,1/3):t/Qr+Zr}function nn(t){return t>Xr?t*t*t:Qr*(t-Zr)}function an(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function on(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function sn(t){if(t instanceof cn)return new cn(t.h,t.c,t.l,t.opacity);if(t instanceof en||(t=tn(t)),0===t.a&&0===t.b)return new cn(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*Ur;return new cn(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function ln(t,e,r,n){return 1===arguments.length?sn(t):new cn(t,e,r,null==n?1:n)}function cn(t,e,r,n){this.h=+t,this.c=+e,this.l=+r,this.opacity=+n}function hn(t){if(isNaN(t.h))return new en(t.l,0,0,t.opacity);var e=t.h*Hr;return new en(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}function un(t){return function(e,r){var n=t((e=ln(e)).h,(r=ln(r)).h),i=dr(e.c,r.c),a=dr(e.l,r.l),o=dr(e.opacity,r.opacity);return function(t){return e.h=n(t),e.c=i(t),e.l=a(t),e.opacity=o(t),e+""}}}Te(en,(function(t,e,r,n){return 1===arguments.length?tn(t):new en(t,e,r,null==n?1:n)}),Me(Be,{brighter(t){return new en(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker(t){return new en(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,r=isNaN(this.b)?t:t-this.b/200;return new Ze(an(3.1338561*(e=Yr*nn(e))-1.6168667*(t=Vr*nn(t))-.4906146*(r=Gr*nn(r))),an(-.9787684*e+1.9161415*t+.033454*r),an(.0719453*e-.2289914*t+1.4052427*r),this.opacity)}})),Te(cn,ln,Me(Be,{brighter(t){return new cn(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker(t){return new cn(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb(){return hn(this).rgb()}}));const dn=un((function(t,e){var r=e-t;return r?hr(t,r>180||r<-180?r-360*Math.round(r/360):r):cr(isNaN(t)?e:t)}));un(dr);function pn(t,e){switch(arguments.length){case 0:break;case 1:this.range(t);break;default:this.range(e).domain(t)}return this}class fn extends Map{constructor(t,e=xn){if(super(),Object.defineProperties(this,{_intern:{value:new Map},_key:{value:e}}),null!=t)for(const[r,n]of t)this.set(r,n)}get(t){return super.get(gn(this,t))}has(t){return super.has(gn(this,t))}set(t,e){return super.set(mn(this,t),e)}delete(t){return super.delete(yn(this,t))}}Set;function gn({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):r}function mn({_intern:t,_key:e},r){const n=e(r);return t.has(n)?t.get(n):(t.set(n,r),r)}function yn({_intern:t,_key:e},r){const n=e(r);return t.has(n)&&(r=t.get(n),t.delete(n)),r}function xn(t){return null!==t&&"object"==typeof t?t.valueOf():t}const bn=Symbol("implicit");function kn(){var t=new fn,e=[],r=[],n=bn;function i(i){let a=t.get(i);if(void 0===a){if(n!==bn)return n;t.set(i,a=e.push(i)-1)}return r[a%r.length]}return i.domain=function(r){if(!arguments.length)return e.slice();e=[],t=new fn;for(const n of r)t.has(n)||t.set(n,e.push(n)-1);return i},i.range=function(t){return arguments.length?(r=Array.from(t),i):r.slice()},i.unknown=function(t){return arguments.length?(n=t,i):n},i.copy=function(){return kn(e,r).unknown(n)},pn.apply(i,arguments),i}function Cn(){var t,e,r=kn().unknown(void 0),n=r.domain,i=r.range,a=0,o=1,s=!1,l=0,c=0,h=.5;function u(){var r=n().length,u=o<a,d=u?o:a,p=u?a:o;t=(p-d)/Math.max(1,r-l+2*c),s&&(t=Math.floor(t)),d+=(p-d-t*(r-l))*h,e=t*(1-l),s&&(d=Math.round(d),e=Math.round(e));var f=function(t,e,r){t=+t,e=+e,r=(i=arguments.length)<2?(e=t,t=0,1):i<3?1:+r;for(var n=-1,i=0|Math.max(0,Math.ceil((e-t)/r)),a=new Array(i);++n<i;)a[n]=t+n*r;return a}(r).map((function(e){return d+t*e}));return i(u?f.reverse():f)}return delete r.unknown,r.domain=function(t){return arguments.length?(n(t),u()):n()},r.range=function(t){return arguments.length?([a,o]=t,a=+a,o=+o,u()):[a,o]},r.rangeRound=function(t){return[a,o]=t,a=+a,o=+o,s=!0,u()},r.bandwidth=function(){return e},r.step=function(){return t},r.round=function(t){return arguments.length?(s=!!t,u()):s},r.padding=function(t){return arguments.length?(l=Math.min(1,c=+t),u()):l},r.paddingInner=function(t){return arguments.length?(l=Math.min(1,t),u()):l},r.paddingOuter=function(t){return arguments.length?(c=+t,u()):c},r.align=function(t){return arguments.length?(h=Math.max(0,Math.min(1,t)),u()):h},r.copy=function(){return Cn(n(),[a,o]).round(s).paddingInner(l).paddingOuter(c).align(h)},pn.apply(u(),arguments)}const wn=Math.sqrt(50),_n=Math.sqrt(10),vn=Math.sqrt(2);function Sn(t,e,r){const n=(e-t)/Math.max(0,r),i=Math.floor(Math.log10(n)),a=n/Math.pow(10,i),o=a>=wn?10:a>=_n?5:a>=vn?2:1;let s,l,c;return i<0?(c=Math.pow(10,-i)/o,s=Math.round(t*c),l=Math.round(e*c),s/c<t&&++s,l/c>e&&--l,c=-c):(c=Math.pow(10,i)*o,s=Math.round(t/c),l=Math.round(e/c),s*c<t&&++s,l*c>e&&--l),l<s&&.5<=r&&r<2?Sn(t,e,2*r):[s,l,c]}function An(t,e,r){return Sn(t=+t,e=+e,r=+r)[2]}function Tn(t,e,r){r=+r;const n=(e=+e)<(t=+t),i=n?An(e,t,r):An(t,e,r);return(n?-1:1)*(i<0?1/-i:i)}function Mn(t,e){return null==t||null==e?NaN:t<e?-1:t>e?1:t>=e?0:NaN}function Bn(t,e){return null==t||null==e?NaN:e<t?-1:e>t?1:e>=t?0:NaN}function Ln(t){let e,r,n;function i(t,n,i=0,a=t.length){if(i<a){if(0!==e(n,n))return a;do{const e=i+a>>>1;r(t[e],n)<0?i=e+1:a=e}while(i<a)}return i}return 2!==t.length?(e=Mn,r=(e,r)=>Mn(t(e),r),n=(e,r)=>t(e)-r):(e=t===Mn||t===Bn?t:Fn,r=t,n=t),{left:i,center:function(t,e,r=0,a=t.length){const o=i(t,e,r,a-1);return o>r&&n(t[o-1],e)>-n(t[o],e)?o-1:o},right:function(t,n,i=0,a=t.length){if(i<a){if(0!==e(n,n))return a;do{const e=i+a>>>1;r(t[e],n)<=0?i=e+1:a=e}while(i<a)}return i}}}function Fn(){return 0}const $n=Ln(Mn),En=$n.right,Nn=($n.left,Ln((function(t){return null===t?NaN:+t})).center,En);function Dn(t,e){var r,n=e?e.length:0,i=t?Math.min(n,t.length):0,a=new Array(i),o=new Array(n);for(r=0;r<i;++r)a[r]=Rn(t[r],e[r]);for(;r<n;++r)o[r]=e[r];return function(t){for(r=0;r<i;++r)o[r]=a[r](t);return o}}function jn(t,e){var r=new Date;return t=+t,e=+e,function(n){return r.setTime(t*(1-n)+e*n),r}}function In(t,e){var r,n={},i={};for(r in null!==t&&"object"==typeof t||(t={}),null!==e&&"object"==typeof e||(e={}),e)r in t?n[r]=Rn(t[r],e[r]):i[r]=e[r];return function(t){for(r in n)i[r]=n[r](t);return i}}function On(t,e){e||(e=[]);var r,n=t?Math.min(e.length,t.length):0,i=e.slice();return function(a){for(r=0;r<n;++r)i[r]=t[r]*(1-a)+e[r]*a;return i}}function Rn(t,e){var r,n,i=typeof e;return null==e||"boolean"===i?cr(e):("number"===i?me:"string"===i?(r=He(e))?(e=r,pr):yr:e instanceof He?pr:e instanceof Date?jn:(n=e,!ArrayBuffer.isView(n)||n instanceof DataView?Array.isArray(e)?Dn:"function"!=typeof e.valueOf&&"function"!=typeof e.toString||isNaN(e)?In:me:On))(t,e)}function Pn(t,e){return t=+t,e=+e,function(r){return Math.round(t*(1-r)+e*r)}}function zn(t){return+t}var Kn=[0,1];function qn(t){return t}function Wn(t,e){return(e-=t=+t)?function(r){return(r-t)/e}:(r=isNaN(e)?NaN:.5,function(){return r});var r}function Hn(t,e,r){var n=t[0],i=t[1],a=e[0],o=e[1];return i<n?(n=Wn(i,n),a=r(o,a)):(n=Wn(n,i),a=r(a,o)),function(t){return a(n(t))}}function Un(t,e,r){var n=Math.min(t.length,e.length)-1,i=new Array(n),a=new Array(n),o=-1;for(t[n]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++o<n;)i[o]=Wn(t[o],t[o+1]),a[o]=r(e[o],e[o+1]);return function(e){var r=Nn(t,e,1,n)-1;return a[r](i[r](e))}}function Yn(t,e){return e.domain(t.domain()).range(t.range()).interpolate(t.interpolate()).clamp(t.clamp()).unknown(t.unknown())}function Vn(){var t,e,r,n,i,a,o=Kn,s=Kn,l=Rn,c=qn;function h(){var t,e,r,l=Math.min(o.length,s.length);return c!==qn&&(t=o[0],e=o[l-1],t>e&&(r=t,t=e,e=r),c=function(r){return Math.max(t,Math.min(e,r))}),n=l>2?Un:Hn,i=a=null,u}function u(e){return null==e||isNaN(e=+e)?r:(i||(i=n(o.map(t),s,l)))(t(c(e)))}return u.invert=function(r){return c(e((a||(a=n(s,o.map(t),me)))(r)))},u.domain=function(t){return arguments.length?(o=Array.from(t,zn),h()):o.slice()},u.range=function(t){return arguments.length?(s=Array.from(t),h()):s.slice()},u.rangeRound=function(t){return s=Array.from(t),l=Pn,h()},u.clamp=function(t){return arguments.length?(c=!!t||qn,h()):c!==qn},u.interpolate=function(t){return arguments.length?(l=t,h()):l},u.unknown=function(t){return arguments.length?(r=t,u):r},function(r,n){return t=r,e=n,h()}}function Gn(){return Vn()(qn,qn)}var Zn,Xn=/^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i;function Qn(t){if(!(e=Xn.exec(t)))throw new Error("invalid format: "+t);var e;return new Jn({fill:e[1],align:e[2],sign:e[3],symbol:e[4],zero:e[5],width:e[6],comma:e[7],precision:e[8]&&e[8].slice(1),trim:e[9],type:e[10]})}function Jn(t){this.fill=void 0===t.fill?" ":t.fill+"",this.align=void 0===t.align?">":t.align+"",this.sign=void 0===t.sign?"-":t.sign+"",this.symbol=void 0===t.symbol?"":t.symbol+"",this.zero=!!t.zero,this.width=void 0===t.width?void 0:+t.width,this.comma=!!t.comma,this.precision=void 0===t.precision?void 0:+t.precision,this.trim=!!t.trim,this.type=void 0===t.type?"":t.type+""}function ti(t,e){if((r=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var r,n=t.slice(0,r);return[n.length>1?n[0]+n.slice(2):n,+t.slice(r+1)]}function ei(t){return(t=ti(Math.abs(t)))?t[1]:NaN}function ri(t,e){var r=ti(t,e);if(!r)return t+"";var n=r[0],i=r[1];return i<0?"0."+new Array(-i).join("0")+n:n.length>i+1?n.slice(0,i+1)+"."+n.slice(i+1):n+new Array(i-n.length+2).join("0")}Qn.prototype=Jn.prototype,Jn.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(void 0===this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(void 0===this.precision?"":"."+Math.max(0,0|this.precision))+(this.trim?"~":"")+this.type};const ni={"%":(t,e)=>(100*t).toFixed(e),b:t=>Math.round(t).toString(2),c:t=>t+"",d:function(t){return Math.abs(t=Math.round(t))>=1e21?t.toLocaleString("en").replace(/,/g,""):t.toString(10)},e:(t,e)=>t.toExponential(e),f:(t,e)=>t.toFixed(e),g:(t,e)=>t.toPrecision(e),o:t=>Math.round(t).toString(8),p:(t,e)=>ri(100*t,e),r:ri,s:function(t,e){var r=ti(t,e);if(!r)return t+"";var n=r[0],i=r[1],a=i-(Zn=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=n.length;return a===o?n:a>o?n+new Array(a-o+1).join("0"):a>0?n.slice(0,a)+"."+n.slice(a):"0."+new Array(1-a).join("0")+ti(t,Math.max(0,e+a-1))[0]},X:t=>Math.round(t).toString(16).toUpperCase(),x:t=>Math.round(t).toString(16)};function ii(t){return t}var ai,oi,si,li=Array.prototype.map,ci=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"];function hi(t){var e,r,n=void 0===t.grouping||void 0===t.thousands?ii:(e=li.call(t.grouping,Number),r=t.thousands+"",function(t,n){for(var i=t.length,a=[],o=0,s=e[0],l=0;i>0&&s>0&&(l+s+1>n&&(s=Math.max(1,n-l)),a.push(t.substring(i-=s,i+s)),!((l+=s+1)>n));)s=e[o=(o+1)%e.length];return a.reverse().join(r)}),i=void 0===t.currency?"":t.currency[0]+"",a=void 0===t.currency?"":t.currency[1]+"",o=void 0===t.decimal?".":t.decimal+"",s=void 0===t.numerals?ii:function(t){return function(e){return e.replace(/[0-9]/g,(function(e){return t[+e]}))}}(li.call(t.numerals,String)),l=void 0===t.percent?"%":t.percent+"",c=void 0===t.minus?"\u2212":t.minus+"",h=void 0===t.nan?"NaN":t.nan+"";function u(t){var e=(t=Qn(t)).fill,r=t.align,u=t.sign,d=t.symbol,p=t.zero,f=t.width,g=t.comma,m=t.precision,y=t.trim,x=t.type;"n"===x?(g=!0,x="g"):ni[x]||(void 0===m&&(m=12),y=!0,x="g"),(p||"0"===e&&"="===r)&&(p=!0,e="0",r="=");var b="$"===d?i:"#"===d&&/[boxX]/.test(x)?"0"+x.toLowerCase():"",k="$"===d?a:/[%p]/.test(x)?l:"",C=ni[x],w=/[defgprs%]/.test(x);function _(t){var i,a,l,d=b,_=k;if("c"===x)_=C(t)+_,t="";else{var v=(t=+t)<0||1/t<0;if(t=isNaN(t)?h:C(Math.abs(t),m),y&&(t=function(t){t:for(var e,r=t.length,n=1,i=-1;n<r;++n)switch(t[n]){case".":i=e=n;break;case"0":0===i&&(i=n),e=n;break;default:if(!+t[n])break t;i>0&&(i=0)}return i>0?t.slice(0,i)+t.slice(e+1):t}(t)),v&&0==+t&&"+"!==u&&(v=!1),d=(v?"("===u?u:c:"-"===u||"("===u?"":u)+d,_=("s"===x?ci[8+Zn/3]:"")+_+(v&&"("===u?")":""),w)for(i=-1,a=t.length;++i<a;)if(48>(l=t.charCodeAt(i))||l>57){_=(46===l?o+t.slice(i+1):t.slice(i))+_,t=t.slice(0,i);break}}g&&!p&&(t=n(t,1/0));var S=d.length+t.length+_.length,A=S<f?new Array(f-S+1).join(e):"";switch(g&&p&&(t=n(A+t,A.length?f-_.length:1/0),A=""),r){case"<":t=d+t+_+A;break;case"=":t=d+A+t+_;break;case"^":t=A.slice(0,S=A.length>>1)+d+t+_+A.slice(S);break;default:t=A+d+t+_}return s(t)}return m=void 0===m?6:/[gprs]/.test(x)?Math.max(1,Math.min(21,m)):Math.max(0,Math.min(20,m)),_.toString=function(){return t+""},_}return{format:u,formatPrefix:function(t,e){var r=u(((t=Qn(t)).type="f",t)),n=3*Math.max(-8,Math.min(8,Math.floor(ei(e)/3))),i=Math.pow(10,-n),a=ci[8+n/3];return function(t){return r(i*t)+a}}}}function ui(t,e,r,n){var i,a=Tn(t,e,r);switch((n=Qn(null==n?",f":n)).type){case"s":var o=Math.max(Math.abs(t),Math.abs(e));return null!=n.precision||isNaN(i=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(ei(e)/3)))-ei(Math.abs(t)))}(a,o))||(n.precision=i),si(n,o);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(i=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,ei(e)-ei(t))+1}(a,Math.max(Math.abs(t),Math.abs(e))))||(n.precision=i-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(i=function(t){return Math.max(0,-ei(Math.abs(t)))}(a))||(n.precision=i-2*("%"===n.type))}return oi(n)}function di(t){var e=t.domain;return t.ticks=function(t){var r=e();return function(t,e,r){if(!((r=+r)>0))return[];if((t=+t)==(e=+e))return[t];const n=e<t,[i,a,o]=n?Sn(e,t,r):Sn(t,e,r);if(!(a>=i))return[];const s=a-i+1,l=new Array(s);if(n)if(o<0)for(let c=0;c<s;++c)l[c]=(a-c)/-o;else for(let c=0;c<s;++c)l[c]=(a-c)*o;else if(o<0)for(let c=0;c<s;++c)l[c]=(i+c)/-o;else for(let c=0;c<s;++c)l[c]=(i+c)*o;return l}(r[0],r[r.length-1],null==t?10:t)},t.tickFormat=function(t,r){var n=e();return ui(n[0],n[n.length-1],null==t?10:t,r)},t.nice=function(r){null==r&&(r=10);var n,i,a=e(),o=0,s=a.length-1,l=a[o],c=a[s],h=10;for(c<l&&(i=l,l=c,c=i,i=o,o=s,s=i);h-- >0;){if((i=An(l,c,r))===n)return a[o]=l,a[s]=c,e(a);if(i>0)l=Math.floor(l/i)*i,c=Math.ceil(c/i)*i;else{if(!(i<0))break;l=Math.ceil(l*i)/i,c=Math.floor(c*i)/i}n=i}return t},t}function pi(){var t=Gn();return t.copy=function(){return Yn(t,pi())},pn.apply(t,arguments),di(t)}ai=hi({thousands:",",grouping:[3],currency:["$",""]}),oi=ai.format,si=ai.formatPrefix;const fi=1e3,gi=6e4,mi=36e5,yi=864e5,xi=6048e5,bi=2592e6,ki=31536e6,Ci=new Date,wi=new Date;function _i(t,e,r,n){function i(e){return t(e=0===arguments.length?new Date:new Date(+e)),e}return i.floor=e=>(t(e=new Date(+e)),e),i.ceil=r=>(t(r=new Date(r-1)),e(r,1),t(r),r),i.round=t=>{const e=i(t),r=i.ceil(t);return t-e<r-t?e:r},i.offset=(t,r)=>(e(t=new Date(+t),null==r?1:Math.floor(r)),t),i.range=(r,n,a)=>{const o=[];if(r=i.ceil(r),a=null==a?1:Math.floor(a),!(r<n&&a>0))return o;let s;do{o.push(s=new Date(+r)),e(r,a),t(r)}while(s<r&&r<n);return o},i.filter=r=>_i((e=>{if(e>=e)for(;t(e),!r(e);)e.setTime(e-1)}),((t,n)=>{if(t>=t)if(n<0)for(;++n<=0;)for(;e(t,-1),!r(t););else for(;--n>=0;)for(;e(t,1),!r(t););})),r&&(i.count=(e,n)=>(Ci.setTime(+e),wi.setTime(+n),t(Ci),t(wi),Math.floor(r(Ci,wi))),i.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(n?e=>n(e)%t==0:e=>i.count(0,e)%t==0):i:null)),i}const vi=_i((()=>{}),((t,e)=>{t.setTime(+t+e)}),((t,e)=>e-t));vi.every=t=>(t=Math.floor(t),isFinite(t)&&t>0?t>1?_i((e=>{e.setTime(Math.floor(e/t)*t)}),((e,r)=>{e.setTime(+e+r*t)}),((e,r)=>(r-e)/t)):vi:null);vi.range;const Si=_i((t=>{t.setTime(t-t.getMilliseconds())}),((t,e)=>{t.setTime(+t+e*fi)}),((t,e)=>(e-t)/fi),(t=>t.getUTCSeconds())),Ai=(Si.range,_i((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*fi)}),((t,e)=>{t.setTime(+t+e*gi)}),((t,e)=>(e-t)/gi),(t=>t.getMinutes()))),Ti=(Ai.range,_i((t=>{t.setUTCSeconds(0,0)}),((t,e)=>{t.setTime(+t+e*gi)}),((t,e)=>(e-t)/gi),(t=>t.getUTCMinutes()))),Mi=(Ti.range,_i((t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*fi-t.getMinutes()*gi)}),((t,e)=>{t.setTime(+t+e*mi)}),((t,e)=>(e-t)/mi),(t=>t.getHours()))),Bi=(Mi.range,_i((t=>{t.setUTCMinutes(0,0,0)}),((t,e)=>{t.setTime(+t+e*mi)}),((t,e)=>(e-t)/mi),(t=>t.getUTCHours()))),Li=(Bi.range,_i((t=>t.setHours(0,0,0,0)),((t,e)=>t.setDate(t.getDate()+e)),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*gi)/yi),(t=>t.getDate()-1))),Fi=(Li.range,_i((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/yi),(t=>t.getUTCDate()-1))),$i=(Fi.range,_i((t=>{t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+e)}),((t,e)=>(e-t)/yi),(t=>Math.floor(t/yi))));$i.range;function Ei(t){return _i((e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)}),((t,e)=>{t.setDate(t.getDate()+7*e)}),((t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*gi)/xi))}const Ni=Ei(0),Di=Ei(1),ji=Ei(2),Ii=Ei(3),Oi=Ei(4),Ri=Ei(5),Pi=Ei(6);Ni.range,Di.range,ji.range,Ii.range,Oi.range,Ri.range,Pi.range;function zi(t){return _i((e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCDate(t.getUTCDate()+7*e)}),((t,e)=>(e-t)/xi))}const Ki=zi(0),qi=zi(1),Wi=zi(2),Hi=zi(3),Ui=zi(4),Yi=zi(5),Vi=zi(6),Gi=(Ki.range,qi.range,Wi.range,Hi.range,Ui.range,Yi.range,Vi.range,_i((t=>{t.setDate(1),t.setHours(0,0,0,0)}),((t,e)=>{t.setMonth(t.getMonth()+e)}),((t,e)=>e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())),(t=>t.getMonth()))),Zi=(Gi.range,_i((t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)}),((t,e)=>e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())),(t=>t.getUTCMonth()))),Xi=(Zi.range,_i((t=>{t.setMonth(0,1),t.setHours(0,0,0,0)}),((t,e)=>{t.setFullYear(t.getFullYear()+e)}),((t,e)=>e.getFullYear()-t.getFullYear()),(t=>t.getFullYear())));Xi.every=t=>isFinite(t=Math.floor(t))&&t>0?_i((e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)}),((e,r)=>{e.setFullYear(e.getFullYear()+r*t)})):null;Xi.range;const Qi=_i((t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),((t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)}),((t,e)=>e.getUTCFullYear()-t.getUTCFullYear()),(t=>t.getUTCFullYear()));Qi.every=t=>isFinite(t=Math.floor(t))&&t>0?_i((e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),((e,r)=>{e.setUTCFullYear(e.getUTCFullYear()+r*t)})):null;Qi.range;function Ji(t,e,r,n,i,a){const o=[[Si,1,fi],[Si,5,5e3],[Si,15,15e3],[Si,30,3e4],[a,1,gi],[a,5,3e5],[a,15,9e5],[a,30,18e5],[i,1,mi],[i,3,108e5],[i,6,216e5],[i,12,432e5],[n,1,yi],[n,2,1728e5],[r,1,xi],[e,1,bi],[e,3,7776e6],[t,1,ki]];function s(e,r,n){const i=Math.abs(r-e)/n,a=Ln((([,,t])=>t)).right(o,i);if(a===o.length)return t.every(Tn(e/ki,r/ki,n));if(0===a)return vi.every(Math.max(Tn(e,r,n),1));const[s,l]=o[i/o[a-1][2]<o[a][2]/i?a-1:a];return s.every(l)}return[function(t,e,r){const n=e<t;n&&([t,e]=[e,t]);const i=r&&"function"==typeof r.range?r:s(t,e,r),a=i?i.range(t,+e+1):[];return n?a.reverse():a},s]}const[ta,ea]=Ji(Qi,Zi,Ki,$i,Bi,Ti),[ra,na]=Ji(Xi,Gi,Ni,Li,Mi,Ai);function ia(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function aa(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function oa(t,e,r){return{y:t,m:e,d:r,H:0,M:0,S:0,L:0}}var sa,la,ca={"-":"",_:" ",0:"0"},ha=/^\s*\d+/,ua=/^%/,da=/[\\^$*+?|[\]().{}]/g;function pa(t,e,r){var n=t<0?"-":"",i=(n?-t:t)+"",a=i.length;return n+(a<r?new Array(r-a+1).join(e)+i:i)}function fa(t){return t.replace(da,"\\$&")}function ga(t){return new RegExp("^(?:"+t.map(fa).join("|")+")","i")}function ma(t){return new Map(t.map(((t,e)=>[t.toLowerCase(),e])))}function ya(t,e,r){var n=ha.exec(e.slice(r,r+1));return n?(t.w=+n[0],r+n[0].length):-1}function xa(t,e,r){var n=ha.exec(e.slice(r,r+1));return n?(t.u=+n[0],r+n[0].length):-1}function ba(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.U=+n[0],r+n[0].length):-1}function ka(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.V=+n[0],r+n[0].length):-1}function Ca(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.W=+n[0],r+n[0].length):-1}function wa(t,e,r){var n=ha.exec(e.slice(r,r+4));return n?(t.y=+n[0],r+n[0].length):-1}function _a(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.y=+n[0]+(+n[0]>68?1900:2e3),r+n[0].length):-1}function va(t,e,r){var n=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(r,r+6));return n?(t.Z=n[1]?0:-(n[2]+(n[3]||"00")),r+n[0].length):-1}function Sa(t,e,r){var n=ha.exec(e.slice(r,r+1));return n?(t.q=3*n[0]-3,r+n[0].length):-1}function Aa(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.m=n[0]-1,r+n[0].length):-1}function Ta(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.d=+n[0],r+n[0].length):-1}function Ma(t,e,r){var n=ha.exec(e.slice(r,r+3));return n?(t.m=0,t.d=+n[0],r+n[0].length):-1}function Ba(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.H=+n[0],r+n[0].length):-1}function La(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.M=+n[0],r+n[0].length):-1}function Fa(t,e,r){var n=ha.exec(e.slice(r,r+2));return n?(t.S=+n[0],r+n[0].length):-1}function $a(t,e,r){var n=ha.exec(e.slice(r,r+3));return n?(t.L=+n[0],r+n[0].length):-1}function Ea(t,e,r){var n=ha.exec(e.slice(r,r+6));return n?(t.L=Math.floor(n[0]/1e3),r+n[0].length):-1}function Na(t,e,r){var n=ua.exec(e.slice(r,r+1));return n?r+n[0].length:-1}function Da(t,e,r){var n=ha.exec(e.slice(r));return n?(t.Q=+n[0],r+n[0].length):-1}function ja(t,e,r){var n=ha.exec(e.slice(r));return n?(t.s=+n[0],r+n[0].length):-1}function Ia(t,e){return pa(t.getDate(),e,2)}function Oa(t,e){return pa(t.getHours(),e,2)}function Ra(t,e){return pa(t.getHours()%12||12,e,2)}function Pa(t,e){return pa(1+Li.count(Xi(t),t),e,3)}function za(t,e){return pa(t.getMilliseconds(),e,3)}function Ka(t,e){return za(t,e)+"000"}function qa(t,e){return pa(t.getMonth()+1,e,2)}function Wa(t,e){return pa(t.getMinutes(),e,2)}function Ha(t,e){return pa(t.getSeconds(),e,2)}function Ua(t){var e=t.getDay();return 0===e?7:e}function Ya(t,e){return pa(Ni.count(Xi(t)-1,t),e,2)}function Va(t){var e=t.getDay();return e>=4||0===e?Oi(t):Oi.ceil(t)}function Ga(t,e){return t=Va(t),pa(Oi.count(Xi(t),t)+(4===Xi(t).getDay()),e,2)}function Za(t){return t.getDay()}function Xa(t,e){return pa(Di.count(Xi(t)-1,t),e,2)}function Qa(t,e){return pa(t.getFullYear()%100,e,2)}function Ja(t,e){return pa((t=Va(t)).getFullYear()%100,e,2)}function to(t,e){return pa(t.getFullYear()%1e4,e,4)}function eo(t,e){var r=t.getDay();return pa((t=r>=4||0===r?Oi(t):Oi.ceil(t)).getFullYear()%1e4,e,4)}function ro(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+pa(e/60|0,"0",2)+pa(e%60,"0",2)}function no(t,e){return pa(t.getUTCDate(),e,2)}function io(t,e){return pa(t.getUTCHours(),e,2)}function ao(t,e){return pa(t.getUTCHours()%12||12,e,2)}function oo(t,e){return pa(1+Fi.count(Qi(t),t),e,3)}function so(t,e){return pa(t.getUTCMilliseconds(),e,3)}function lo(t,e){return so(t,e)+"000"}function co(t,e){return pa(t.getUTCMonth()+1,e,2)}function ho(t,e){return pa(t.getUTCMinutes(),e,2)}function uo(t,e){return pa(t.getUTCSeconds(),e,2)}function po(t){var e=t.getUTCDay();return 0===e?7:e}function fo(t,e){return pa(Ki.count(Qi(t)-1,t),e,2)}function go(t){var e=t.getUTCDay();return e>=4||0===e?Ui(t):Ui.ceil(t)}function mo(t,e){return t=go(t),pa(Ui.count(Qi(t),t)+(4===Qi(t).getUTCDay()),e,2)}function yo(t){return t.getUTCDay()}function xo(t,e){return pa(qi.count(Qi(t)-1,t),e,2)}function bo(t,e){return pa(t.getUTCFullYear()%100,e,2)}function ko(t,e){return pa((t=go(t)).getUTCFullYear()%100,e,2)}function Co(t,e){return pa(t.getUTCFullYear()%1e4,e,4)}function wo(t,e){var r=t.getUTCDay();return pa((t=r>=4||0===r?Ui(t):Ui.ceil(t)).getUTCFullYear()%1e4,e,4)}function _o(){return"+0000"}function vo(){return"%"}function So(t){return+t}function Ao(t){return Math.floor(+t/1e3)}function To(t){return new Date(t)}function Mo(t){return t instanceof Date?+t:+new Date(+t)}function Bo(t,e,r,n,i,a,o,s,l,c){var h=Gn(),u=h.invert,d=h.domain,p=c(".%L"),f=c(":%S"),g=c("%I:%M"),m=c("%I %p"),y=c("%a %d"),x=c("%b %d"),b=c("%B"),k=c("%Y");function C(t){return(l(t)<t?p:s(t)<t?f:o(t)<t?g:a(t)<t?m:n(t)<t?i(t)<t?y:x:r(t)<t?b:k)(t)}return h.invert=function(t){return new Date(u(t))},h.domain=function(t){return arguments.length?d(Array.from(t,Mo)):d().map(To)},h.ticks=function(e){var r=d();return t(r[0],r[r.length-1],null==e?10:e)},h.tickFormat=function(t,e){return null==e?C:c(e)},h.nice=function(t){var r=d();return t&&"function"==typeof t.range||(t=e(r[0],r[r.length-1],null==t?10:t)),t?d(function(t,e){var r,n=0,i=(t=t.slice()).length-1,a=t[n],o=t[i];return o<a&&(r=n,n=i,i=r,r=a,a=o,o=r),t[n]=e.floor(a),t[i]=e.ceil(o),t}(r,t)):h},h.copy=function(){return Yn(h,Bo(t,e,r,n,i,a,o,s,l,c))},h}function Lo(){return pn.apply(Bo(ra,na,Xi,Gi,Ni,Li,Mi,Ai,Si,la).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}!function(t){sa=function(t){var e=t.dateTime,r=t.date,n=t.time,i=t.periods,a=t.days,o=t.shortDays,s=t.months,l=t.shortMonths,c=ga(i),h=ma(i),u=ga(a),d=ma(a),p=ga(o),f=ma(o),g=ga(s),m=ma(s),y=ga(l),x=ma(l),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return l[t.getMonth()]},B:function(t){return s[t.getMonth()]},c:null,d:Ia,e:Ia,f:Ka,g:Ja,G:eo,H:Oa,I:Ra,j:Pa,L:za,m:qa,M:Wa,p:function(t){return i[+(t.getHours()>=12)]},q:function(t){return 1+~~(t.getMonth()/3)},Q:So,s:Ao,S:Ha,u:Ua,U:Ya,V:Ga,w:Za,W:Xa,x:null,X:null,y:Qa,Y:to,Z:ro,"%":vo},k={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return l[t.getUTCMonth()]},B:function(t){return s[t.getUTCMonth()]},c:null,d:no,e:no,f:lo,g:ko,G:wo,H:io,I:ao,j:oo,L:so,m:co,M:ho,p:function(t){return i[+(t.getUTCHours()>=12)]},q:function(t){return 1+~~(t.getUTCMonth()/3)},Q:So,s:Ao,S:uo,u:po,U:fo,V:mo,w:yo,W:xo,x:null,X:null,y:bo,Y:Co,Z:_o,"%":vo},C={a:function(t,e,r){var n=p.exec(e.slice(r));return n?(t.w=f.get(n[0].toLowerCase()),r+n[0].length):-1},A:function(t,e,r){var n=u.exec(e.slice(r));return n?(t.w=d.get(n[0].toLowerCase()),r+n[0].length):-1},b:function(t,e,r){var n=y.exec(e.slice(r));return n?(t.m=x.get(n[0].toLowerCase()),r+n[0].length):-1},B:function(t,e,r){var n=g.exec(e.slice(r));return n?(t.m=m.get(n[0].toLowerCase()),r+n[0].length):-1},c:function(t,r,n){return v(t,e,r,n)},d:Ta,e:Ta,f:Ea,g:_a,G:wa,H:Ba,I:Ba,j:Ma,L:$a,m:Aa,M:La,p:function(t,e,r){var n=c.exec(e.slice(r));return n?(t.p=h.get(n[0].toLowerCase()),r+n[0].length):-1},q:Sa,Q:Da,s:ja,S:Fa,u:xa,U:ba,V:ka,w:ya,W:Ca,x:function(t,e,n){return v(t,r,e,n)},X:function(t,e,r){return v(t,n,e,r)},y:_a,Y:wa,Z:va,"%":Na};function w(t,e){return function(r){var n,i,a,o=[],s=-1,l=0,c=t.length;for(r instanceof Date||(r=new Date(+r));++s<c;)37===t.charCodeAt(s)&&(o.push(t.slice(l,s)),null!=(i=ca[n=t.charAt(++s)])?n=t.charAt(++s):i="e"===n?" ":"0",(a=e[n])&&(n=a(r,i)),o.push(n),l=s+1);return o.push(t.slice(l,s)),o.join("")}}function _(t,e){return function(r){var n,i,a=oa(1900,void 0,1);if(v(a,t,r+="",0)!=r.length)return null;if("Q"in a)return new Date(a.Q);if("s"in a)return new Date(1e3*a.s+("L"in a?a.L:0));if(e&&!("Z"in a)&&(a.Z=0),"p"in a&&(a.H=a.H%12+12*a.p),void 0===a.m&&(a.m="q"in a?a.q:0),"V"in a){if(a.V<1||a.V>53)return null;"w"in a||(a.w=1),"Z"in a?(i=(n=aa(oa(a.y,0,1))).getUTCDay(),n=i>4||0===i?qi.ceil(n):qi(n),n=Fi.offset(n,7*(a.V-1)),a.y=n.getUTCFullYear(),a.m=n.getUTCMonth(),a.d=n.getUTCDate()+(a.w+6)%7):(i=(n=ia(oa(a.y,0,1))).getDay(),n=i>4||0===i?Di.ceil(n):Di(n),n=Li.offset(n,7*(a.V-1)),a.y=n.getFullYear(),a.m=n.getMonth(),a.d=n.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?aa(oa(a.y,0,1)).getUTCDay():ia(oa(a.y,0,1)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,aa(a)):ia(a)}}function v(t,e,r,n){for(var i,a,o=0,s=e.length,l=r.length;o<s;){if(n>=l)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=C[i in ca?e.charAt(o++):i])||(n=a(t,r,n))<0)return-1}else if(i!=r.charCodeAt(n++))return-1}return n}return b.x=w(r,b),b.X=w(n,b),b.c=w(e,b),k.x=w(r,k),k.X=w(n,k),k.c=w(e,k),{format:function(t){var e=w(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=_(t+="",!1);return e.toString=function(){return t},e},utcFormat:function(t){var e=w(t+="",k);return e.toString=function(){return t},e},utcParse:function(t){var e=_(t+="",!0);return e.toString=function(){return t},e}}}(t),la=sa.format,sa.parse,sa.utcFormat,sa.utcParse}({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});const Fo=function(t){for(var e=t.length/6|0,r=new Array(e),n=0;n<e;)r[n]="#"+t.slice(6*n,6*++n);return r}("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function $o(t){return"string"==typeof t?new Bt([[document.querySelector(t)]],[document.documentElement]):new Bt([[t]],Mt)}function Eo(t){return function(){return t}}const No=Math.abs,Do=Math.atan2,jo=Math.cos,Io=Math.max,Oo=Math.min,Ro=Math.sin,Po=Math.sqrt,zo=1e-12,Ko=Math.PI,qo=Ko/2,Wo=2*Ko;function Ho(t){return t>=1?qo:t<=-1?-qo:Math.asin(t)}const Uo=Math.PI,Yo=2*Uo,Vo=1e-6,Go=Yo-Vo;function Zo(t){this._+=t[0];for(let e=1,r=t.length;e<r;++e)this._+=arguments[e]+t[e]}class Xo{constructor(t){this._x0=this._y0=this._x1=this._y1=null,this._="",this._append=null==t?Zo:function(t){let e=Math.floor(t);if(!(e>=0))throw new Error(`invalid digits: ${t}`);if(e>15)return Zo;const r=10**e;return function(t){this._+=t[0];for(let e=1,n=t.length;e<n;++e)this._+=Math.round(arguments[e]*r)/r+t[e]}}(t)}moveTo(t,e){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}`}closePath(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._append`Z`)}lineTo(t,e){this._append`L${this._x1=+t},${this._y1=+e}`}quadraticCurveTo(t,e,r,n){this._append`Q${+t},${+e},${this._x1=+r},${this._y1=+n}`}bezierCurveTo(t,e,r,n,i,a){this._append`C${+t},${+e},${+r},${+n},${this._x1=+i},${this._y1=+a}`}arcTo(t,e,r,n,i){if(t=+t,e=+e,r=+r,n=+n,(i=+i)<0)throw new Error(`negative radius: ${i}`);let a=this._x1,o=this._y1,s=r-t,l=n-e,c=a-t,h=o-e,u=c*c+h*h;if(null===this._x1)this._append`M${this._x1=t},${this._y1=e}`;else if(u>Vo)if(Math.abs(h*s-l*c)>Vo&&i){let d=r-a,p=n-o,f=s*s+l*l,g=d*d+p*p,m=Math.sqrt(f),y=Math.sqrt(u),x=i*Math.tan((Uo-Math.acos((f+u-g)/(2*m*y)))/2),b=x/y,k=x/m;Math.abs(b-1)>Vo&&this._append`L${t+b*c},${e+b*h}`,this._append`A${i},${i},0,0,${+(h*d>c*p)},${this._x1=t+k*s},${this._y1=e+k*l}`}else this._append`L${this._x1=t},${this._y1=e}`;else;}arc(t,e,r,n,i,a){if(t=+t,e=+e,a=!!a,(r=+r)<0)throw new Error(`negative radius: ${r}`);let o=r*Math.cos(n),s=r*Math.sin(n),l=t+o,c=e+s,h=1^a,u=a?n-i:i-n;null===this._x1?this._append`M${l},${c}`:(Math.abs(this._x1-l)>Vo||Math.abs(this._y1-c)>Vo)&&this._append`L${l},${c}`,r&&(u<0&&(u=u%Yo+Yo),u>Go?this._append`A${r},${r},0,1,${h},${t-o},${e-s}A${r},${r},0,1,${h},${this._x1=l},${this._y1=c}`:u>Vo&&this._append`A${r},${r},0,${+(u>=Uo)},${h},${this._x1=t+r*Math.cos(i)},${this._y1=e+r*Math.sin(i)}`)}rect(t,e,r,n){this._append`M${this._x0=this._x1=+t},${this._y0=this._y1=+e}h${r=+r}v${+n}h${-r}Z`}toString(){return this._}}function Qo(t){let e=3;return t.digits=function(r){if(!arguments.length)return e;if(null==r)e=null;else{const t=Math.floor(r);if(!(t>=0))throw new RangeError(`invalid digits: ${r}`);e=t}return t},()=>new Xo(e)}function Jo(t){return t.innerRadius}function ts(t){return t.outerRadius}function es(t){return t.startAngle}function rs(t){return t.endAngle}function ns(t){return t&&t.padAngle}function is(t,e,r,n,i,a,o){var s=t-r,l=e-n,c=(o?a:-a)/Po(s*s+l*l),h=c*l,u=-c*s,d=t+h,p=e+u,f=r+h,g=n+u,m=(d+f)/2,y=(p+g)/2,x=f-d,b=g-p,k=x*x+b*b,C=i-a,w=d*g-f*p,_=(b<0?-1:1)*Po(Io(0,C*C*k-w*w)),v=(w*b-x*_)/k,S=(-w*x-b*_)/k,A=(w*b+x*_)/k,T=(-w*x+b*_)/k,M=v-m,B=S-y,L=A-m,F=T-y;return M*M+B*B>L*L+F*F&&(v=A,S=T),{cx:v,cy:S,x01:-h,y01:-u,x11:v*(i/C-1),y11:S*(i/C-1)}}function as(){var t=Jo,e=ts,r=Eo(0),n=null,i=es,a=rs,o=ns,s=null,l=Qo(c);function c(){var c,h,u,d=+t.apply(this,arguments),p=+e.apply(this,arguments),f=i.apply(this,arguments)-qo,g=a.apply(this,arguments)-qo,m=No(g-f),y=g>f;if(s||(s=c=l()),p<d&&(h=p,p=d,d=h),p>zo)if(m>Wo-zo)s.moveTo(p*jo(f),p*Ro(f)),s.arc(0,0,p,f,g,!y),d>zo&&(s.moveTo(d*jo(g),d*Ro(g)),s.arc(0,0,d,g,f,y));else{var x,b,k=f,C=g,w=f,_=g,v=m,S=m,A=o.apply(this,arguments)/2,T=A>zo&&(n?+n.apply(this,arguments):Po(d*d+p*p)),M=Oo(No(p-d)/2,+r.apply(this,arguments)),B=M,L=M;if(T>zo){var F=Ho(T/d*Ro(A)),$=Ho(T/p*Ro(A));(v-=2*F)>zo?(w+=F*=y?1:-1,_-=F):(v=0,w=_=(f+g)/2),(S-=2*$)>zo?(k+=$*=y?1:-1,C-=$):(S=0,k=C=(f+g)/2)}var E=p*jo(k),N=p*Ro(k),D=d*jo(_),j=d*Ro(_);if(M>zo){var I,O=p*jo(C),R=p*Ro(C),P=d*jo(w),z=d*Ro(w);if(m<Ko)if(I=function(t,e,r,n,i,a,o,s){var l=r-t,c=n-e,h=o-i,u=s-a,d=u*l-h*c;if(!(d*d<zo))return[t+(d=(h*(e-a)-u*(t-i))/d)*l,e+d*c]}(E,N,P,z,O,R,D,j)){var K=E-I[0],q=N-I[1],W=O-I[0],H=R-I[1],U=1/Ro(((u=(K*W+q*H)/(Po(K*K+q*q)*Po(W*W+H*H)))>1?0:u<-1?Ko:Math.acos(u))/2),Y=Po(I[0]*I[0]+I[1]*I[1]);B=Oo(M,(d-Y)/(U-1)),L=Oo(M,(p-Y)/(U+1))}else B=L=0}S>zo?L>zo?(x=is(P,z,E,N,p,L,y),b=is(O,R,D,j,p,L,y),s.moveTo(x.cx+x.x01,x.cy+x.y01),L<M?s.arc(x.cx,x.cy,L,Do(x.y01,x.x01),Do(b.y01,b.x01),!y):(s.arc(x.cx,x.cy,L,Do(x.y01,x.x01),Do(x.y11,x.x11),!y),s.arc(0,0,p,Do(x.cy+x.y11,x.cx+x.x11),Do(b.cy+b.y11,b.cx+b.x11),!y),s.arc(b.cx,b.cy,L,Do(b.y11,b.x11),Do(b.y01,b.x01),!y))):(s.moveTo(E,N),s.arc(0,0,p,k,C,!y)):s.moveTo(E,N),d>zo&&v>zo?B>zo?(x=is(D,j,O,R,d,-B,y),b=is(E,N,P,z,d,-B,y),s.lineTo(x.cx+x.x01,x.cy+x.y01),B<M?s.arc(x.cx,x.cy,B,Do(x.y01,x.x01),Do(b.y01,b.x01),!y):(s.arc(x.cx,x.cy,B,Do(x.y01,x.x01),Do(x.y11,x.x11),!y),s.arc(0,0,d,Do(x.cy+x.y11,x.cx+x.x11),Do(b.cy+b.y11,b.cx+b.x11),y),s.arc(b.cx,b.cy,B,Do(b.y11,b.x11),Do(b.y01,b.x01),!y))):s.arc(0,0,d,_,w,y):s.lineTo(D,j)}else s.moveTo(0,0);if(s.closePath(),c)return s=null,c+""||null}return c.centroid=function(){var r=(+t.apply(this,arguments)+ +e.apply(this,arguments))/2,n=(+i.apply(this,arguments)+ +a.apply(this,arguments))/2-Ko/2;return[jo(n)*r,Ro(n)*r]},c.innerRadius=function(e){return arguments.length?(t="function"==typeof e?e:Eo(+e),c):t},c.outerRadius=function(t){return arguments.length?(e="function"==typeof t?t:Eo(+t),c):e},c.cornerRadius=function(t){return arguments.length?(r="function"==typeof t?t:Eo(+t),c):r},c.padRadius=function(t){return arguments.length?(n=null==t?null:"function"==typeof t?t:Eo(+t),c):n},c.startAngle=function(t){return arguments.length?(i="function"==typeof t?t:Eo(+t),c):i},c.endAngle=function(t){return arguments.length?(a="function"==typeof t?t:Eo(+t),c):a},c.padAngle=function(t){return arguments.length?(o="function"==typeof t?t:Eo(+t),c):o},c.context=function(t){return arguments.length?(s=null==t?null:t,c):s},c}Xo.prototype;Array.prototype.slice;function os(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function ss(t){this._context=t}function ls(t){return new ss(t)}function cs(t){return t[0]}function hs(t){return t[1]}function us(t,e){var r=Eo(!0),n=null,i=ls,a=null,o=Qo(s);function s(s){var l,c,h,u=(s=os(s)).length,d=!1;for(null==n&&(a=i(h=o())),l=0;l<=u;++l)!(l<u&&r(c=s[l],l,s))===d&&((d=!d)?a.lineStart():a.lineEnd()),d&&a.point(+t(c,l,s),+e(c,l,s));if(h)return a=null,h+""||null}return t="function"==typeof t?t:void 0===t?cs:Eo(t),e="function"==typeof e?e:void 0===e?hs:Eo(e),s.x=function(e){return arguments.length?(t="function"==typeof e?e:Eo(+e),s):t},s.y=function(t){return arguments.length?(e="function"==typeof t?t:Eo(+t),s):e},s.defined=function(t){return arguments.length?(r="function"==typeof t?t:Eo(!!t),s):r},s.curve=function(t){return arguments.length?(i=t,null!=n&&(a=i(n)),s):i},s.context=function(t){return arguments.length?(null==t?n=a=null:a=i(n=t),s):n},s}function ds(t,e){return e<t?-1:e>t?1:e>=t?0:NaN}function ps(t){return t}function fs(){var t=ps,e=ds,r=null,n=Eo(0),i=Eo(Wo),a=Eo(0);function o(o){var s,l,c,h,u,d=(o=os(o)).length,p=0,f=new Array(d),g=new Array(d),m=+n.apply(this,arguments),y=Math.min(Wo,Math.max(-Wo,i.apply(this,arguments)-m)),x=Math.min(Math.abs(y)/d,a.apply(this,arguments)),b=x*(y<0?-1:1);for(s=0;s<d;++s)(u=g[f[s]=s]=+t(o[s],s,o))>0&&(p+=u);for(null!=e?f.sort((function(t,r){return e(g[t],g[r])})):null!=r&&f.sort((function(t,e){return r(o[t],o[e])})),s=0,c=p?(y-d*b)/p:0;s<d;++s,m=h)l=f[s],h=m+((u=g[l])>0?u*c:0)+b,g[l]={data:o[l],index:s,value:u,startAngle:m,endAngle:h,padAngle:x};return g}return o.value=function(e){return arguments.length?(t="function"==typeof e?e:Eo(+e),o):t},o.sortValues=function(t){return arguments.length?(e=t,r=null,o):e},o.sort=function(t){return arguments.length?(r=t,e=null,o):r},o.startAngle=function(t){return arguments.length?(n="function"==typeof t?t:Eo(+t),o):n},o.endAngle=function(t){return arguments.length?(i="function"==typeof t?t:Eo(+t),o):i},o.padAngle=function(t){return arguments.length?(a="function"==typeof t?t:Eo(+t),o):a},o}function gs(){}function ms(t,e,r){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+r)/6)}function ys(t){this._context=t}function xs(t){return new ys(t)}function bs(t){this._context=t}function ks(t){return new bs(t)}function Cs(t){this._context=t}function ws(t){return new Cs(t)}ss.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}},ys.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:ms(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:ms(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},bs.prototype={areaStart:gs,areaEnd:gs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:ms(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}},Cs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var r=(this._x0+4*this._x1+t)/6,n=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(r,n):this._context.moveTo(r,n);break;case 3:this._point=4;default:ms(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};class _s{constructor(t,e){this._context=t,this._x=e}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,e,t,e):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+e)/2,t,this._y0,t,e)}this._x0=t,this._y0=e}}function vs(t){return new _s(t,!0)}function Ss(t){return new _s(t,!1)}function As(t,e){this._basis=new ys(t),this._beta=e}As.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,r=t.length-1;if(r>0)for(var n,i=t[0],a=e[0],o=t[r]-i,s=e[r]-a,l=-1;++l<=r;)n=l/r,this._basis.point(this._beta*t[l]+(1-this._beta)*(i+n*o),this._beta*e[l]+(1-this._beta)*(a+n*s));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};const Ts=function t(e){function r(t){return 1===e?new ys(t):new As(t,e)}return r.beta=function(e){return t(+e)},r}(.85);function Ms(t,e,r){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-r),t._x2,t._y2)}function Bs(t,e){this._context=t,this._k=(1-e)/6}Bs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:Ms(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:Ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ls=function t(e){function r(t){return new Bs(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Fs(t,e){this._context=t,this._k=(1-e)/6}Fs.prototype={areaStart:gs,areaEnd:gs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const $s=function t(e){function r(t){return new Fs(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Es(t,e){this._context=t,this._k=(1-e)/6}Es.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ms(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Ns=function t(e){function r(t){return new Es(t,e)}return r.tension=function(e){return t(+e)},r}(0);function Ds(t,e,r){var n=t._x1,i=t._y1,a=t._x2,o=t._y2;if(t._l01_a>zo){var s=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,l=3*t._l01_a*(t._l01_a+t._l12_a);n=(n*s-t._x0*t._l12_2a+t._x2*t._l01_2a)/l,i=(i*s-t._y0*t._l12_2a+t._y2*t._l01_2a)/l}if(t._l23_a>zo){var c=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,h=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*c+t._x1*t._l23_2a-e*t._l12_2a)/h,o=(o*c+t._y1*t._l23_2a-r*t._l12_2a)/h}t._context.bezierCurveTo(n,i,a,o,t._x2,t._y2)}function js(t,e){this._context=t,this._alpha=e}js.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Is=function t(e){function r(t){return e?new js(t,e):new Bs(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Os(t,e){this._context=t,this._alpha=e}Os.prototype={areaStart:gs,areaEnd:gs,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const Rs=function t(e){function r(t){return e?new Os(t,e):new Fs(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Ps(t,e){this._context=t,this._alpha=e}Ps.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var r=this._x2-t,n=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(r*r+n*n,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Ds(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};const zs=function t(e){function r(t){return e?new Ps(t,e):new Es(t,0)}return r.alpha=function(e){return t(+e)},r}(.5);function Ks(t){this._context=t}function qs(t){return new Ks(t)}function Ws(t){return t<0?-1:1}function Hs(t,e,r){var n=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(n||i<0&&-0),o=(r-t._y1)/(i||n<0&&-0),s=(a*i+o*n)/(n+i);return(Ws(a)+Ws(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(s))||0}function Us(t,e){var r=t._x1-t._x0;return r?(3*(t._y1-t._y0)/r-e)/2:e}function Ys(t,e,r){var n=t._x0,i=t._y0,a=t._x1,o=t._y1,s=(a-n)/3;t._context.bezierCurveTo(n+s,i+s*e,a-s,o-s*r,a,o)}function Vs(t){this._context=t}function Gs(t){this._context=new Zs(t)}function Zs(t){this._context=t}function Xs(t){return new Vs(t)}function Qs(t){return new Gs(t)}function Js(t){this._context=t}function tl(t){var e,r,n=t.length-1,i=new Array(n),a=new Array(n),o=new Array(n);for(i[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e<n-1;++e)i[e]=1,a[e]=4,o[e]=4*t[e]+2*t[e+1];for(i[n-1]=2,a[n-1]=7,o[n-1]=8*t[n-1]+t[n],e=1;e<n;++e)r=i[e]/a[e-1],a[e]-=r,o[e]-=r*o[e-1];for(i[n-1]=o[n-1]/a[n-1],e=n-2;e>=0;--e)i[e]=(o[e]-i[e+1])/a[e];for(a[n-1]=(t[n]+i[n-1])/2,e=0;e<n-1;++e)a[e]=2*t[e+1]-i[e+1];return[i,a]}function el(t){return new Js(t)}function rl(t,e){this._context=t,this._t=e}function nl(t){return new rl(t,.5)}function il(t){return new rl(t,0)}function al(t){return new rl(t,1)}function ol(t,e,r){this.k=t,this.x=e,this.y=r}Ks.prototype={areaStart:gs,areaEnd:gs,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}},Vs.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=this._t0=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x1,this._y1);break;case 3:Ys(this,this._t0,Us(this,this._t0))}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){var r=NaN;if(e=+e,(t=+t)!==this._x1||e!==this._y1){switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,Ys(this,Us(this,r=Hs(this,t,e)),r);break;default:Ys(this,this._t0,r=Hs(this,t,e))}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e,this._t0=r}}},(Gs.prototype=Object.create(Vs.prototype)).point=function(t,e){Vs.prototype.point.call(this,e,t)},Zs.prototype={moveTo:function(t,e){this._context.moveTo(e,t)},closePath:function(){this._context.closePath()},lineTo:function(t,e){this._context.lineTo(e,t)},bezierCurveTo:function(t,e,r,n,i,a){this._context.bezierCurveTo(e,t,n,r,a,i)}},Js.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=[],this._y=[]},lineEnd:function(){var t=this._x,e=this._y,r=t.length;if(r)if(this._line?this._context.lineTo(t[0],e[0]):this._context.moveTo(t[0],e[0]),2===r)this._context.lineTo(t[1],e[1]);else for(var n=tl(t),i=tl(e),a=0,o=1;o<r;++a,++o)this._context.bezierCurveTo(n[0][a],i[0][a],n[1][a],i[1][a],t[o],e[o]);(this._line||0!==this._line&&1===r)&&this._context.closePath(),this._line=1-this._line,this._x=this._y=null},point:function(t,e){this._x.push(+t),this._y.push(+e)}},rl.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x=this._y=NaN,this._point=0},lineEnd:function(){0<this._t&&this._t<1&&2===this._point&&this._context.lineTo(this._x,this._y),(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line>=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var r=this._x*(1-this._t)+t*this._t;this._context.lineTo(r,this._y),this._context.lineTo(r,e)}}this._x=t,this._y=e}},ol.prototype={constructor:ol,scale:function(t){return 1===t?this:new ol(this.k*t,this.x,this.y)},translate:function(t,e){return 0===t&0===e?this:new ol(this.k,this.x+this.k*t,this.y+this.k*e)},apply:function(t){return[t[0]*this.k+this.x,t[1]*this.k+this.y]},applyX:function(t){return t*this.k+this.x},applyY:function(t){return t*this.k+this.y},invert:function(t){return[(t[0]-this.x)/this.k,(t[1]-this.y)/this.k]},invertX:function(t){return(t-this.x)/this.k},invertY:function(t){return(t-this.y)/this.k},rescaleX:function(t){return t.copy().domain(t.range().map(this.invertX,this).map(t.invert,t))},rescaleY:function(t){return t.copy().domain(t.range().map(this.invertY,this).map(t.invert,t))},toString:function(){return"translate("+this.x+","+this.y+") scale("+this.k+")"}};new ol(1,0,0);ol.prototype},93539:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var n=r(72453),i=r(63122);const a=class{constructor(){this.type=i.Z.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=i.Z.ALL}is(t){return this.type===t}};const o=new class{constructor(t,e){this.color=e,this.changed=!1,this.data=t,this.type=new a}set(t,e){return this.color=e,this.changed=!1,this.data=t,this.type.type=i.Z.ALL,this}_ensureHSL(){const t=this.data,{h:e,s:r,l:i}=t;void 0===e&&(t.h=n.A.channel.rgb2hsl(t,"h")),void 0===r&&(t.s=n.A.channel.rgb2hsl(t,"s")),void 0===i&&(t.l=n.A.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r:e,g:r,b:i}=t;void 0===e&&(t.r=n.A.channel.hsl2rgb(t,"r")),void 0===r&&(t.g=n.A.channel.hsl2rgb(t,"g")),void 0===i&&(t.b=n.A.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,e=t.r;return this.type.is(i.Z.HSL)||void 0===e?(this._ensureHSL(),n.A.channel.hsl2rgb(t,"r")):e}get g(){const t=this.data,e=t.g;return this.type.is(i.Z.HSL)||void 0===e?(this._ensureHSL(),n.A.channel.hsl2rgb(t,"g")):e}get b(){const t=this.data,e=t.b;return this.type.is(i.Z.HSL)||void 0===e?(this._ensureHSL(),n.A.channel.hsl2rgb(t,"b")):e}get h(){const t=this.data,e=t.h;return this.type.is(i.Z.RGB)||void 0===e?(this._ensureRGB(),n.A.channel.rgb2hsl(t,"h")):e}get s(){const t=this.data,e=t.s;return this.type.is(i.Z.RGB)||void 0===e?(this._ensureRGB(),n.A.channel.rgb2hsl(t,"s")):e}get l(){const t=this.data,e=t.l;return this.type.is(i.Z.RGB)||void 0===e?(this._ensureRGB(),n.A.channel.rgb2hsl(t,"l")):e}get a(){return this.data.a}set r(t){this.type.set(i.Z.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(i.Z.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(i.Z.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(i.Z.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(i.Z.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(i.Z.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}({r:0,g:0,b:0,a:0},"transparent")},74886:(t,e,r)=>{"use strict";r.d(e,{A:()=>g});var n=r(93539),i=r(63122);const a={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:t=>{if(35!==t.charCodeAt(0))return;const e=t.match(a.re);if(!e)return;const r=e[1],i=parseInt(r,16),o=r.length,s=o%4==0,l=o>4,c=l?1:17,h=l?8:4,u=s?0:-1,d=l?255:15;return n.A.set({r:(i>>h*(u+3)&d)*c,g:(i>>h*(u+2)&d)*c,b:(i>>h*(u+1)&d)*c,a:s?(i&d)*c/255:1},t)},stringify:t=>{const{r:e,g:r,b:n,a:a}=t;return a<1?`#${i.Y[Math.round(e)]}${i.Y[Math.round(r)]}${i.Y[Math.round(n)]}${i.Y[Math.round(255*a)]}`:`#${i.Y[Math.round(e)]}${i.Y[Math.round(r)]}${i.Y[Math.round(n)]}`}},o=a;var s=r(72453);const l={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:t=>{const e=t.match(l.hueRe);if(e){const[,t,r]=e;switch(r){case"grad":return s.A.channel.clamp.h(.9*parseFloat(t));case"rad":return s.A.channel.clamp.h(180*parseFloat(t)/Math.PI);case"turn":return s.A.channel.clamp.h(360*parseFloat(t))}}return s.A.channel.clamp.h(parseFloat(t))},parse:t=>{const e=t.charCodeAt(0);if(104!==e&&72!==e)return;const r=t.match(l.re);if(!r)return;const[,i,a,o,c,h]=r;return n.A.set({h:l._hue2deg(i),s:s.A.channel.clamp.s(parseFloat(a)),l:s.A.channel.clamp.l(parseFloat(o)),a:c?s.A.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},t)},stringify:t=>{const{h:e,s:r,l:n,a:i}=t;return i<1?`hsla(${s.A.lang.round(e)}, ${s.A.lang.round(r)}%, ${s.A.lang.round(n)}%, ${i})`:`hsl(${s.A.lang.round(e)}, ${s.A.lang.round(r)}%, ${s.A.lang.round(n)}%)`}},c=l,h={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:t=>{t=t.toLowerCase();const e=h.colors[t];if(e)return o.parse(e)},stringify:t=>{const e=o.stringify(t);for(const r in h.colors)if(h.colors[r]===e)return r}},u=h,d={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:t=>{const e=t.charCodeAt(0);if(114!==e&&82!==e)return;const r=t.match(d.re);if(!r)return;const[,i,a,o,l,c,h,u,p]=r;return n.A.set({r:s.A.channel.clamp.r(a?2.55*parseFloat(i):parseFloat(i)),g:s.A.channel.clamp.g(l?2.55*parseFloat(o):parseFloat(o)),b:s.A.channel.clamp.b(h?2.55*parseFloat(c):parseFloat(c)),a:u?s.A.channel.clamp.a(p?parseFloat(u)/100:parseFloat(u)):1},t)},stringify:t=>{const{r:e,g:r,b:n,a:i}=t;return i<1?`rgba(${s.A.lang.round(e)}, ${s.A.lang.round(r)}, ${s.A.lang.round(n)}, ${s.A.lang.round(i)})`:`rgb(${s.A.lang.round(e)}, ${s.A.lang.round(r)}, ${s.A.lang.round(n)})`}},p=d,f={format:{keyword:h,hex:o,rgb:d,rgba:d,hsl:l,hsla:l},parse:t=>{if("string"!=typeof t)return t;const e=o.parse(t)||p.parse(t)||c.parse(t)||u.parse(t);if(e)return e;throw new Error(`Unsupported color format: "${t}"`)},stringify:t=>!t.changed&&t.color?t.color:t.type.is(i.Z.HSL)||void 0===t.data.r?c.stringify(t):t.a<1||!Number.isInteger(t.r)||!Number.isInteger(t.g)||!Number.isInteger(t.b)?p.stringify(t):o.stringify(t)},g=f},63122:(t,e,r)=>{"use strict";r.d(e,{Y:()=>i,Z:()=>a});var n=r(72453);const i={};for(let o=0;o<=255;o++)i[o]=n.A.unit.dec2hex(o);const a={ALL:0,RGB:1,HSL:2}},95635:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(72453),i=r(74886);const a=(t,e,r)=>{const a=i.A.parse(t),o=a[e],s=n.A.channel.clamp[e](o+r);return o!==s&&(a[e]=s),i.A.stringify(a)}},8232:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(72453),i=r(74886);const a=(t,e)=>{const r=i.A.parse(t);for(const i in e)r[i]=n.A.channel.clamp[i](e[i]);return i.A.stringify(r)}},75263:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(95635);const i=(t,e)=>(0,n.A)(t,"l",-e)},3219:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var n=r(72453),i=r(74886);const a=t=>{const{r:e,g:r,b:a}=i.A.parse(t),o=.2126*n.A.channel.toLinear(e)+.7152*n.A.channel.toLinear(r)+.0722*n.A.channel.toLinear(a);return n.A.lang.round(o)},o=t=>a(t)>=.5,s=t=>!o(t)},78041:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(95635);const i=(t,e)=>(0,n.A)(t,"l",e)},25582:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var n=r(72453),i=r(93539),a=r(74886),o=r(8232);const s=(t,e,r=0,s=1)=>{if("number"!=typeof t)return(0,o.A)(t,{a:e});const l=i.A.set({r:n.A.channel.clamp.r(t),g:n.A.channel.clamp.g(e),b:n.A.channel.clamp.b(r),a:n.A.channel.clamp.a(s)});return a.A.stringify(l)}},72453:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});const n={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:t=>t>=255?255:t<0?0:t,g:t=>t>=255?255:t<0?0:t,b:t=>t>=255?255:t<0?0:t,h:t=>t%360,s:t=>t>=100?100:t<0?0:t,l:t=>t>=100?100:t<0?0:t,a:t=>t>=1?1:t<0?0:t},toLinear:t=>{const e=t/255;return t>.03928?Math.pow((e+.055)/1.055,2.4):e/12.92},hue2rgb:(t,e,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t),hsl2rgb:({h:t,s:e,l:r},i)=>{if(!e)return 2.55*r;t/=360,e/=100;const a=(r/=100)<.5?r*(1+e):r+e-r*e,o=2*r-a;switch(i){case"r":return 255*n.hue2rgb(o,a,t+1/3);case"g":return 255*n.hue2rgb(o,a,t);case"b":return 255*n.hue2rgb(o,a,t-1/3)}},rgb2hsl:({r:t,g:e,b:r},n)=>{t/=255,e/=255,r/=255;const i=Math.max(t,e,r),a=Math.min(t,e,r),o=(i+a)/2;if("l"===n)return 100*o;if(i===a)return 0;const s=i-a;if("s"===n)return 100*(o>.5?s/(2-i-a):s/(i+a));switch(i){case t:return 60*((e-r)/s+(e<r?6:0));case e:return 60*((r-t)/s+2);case r:return 60*((t-e)/s+4);default:return-1}}},i={channel:n,lang:{clamp:(t,e,r)=>e>r?Math.min(e,Math.max(r,t)):Math.min(r,Math.max(e,t)),round:t=>Math.round(1e10*t)/1e10},unit:{dec2hex:t=>{const e=Math.round(t).toString(16);return e.length>1?e:`0${e}`}}}},80127:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});const n=function(){this.__data__=[],this.size=0};var i=r(66984);const a=function(t,e){for(var r=t.length;r--;)if((0,i.A)(t[r][0],e))return r;return-1};var o=Array.prototype.splice;const s=function(t){var e=this.__data__,r=a(e,t);return!(r<0)&&(r==e.length-1?e.pop():o.call(e,r,1),--this.size,!0)};const l=function(t){var e=this.__data__,r=a(e,t);return r<0?void 0:e[r][1]};const c=function(t){return a(this.__data__,t)>-1};const h=function(t,e){var r=this.__data__,n=a(r,t);return n<0?(++this.size,r.push([t,e])):r[n][1]=e,this};function u(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}u.prototype.clear=n,u.prototype.delete=s,u.prototype.get=l,u.prototype.has=c,u.prototype.set=h;const d=u},68335:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(18744),i=r(41917);const a=(0,n.A)(i.A,"Map")},29471:(t,e,r)=>{"use strict";r.d(e,{A:()=>_});const n=(0,r(18744).A)(Object,"create");const i=function(){this.__data__=n?n(null):{},this.size=0};const a=function(t){var e=this.has(t)&&delete this.__data__[t];return this.size-=e?1:0,e};var o=Object.prototype.hasOwnProperty;const s=function(t){var e=this.__data__;if(n){var r=e[t];return"__lodash_hash_undefined__"===r?void 0:r}return o.call(e,t)?e[t]:void 0};var l=Object.prototype.hasOwnProperty;const c=function(t){var e=this.__data__;return n?void 0!==e[t]:l.call(e,t)};const h=function(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=n&&void 0===e?"__lodash_hash_undefined__":e,this};function u(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}u.prototype.clear=i,u.prototype.delete=a,u.prototype.get=s,u.prototype.has=c,u.prototype.set=h;const d=u;var p=r(80127),f=r(68335);const g=function(){this.size=0,this.__data__={hash:new d,map:new(f.A||p.A),string:new d}};const m=function(t){var e=typeof t;return"string"==e||"number"==e||"symbol"==e||"boolean"==e?"__proto__"!==t:null===t};const y=function(t,e){var r=t.__data__;return m(e)?r["string"==typeof e?"string":"hash"]:r.map};const x=function(t){var e=y(this,t).delete(t);return this.size-=e?1:0,e};const b=function(t){return y(this,t).get(t)};const k=function(t){return y(this,t).has(t)};const C=function(t,e){var r=y(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this};function w(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}w.prototype.clear=g,w.prototype.delete=x,w.prototype.get=b,w.prototype.has=k,w.prototype.set=C;const _=w},39857:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(18744),i=r(41917);const a=(0,n.A)(i.A,"Set")},11754:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var n=r(80127);const i=function(){this.__data__=new n.A,this.size=0};const a=function(t){var e=this.__data__,r=e.delete(t);return this.size=e.size,r};const o=function(t){return this.__data__.get(t)};const s=function(t){return this.__data__.has(t)};var l=r(68335),c=r(29471);const h=function(t,e){var r=this.__data__;if(r instanceof n.A){var i=r.__data__;if(!l.A||i.length<199)return i.push([t,e]),this.size=++r.size,this;r=this.__data__=new c.A(i)}return r.set(t,e),this.size=r.size,this};function u(t){var e=this.__data__=new n.A(t);this.size=e.size}u.prototype.clear=i,u.prototype.delete=a,u.prototype.get=o,u.prototype.has=s,u.prototype.set=h;const d=u},241:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=r(41917).A.Symbol},43988:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=r(41917).A.Uint8Array},83607:(t,e,r)=>{"use strict";r.d(e,{A:()=>h});const n=function(t,e){for(var r=-1,n=Array(t);++r<t;)n[r]=e(r);return n};var i=r(52274),a=r(92049),o=r(99912),s=r(25353),l=r(33858),c=Object.prototype.hasOwnProperty;const h=function(t,e){var r=(0,a.A)(t),h=!r&&(0,i.A)(t),u=!r&&!h&&(0,o.A)(t),d=!r&&!h&&!u&&(0,l.A)(t),p=r||h||u||d,f=p?n(t.length,String):[],g=f.length;for(var m in t)!e&&!c.call(t,m)||p&&("length"==m||u&&("offset"==m||"parent"==m)||d&&("buffer"==m||"byteLength"==m||"byteOffset"==m)||(0,s.A)(m,g))||f.push(m);return f}},52851:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var n=r(52528),i=r(66984),a=Object.prototype.hasOwnProperty;const o=function(t,e,r){var o=t[e];a.call(t,e)&&(0,i.A)(o,r)&&(void 0!==r||e in t)||(0,n.A)(t,e,r)}},52528:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(84171);const i=function(t,e,r){"__proto__"==e&&n.A?(0,n.A)(t,e,{configurable:!0,enumerable:!0,value:r,writable:!0}):t[e]=r}},4574:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return function(e,r,n){for(var i=-1,a=Object(e),o=n(e),s=o.length;s--;){var l=o[t?s:++i];if(!1===r(a[l],l,a))break}return e}}()},88496:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var n=r(241),i=Object.prototype,a=i.hasOwnProperty,o=i.toString,s=n.A?n.A.toStringTag:void 0;const l=function(t){var e=a.call(t,s),r=t[s];try{t[s]=void 0;var n=!0}catch(l){}var i=o.call(t);return n&&(e?t[s]=r:delete t[s]),i};var c=Object.prototype.toString;const h=function(t){return c.call(t)};var u=n.A?n.A.toStringTag:void 0;const d=function(t){return null==t?void 0===t?"[object Undefined]":"[object Null]":u&&u in Object(t)?l(t):h(t)}},69471:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var n=r(97271);const i=(0,r(40367).A)(Object.keys,Object);var a=Object.prototype.hasOwnProperty;const o=function(t){if(!(0,n.A)(t))return i(t);var e=[];for(var r in Object(t))a.call(t,r)&&"constructor"!=r&&e.push(r);return e}},24326:(t,e,r)=>{"use strict";r.d(e,{A:()=>o});var n=r(29008),i=r(76875),a=r(67525);const o=function(t,e){return(0,a.A)((0,i.A)(t,e,n.A),t+"")}},52789:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return function(e){return t(e)}}},90565:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(43988);const i=function(t){var e=new t.constructor(t.byteLength);return new n.A(e).set(new n.A(t)),e}},80154:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var n=r(41917),i="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=i&&"object"==typeof module&&module&&!module.nodeType&&module,o=a&&a.exports===i?n.A.Buffer:void 0,s=o?o.allocUnsafe:void 0;const l=function(t,e){if(e)return t.slice();var r=t.length,n=s?s(r):new t.constructor(r);return t.copy(n),n}},1801:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(90565);const i=function(t,e){var r=e?(0,n.A)(t.buffer):t.buffer;return new t.constructor(r,t.byteOffset,t.length)}},39759:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r<n;)e[r]=t[r];return e}},22031:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(52851),i=r(52528);const a=function(t,e,r,a){var o=!r;r||(r={});for(var s=-1,l=e.length;++s<l;){var c=e[s],h=a?a(r[c],t[c],c,r,t):void 0;void 0===h&&(h=t[c]),o?(0,i.A)(r,c,h):(0,n.A)(r,c,h)}return r}},3767:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(24326),i=r(6832);const a=function(t){return(0,n.A)((function(e,r){var n=-1,a=r.length,o=a>1?r[a-1]:void 0,s=a>2?r[2]:void 0;for(o=t.length>3&&"function"==typeof o?(a--,o):void 0,s&&(0,i.A)(r[0],r[1],s)&&(o=a<3?void 0:o,a=1),e=Object(e);++n<a;){var l=r[n];l&&t(e,l,n,o)}return e}))}},84171:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=r(18744);const i=function(){try{var t=(0,n.A)(Object,"defineProperty");return t({},"",{}),t}catch(e){}}()},72136:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n="object"==typeof global&&global&&global.Object===Object&&global},18744:(t,e,r)=>{"use strict";r.d(e,{A:()=>x});var n=r(89610);const i=r(41917).A["__core-js_shared__"];var a,o=(a=/[^.]+$/.exec(i&&i.keys&&i.keys.IE_PROTO||""))?"Symbol(src)_1."+a:"";const s=function(t){return!!o&&o in t};var l=r(23149),c=r(81121),h=/^\[object .+?Constructor\]$/,u=Function.prototype,d=Object.prototype,p=u.toString,f=d.hasOwnProperty,g=RegExp("^"+p.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");const m=function(t){return!(!(0,l.A)(t)||s(t))&&((0,n.A)(t)?g:h).test((0,c.A)(t))};const y=function(t,e){return null==t?void 0:t[e]};const x=function(t,e){var r=y(t,e);return m(r)?r:void 0}},15647:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=(0,r(40367).A)(Object.getPrototypeOf,Object)},9779:(t,e,r)=>{"use strict";r.d(e,{A:()=>_});var n=r(18744),i=r(41917);const a=(0,n.A)(i.A,"DataView");var o=r(68335);const s=(0,n.A)(i.A,"Promise");var l=r(39857);const c=(0,n.A)(i.A,"WeakMap");var h=r(88496),u=r(81121),d="[object Map]",p="[object Promise]",f="[object Set]",g="[object WeakMap]",m="[object DataView]",y=(0,u.A)(a),x=(0,u.A)(o.A),b=(0,u.A)(s),k=(0,u.A)(l.A),C=(0,u.A)(c),w=h.A;(a&&w(new a(new ArrayBuffer(1)))!=m||o.A&&w(new o.A)!=d||s&&w(s.resolve())!=p||l.A&&w(new l.A)!=f||c&&w(new c)!=g)&&(w=function(t){var e=(0,h.A)(t),r="[object Object]"==e?t.constructor:void 0,n=r?(0,u.A)(r):"";if(n)switch(n){case y:return m;case x:return d;case b:return p;case k:return f;case C:return g}return e});const _=w},18598:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var n=r(23149),i=Object.create;const a=function(){function t(){}return function(e){if(!(0,n.A)(e))return{};if(i)return i(e);t.prototype=e;var r=new t;return t.prototype=void 0,r}}();var o=r(15647),s=r(97271);const l=function(t){return"function"!=typeof t.constructor||(0,s.A)(t)?{}:a((0,o.A)(t))}},25353:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=/^(?:0|[1-9]\d*)$/;const i=function(t,e){var r=typeof t;return!!(e=null==e?9007199254740991:e)&&("number"==r||"symbol"!=r&&n.test(t))&&t>-1&&t%1==0&&t<e}},6832:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var n=r(66984),i=r(38446),a=r(25353),o=r(23149);const s=function(t,e,r){if(!(0,o.A)(r))return!1;var s=typeof e;return!!("number"==s?(0,i.A)(r)&&(0,a.A)(e,r.length):"string"==s&&e in r)&&(0,n.A)(r[e],t)}},97271:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=Object.prototype;const i=function(t){var e=t&&t.constructor;return t===("function"==typeof e&&e.prototype||n)}},64841:(t,e,r)=>{"use strict";r.d(e,{A:()=>s});var n=r(72136),i="object"==typeof exports&&exports&&!exports.nodeType&&exports,a=i&&"object"==typeof module&&module&&!module.nodeType&&module,o=a&&a.exports===i&&n.A.process;const s=function(){try{var t=a&&a.require&&a.require("util").types;return t||o&&o.binding&&o.binding("util")}catch(e){}}()},40367:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t,e){return function(r){return t(e(r))}}},76875:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});const n=function(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)};var i=Math.max;const a=function(t,e,r){return e=i(void 0===e?t.length-1:e,0),function(){for(var a=arguments,o=-1,s=i(a.length-e,0),l=Array(s);++o<s;)l[o]=a[e+o];o=-1;for(var c=Array(e+1);++o<e;)c[o]=a[o];return c[e]=r(l),n(t,this,c)}}},41917:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(72136),i="object"==typeof self&&self&&self.Object===Object&&self;const a=n.A||i||Function("return this")()},67525:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var n=r(39142),i=r(84171),a=r(29008);const o=i.A?function(t,e){return(0,i.A)(t,"toString",{configurable:!0,enumerable:!1,value:(0,n.A)(e),writable:!0})}:a.A;var s=Date.now;const l=function(t){var e=0,r=0;return function(){var n=s(),i=16-(n-r);if(r=n,i>0){if(++e>=800)return arguments[0]}else e=0;return t.apply(void 0,arguments)}}(o)},81121:(t,e,r)=>{"use strict";r.d(e,{A:()=>i});var n=Function.prototype.toString;const i=function(t){if(null!=t){try{return n.call(t)}catch(e){}try{return t+""}catch(e){}}return""}},39142:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return function(){return t}}},66984:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t,e){return t===e||t!=t&&e!=e}},29008:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return t}},52274:(t,e,r)=>{"use strict";r.d(e,{A:()=>c});var n=r(88496),i=r(53098);const a=function(t){return(0,i.A)(t)&&"[object Arguments]"==(0,n.A)(t)};var o=Object.prototype,s=o.hasOwnProperty,l=o.propertyIsEnumerable;const c=a(function(){return arguments}())?a:function(t){return(0,i.A)(t)&&s.call(t,"callee")&&!l.call(t,"callee")}},92049:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=Array.isArray},38446:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(89610),i=r(5254);const a=function(t){return null!=t&&(0,i.A)(t.length)&&!(0,n.A)(t)}},53533:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(38446),i=r(53098);const a=function(t){return(0,i.A)(t)&&(0,n.A)(t)}},99912:(t,e,r)=>{"use strict";r.d(e,{A:()=>l});var n=r(41917);const i=function(){return!1};var a="object"==typeof exports&&exports&&!exports.nodeType&&exports,o=a&&"object"==typeof module&&module&&!module.nodeType&&module,s=o&&o.exports===a?n.A.Buffer:void 0;const l=(s?s.isBuffer:void 0)||i},66401:(t,e,r)=>{"use strict";r.d(e,{A:()=>d});var n=r(69471),i=r(9779),a=r(52274),o=r(92049),s=r(38446),l=r(99912),c=r(97271),h=r(33858),u=Object.prototype.hasOwnProperty;const d=function(t){if(null==t)return!0;if((0,s.A)(t)&&((0,o.A)(t)||"string"==typeof t||"function"==typeof t.splice||(0,l.A)(t)||(0,h.A)(t)||(0,a.A)(t)))return!t.length;var e=(0,i.A)(t);if("[object Map]"==e||"[object Set]"==e)return!t.size;if((0,c.A)(t))return!(0,n.A)(t).length;for(var r in t)if(u.call(t,r))return!1;return!0}},89610:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(88496),i=r(23149);const a=function(t){if(!(0,i.A)(t))return!1;var e=(0,n.A)(t);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},5254:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return"number"==typeof t&&t>-1&&t%1==0&&t<=9007199254740991}},23149:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}},53098:(t,e,r)=>{"use strict";r.d(e,{A:()=>n});const n=function(t){return null!=t&&"object"==typeof t}},33858:(t,e,r)=>{"use strict";r.d(e,{A:()=>u});var n=r(88496),i=r(5254),a=r(53098),o={};o["[object Float32Array]"]=o["[object Float64Array]"]=o["[object Int8Array]"]=o["[object Int16Array]"]=o["[object Int32Array]"]=o["[object Uint8Array]"]=o["[object Uint8ClampedArray]"]=o["[object Uint16Array]"]=o["[object Uint32Array]"]=!0,o["[object Arguments]"]=o["[object Array]"]=o["[object ArrayBuffer]"]=o["[object Boolean]"]=o["[object DataView]"]=o["[object Date]"]=o["[object Error]"]=o["[object Function]"]=o["[object Map]"]=o["[object Number]"]=o["[object Object]"]=o["[object RegExp]"]=o["[object Set]"]=o["[object String]"]=o["[object WeakMap]"]=!1;const s=function(t){return(0,a.A)(t)&&(0,i.A)(t.length)&&!!o[(0,n.A)(t)]};var l=r(52789),c=r(64841),h=c.A&&c.A.isTypedArray;const u=h?(0,l.A)(h):s},55615:(t,e,r)=>{"use strict";r.d(e,{A:()=>h});var n=r(83607),i=r(23149),a=r(97271);const o=function(t){var e=[];if(null!=t)for(var r in Object(t))e.push(r);return e};var s=Object.prototype.hasOwnProperty;const l=function(t){if(!(0,i.A)(t))return o(t);var e=(0,a.A)(t),r=[];for(var n in t)("constructor"!=n||!e&&s.call(t,n))&&r.push(n);return r};var c=r(38446);const h=function(t){return(0,c.A)(t)?(0,n.A)(t,!0):l(t)}},46632:(t,e,r)=>{"use strict";r.d(e,{A:()=>a});var n=r(29471);function i(t,e){if("function"!=typeof t||null!=e&&"function"!=typeof e)throw new TypeError("Expected a function");var r=function(){var n=arguments,i=e?e.apply(this,n):n[0],a=r.cache;if(a.has(i))return a.get(i);var o=t.apply(this,n);return r.cache=a.set(i,o)||a,o};return r.cache=new(i.Cache||n.A),r}i.Cache=n.A;const a=i},42837:(t,e,r)=>{"use strict";r.d(e,{A:()=>N});var n=r(11754),i=r(52528),a=r(66984);const o=function(t,e,r){(void 0!==r&&!(0,a.A)(t[e],r)||void 0===r&&!(e in t))&&(0,i.A)(t,e,r)};var s=r(4574),l=r(80154),c=r(1801),h=r(39759),u=r(18598),d=r(52274),p=r(92049),f=r(53533),g=r(99912),m=r(89610),y=r(23149),x=r(88496),b=r(15647),k=r(53098),C=Function.prototype,w=Object.prototype,_=C.toString,v=w.hasOwnProperty,S=_.call(Object);const A=function(t){if(!(0,k.A)(t)||"[object Object]"!=(0,x.A)(t))return!1;var e=(0,b.A)(t);if(null===e)return!0;var r=v.call(e,"constructor")&&e.constructor;return"function"==typeof r&&r instanceof r&&_.call(r)==S};var T=r(33858);const M=function(t,e){if(("constructor"!==e||"function"!=typeof t[e])&&"__proto__"!=e)return t[e]};var B=r(22031),L=r(55615);const F=function(t){return(0,B.A)(t,(0,L.A)(t))};const $=function(t,e,r,n,i,a,s){var x=M(t,r),b=M(e,r),k=s.get(b);if(k)o(t,r,k);else{var C=a?a(x,b,r+"",t,e,s):void 0,w=void 0===C;if(w){var _=(0,p.A)(b),v=!_&&(0,g.A)(b),S=!_&&!v&&(0,T.A)(b);C=b,_||v||S?(0,p.A)(x)?C=x:(0,f.A)(x)?C=(0,h.A)(x):v?(w=!1,C=(0,l.A)(b,!0)):S?(w=!1,C=(0,c.A)(b,!0)):C=[]:A(b)||(0,d.A)(b)?(C=x,(0,d.A)(x)?C=F(x):(0,y.A)(x)&&!(0,m.A)(x)||(C=(0,u.A)(b))):w=!1}w&&(s.set(b,C),i(C,b,n,a,s),s.delete(b)),o(t,r,C)}};const E=function t(e,r,i,a,l){e!==r&&(0,s.A)(r,(function(s,c){if(l||(l=new n.A),(0,y.A)(s))$(e,r,c,i,t,a,l);else{var h=a?a(M(e,c),s,c+"",e,r,l):void 0;void 0===h&&(h=s),o(e,c,h)}}),L.A)};const N=(0,r(3767).A)((function(t,e,r){E(t,e,r)}))},34483:(t,e,r)=>{"use strict";r.d(e,{WY:()=>A,pC:()=>v,Gc:()=>C});var n=r(45567);const i=/^[a-z0-9]+(-[a-z0-9]+)*$/,a=(t,e)=>!!t&&!(""!==t.provider&&!t.provider.match(i)||!(e&&""===t.prefix||t.prefix.match(i))||!t.name.match(i)),o=Object.freeze({left:0,top:0,width:16,height:16}),s=Object.freeze({rotate:0,vFlip:!1,hFlip:!1}),l=Object.freeze({...o,...s}),c=Object.freeze({...l,body:"",hidden:!1});function h(t,e){const r=function(t,e){const r={};!t.hFlip!=!e.hFlip&&(r.hFlip=!0),!t.vFlip!=!e.vFlip&&(r.vFlip=!0);const n=((t.rotate||0)+(e.rotate||0))%4;return n&&(r.rotate=n),r}(t,e);for(const n in c)n in s?n in t&&!(n in r)&&(r[n]=s[n]):n in e?r[n]=e[n]:n in t&&(r[n]=t[n]);return r}function u(t,e,r){const n=t.icons,i=t.aliases||Object.create(null);let a={};function o(t){a=h(n[t]||i[t],a)}return o(e),r.forEach(o),h(t,a)}function d(t,e){if(t.icons[e])return u(t,e,[]);const r=function(t,e){const r=t.icons,n=t.aliases||Object.create(null),i=Object.create(null);return(e||Object.keys(r).concat(Object.keys(n))).forEach((function t(e){if(r[e])return i[e]=[];if(!(e in i)){i[e]=null;const r=n[e]&&n[e].parent,a=r&&t(r);a&&(i[e]=[r].concat(a))}return i[e]})),i}(t,[e])[e];return r?u(t,e,r):null}const p=Object.freeze({width:null,height:null}),f=Object.freeze({...p,...s}),g=/(-?[0-9.]*[0-9]+[0-9.]*)/g,m=/^-?[0-9.]*[0-9]+[0-9.]*$/g;function y(t,e,r){if(1===e)return t;if(r=r||100,"number"==typeof t)return Math.ceil(t*e*r)/r;if("string"!=typeof t)return t;const n=t.split(g);if(null===n||!n.length)return t;const i=[];let a=n.shift(),o=m.test(a);for(;;){if(o){const t=parseFloat(a);isNaN(t)?i.push(a):i.push(Math.ceil(t*e*r)/r)}else i.push(a);if(a=n.shift(),void 0===a)return i.join("");o=!o}}const x=/\sid="(\S+)"/g,b="IconifyId"+Date.now().toString(16)+(16777216*Math.random()|0).toString(16);let k=0;var C={body:'<g><rect width="80" height="80" style="fill: #087ebf; stroke-width: 0px;"/><text transform="translate(21.16 64.67)" style="fill: #fff; font-family: ArialMT, Arial; font-size: 67.75px;"><tspan x="0" y="0">?</tspan></text></g>',height:80,width:80},w=new Map,_=new Map,v=(0,n.K2)((t=>{for(const e of t){if(!e.name)throw new Error('Invalid icon loader. Must have a "name" property with non-empty string value.');if(n.Rm.debug("Registering icon pack:",e.name),"loader"in e)_.set(e.name,e.loader);else{if(!("icons"in e))throw n.Rm.error("Invalid icon loader:",e),new Error('Invalid icon loader. Must have either "icons" or "loader" property.');w.set(e.name,e.icons)}}}),"registerIconPacks"),S=(0,n.K2)((async(t,e)=>{const r=((t,e,r,n="")=>{const i=t.split(":");if("@"===t.slice(0,1)){if(i.length<2||i.length>3)return null;n=i.shift().slice(1)}if(i.length>3||!i.length)return null;if(i.length>1){const t=i.pop(),r=i.pop(),o={provider:i.length>0?i[0]:n,prefix:r,name:t};return e&&!a(o)?null:o}const o=i[0],s=o.split("-");if(s.length>1){const t={provider:n,prefix:s.shift(),name:s.join("-")};return e&&!a(t)?null:t}if(r&&""===n){const t={provider:n,prefix:"",name:o};return e&&!a(t,r)?null:t}return null})(t,!0,void 0!==e);if(!r)throw new Error(`Invalid icon name: ${t}`);const i=r.prefix||e;if(!i)throw new Error(`Icon name must contain a prefix: ${t}`);let o=w.get(i);if(!o){const t=_.get(i);if(!t)throw new Error(`Icon set not found: ${r.prefix}`);try{o={...await t(),prefix:i},w.set(i,o)}catch(l){throw n.Rm.error(l),new Error(`Failed to load icon set: ${r.prefix}`)}}const s=d(o,r.name);if(!s)throw new Error(`Icon not found: ${t}`);return s}),"getRegisteredIconData"),A=(0,n.K2)((async(t,e)=>{let r;try{r=await S(t,e?.fallbackPrefix)}catch(a){n.Rm.error(a),r=C}const i=function(t,e){const r={...l,...t},n={...f,...e},i={left:r.left,top:r.top,width:r.width,height:r.height};let a=r.body;[r,n].forEach((t=>{const e=[],r=t.hFlip,n=t.vFlip;let o,s=t.rotate;switch(r?n?s+=2:(e.push("translate("+(i.width+i.left).toString()+" "+(0-i.top).toString()+")"),e.push("scale(-1 1)"),i.top=i.left=0):n&&(e.push("translate("+(0-i.left).toString()+" "+(i.height+i.top).toString()+")"),e.push("scale(1 -1)"),i.top=i.left=0),s<0&&(s-=4*Math.floor(s/4)),s%=4,s){case 1:o=i.height/2+i.top,e.unshift("rotate(90 "+o.toString()+" "+o.toString()+")");break;case 2:e.unshift("rotate(180 "+(i.width/2+i.left).toString()+" "+(i.height/2+i.top).toString()+")");break;case 3:o=i.width/2+i.left,e.unshift("rotate(-90 "+o.toString()+" "+o.toString()+")")}s%2==1&&(i.left!==i.top&&(o=i.left,i.left=i.top,i.top=o),i.width!==i.height&&(o=i.width,i.width=i.height,i.height=o)),e.length&&(a=function(t,e,r){const n=function(t,e="defs"){let r="";const n=t.indexOf("<"+e);for(;n>=0;){const i=t.indexOf(">",n),a=t.indexOf("</"+e);if(-1===i||-1===a)break;const o=t.indexOf(">",a);if(-1===o)break;r+=t.slice(i+1,a).trim(),t=t.slice(0,n).trim()+t.slice(o+1)}return{defs:r,content:t}}(t);return i=n.defs,a=e+n.content+r,i?"<defs>"+i+"</defs>"+a:a;var i,a}(a,'<g transform="'+e.join(" ")+'">',"</g>"))}));const o=n.width,s=n.height,c=i.width,h=i.height;let u,d;null===o?(d=null===s?"1em":"auto"===s?h:s,u=y(d,c/h)):(u="auto"===o?c:o,d=null===s?y(u,h/c):"auto"===s?h:s);const p={},g=(t,e)=>{(t=>"unset"===t||"undefined"===t||"none"===t)(e)||(p[t]=e.toString())};g("width",u),g("height",d);const m=[i.left,i.top,c,h];return p.viewBox=m.join(" "),{attributes:p,viewBox:m,body:a}}(r,e);return function(t,e){let r=-1===t.indexOf("xlink:")?"":' xmlns:xlink="http://www.w3.org/1999/xlink"';for(const n in e)r+=" "+n+'="'+e[n]+'"';return'<svg xmlns="http://www.w3.org/2000/svg"'+r+">"+t+"</svg>"}(function(t,e=b){const r=[];let n;for(;n=x.exec(t);)r.push(n[1]);if(!r.length)return t;const i="suffix"+(16777216*Math.random()|Date.now()).toString(16);return r.forEach((r=>{const n="function"==typeof e?e(r):e+(k++).toString(),a=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");t=t.replace(new RegExp('([#;"])('+a+')([")]|\\.[a-z])',"g"),"$1"+n+i+"$3")})),t=t.replace(new RegExp(i,"g"),"")}(i.body),i.attributes)}),"getIconSVG")},61021:(t,e,r)=>{"use strict";r.d(e,{D:()=>a});var n=r(45567),i=r(20007),a=(0,n.K2)((t=>{const{securityLevel:e}=(0,n.D7)();let r=(0,i.Ltv)("body");if("sandbox"===e){const e=(0,i.Ltv)(`#i${t}`),n=e.node()?.contentDocument??document;r=(0,i.Ltv)(n.body)}return r.select(`#${t}`)}),"selectSvgElement")},5081:(t,e,r)=>{"use strict";r.d(e,{DA:()=>k,IU:()=>N,U:()=>E,U7:()=>we,U_:()=>ve,Zk:()=>h,aP:()=>be,gh:()=>_e,lC:()=>d,on:()=>Ce});var n=r(34483),i=r(62392),a=r(86825),o=r(85039),s=r(45567),l=r(20007),c=r(29893),h=(0,s.K2)((async(t,e,r)=>{let n;const i=e.useHtmlLabels||(0,s._3)((0,s.D7)()?.htmlLabels);n=r||"node default";const c=t.insert("g").attr("class",n).attr("id",e.domId||e.id),h=c.insert("g").attr("class","label").attr("style",(0,o.KL)(e.labelStyle));let u;u=void 0===e.label?"":"string"==typeof e.label?e.label:e.label[0];const d=await(0,a.GZ)(h,(0,s.jZ)((0,o.Sm)(u),(0,s.D7)()),{useHtmlLabels:i,width:e.width||(0,s.D7)().flowchart?.wrappingWidth,cssClasses:"markdown-node-label",style:e.labelStyle,addSvgBackground:!!e.icon||!!e.img});let p=d.getBBox();const f=(e?.padding??0)/2;if(i){const t=d.children[0],e=(0,l.Ltv)(d),r=t.getElementsByTagName("img");if(r){const t=""===u.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map((e=>new Promise((r=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=(0,s.D7)().fontSize?(0,s.D7)().fontSize:window.getComputedStyle(document.body).fontSize,r=5,[n=s.UI.fontSize]=(0,o.I5)(t),i=n*r+"px";e.style.minWidth=i,e.style.maxWidth=i}else e.style.width="100%";r(e)}(0,s.K2)(n,"setupImage"),setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}p=t.getBoundingClientRect(),e.attr("width",p.width),e.attr("height",p.height)}return i?h.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"):h.attr("transform","translate(0, "+-p.height/2+")"),e.centerLabel&&h.attr("transform","translate("+-p.width/2+", "+-p.height/2+")"),h.insert("rect",":first-child"),{shapeSvg:c,bbox:p,halfPadding:f,label:h}}),"labelHelper"),u=(0,s.K2)((async(t,e,r)=>{const n=r.useHtmlLabels||(0,s._3)((0,s.D7)()?.flowchart?.htmlLabels),i=t.insert("g").attr("class","label").attr("style",r.labelStyle||""),c=await(0,a.GZ)(i,(0,s.jZ)((0,o.Sm)(e),(0,s.D7)()),{useHtmlLabels:n,width:r.width||(0,s.D7)()?.flowchart?.wrappingWidth,style:r.labelStyle,addSvgBackground:!!r.icon||!!r.img});let h=c.getBBox();const u=r.padding/2;if((0,s._3)((0,s.D7)()?.flowchart?.htmlLabels)){const t=c.children[0],e=(0,l.Ltv)(c);h=t.getBoundingClientRect(),e.attr("width",h.width),e.attr("height",h.height)}return n?i.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"):i.attr("transform","translate(0, "+-h.height/2+")"),r.centerLabel&&i.attr("transform","translate("+-h.width/2+", "+-h.height/2+")"),i.insert("rect",":first-child"),{shapeSvg:t,bbox:h,halfPadding:u,label:i}}),"insertLabel"),d=(0,s.K2)(((t,e)=>{const r=e.node().getBBox();t.width=r.width,t.height=r.height}),"updateNodeBounds"),p=(0,s.K2)(((t,e)=>("handDrawn"===t.look?"rough-node":"node")+" "+t.cssClasses+" "+(e||"")),"getNodeClasses");function f(t){const e=t.map(((t,e)=>`${0===e?"M":"L"}${t.x},${t.y}`));return e.push("Z"),e.join(" ")}function g(t,e,r,n,i,a){const o=[],s=r-t,l=n-e,c=s/a,h=2*Math.PI/c,u=e+l/2;for(let d=0;d<=50;d++){const e=t+d/50*s,r=u+i*Math.sin(h*(e-t));o.push({x:e,y:r})}return o}function m(t,e,r,n,i,a){const o=[],s=i*Math.PI/180,l=(a*Math.PI/180-s)/(n-1);for(let c=0;c<n;c++){const n=s+c*l,i=t+r*Math.cos(n),a=e+r*Math.sin(n);o.push({x:-i,y:-a})}return o}(0,s.K2)(f,"createPathFromPoints"),(0,s.K2)(g,"generateFullSineWavePoints"),(0,s.K2)(m,"generateCirclePoints");var y=(0,s.K2)(((t,e)=>{var r,n,i=t.x,a=t.y,o=e.x-i,s=e.y-a,l=t.width/2,c=t.height/2;return Math.abs(s)*l>Math.abs(o)*c?(s<0&&(c=-c),r=0===s?0:c*o/s,n=c):(o<0&&(l=-l),r=l,n=0===o?0:l*s/o),{x:i+r,y:a+n}}),"intersectRect");function x(t,e){e&&t.attr("style",e)}async function b(t){const e=(0,l.Ltv)(document.createElementNS("http://www.w3.org/2000/svg","foreignObject")),r=e.append("xhtml:div");let n=t.label;t.label&&(0,s.Wi)(t.label)&&(n=await(0,s.VJ)(t.label.replace(s.Y2.lineBreakRegex,"\n"),(0,s.D7)()));const i=t.isNode?"nodeLabel":"edgeLabel";return r.html('<span class="'+i+'" '+(t.labelStyle?'style="'+t.labelStyle+'"':"")+">"+n+"</span>"),x(r,t.labelStyle),r.style("display","inline-block"),r.style("padding-right","1px"),r.style("white-space","nowrap"),r.attr("xmlns","http://www.w3.org/1999/xhtml"),e.node()}(0,s.K2)(x,"applyStyle"),(0,s.K2)(b,"addHtmlLabel");var k=(0,s.K2)((async(t,e,r,n)=>{let i=t||"";if("object"==typeof i&&(i=i[0]),(0,s._3)((0,s.D7)().flowchart.htmlLabels)){i=i.replace(/\\n|\n/g,"<br />"),s.Rm.info("vertexText"+i);const t={isNode:n,label:(0,o.Sm)(i).replace(/fa[blrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`)),labelStyle:e?e.replace("fill:","color:"):e};return await b(t)}{const t=document.createElementNS("http://www.w3.org/2000/svg","text");t.setAttribute("style",e.replace("color:","fill:"));let n=[];n="string"==typeof i?i.split(/\\n|\n|<br\s*\/?>/gi):Array.isArray(i)?i:[];for(const e of n){const n=document.createElementNS("http://www.w3.org/2000/svg","tspan");n.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),n.setAttribute("dy","1em"),n.setAttribute("x","0"),r?n.setAttribute("class","title-row"):n.setAttribute("class","row"),n.textContent=e.trim(),t.appendChild(n)}return t}}),"createLabel"),C=(0,s.K2)(((t,e,r,n,i)=>["M",t+i,e,"H",t+r-i,"A",i,i,0,0,1,t+r,e+i,"V",e+n-i,"A",i,i,0,0,1,t+r-i,e+n,"H",t+i,"A",i,i,0,0,1,t,e+n-i,"V",e+i,"A",i,i,0,0,1,t+i,e,"Z"].join(" ")),"createRoundedRectPathD"),w=(0,s.K2)((t=>{const{handDrawnSeed:e}=(0,s.D7)();return{fill:t,hachureAngle:120,hachureGap:4,fillWeight:2,roughness:.7,stroke:t,seed:e}}),"solidStateFill"),_=(0,s.K2)((t=>{const e=v([...t.cssCompiledStyles||[],...t.cssStyles||[]]);return{stylesMap:e,stylesArray:[...e]}}),"compileStyles"),v=(0,s.K2)((t=>{const e=new Map;return t.forEach((t=>{const[r,n]=t.split(":");e.set(r.trim(),n?.trim())})),e}),"styles2Map"),S=(0,s.K2)((t=>{const{stylesArray:e}=_(t),r=[],n=[],i=[],a=[];return e.forEach((t=>{const e=t[0];"color"===e||"font-size"===e||"font-family"===e||"font-weight"===e||"font-style"===e||"text-decoration"===e||"text-align"===e||"text-transform"===e||"line-height"===e||"letter-spacing"===e||"word-spacing"===e||"text-shadow"===e||"text-overflow"===e||"white-space"===e||"word-wrap"===e||"word-break"===e||"overflow-wrap"===e||"hyphens"===e?r.push(t.join(":")+" !important"):(n.push(t.join(":")+" !important"),e.includes("stroke")&&i.push(t.join(":")+" !important"),"fill"===e&&a.push(t.join(":")+" !important"))})),{labelStyles:r.join(";"),nodeStyles:n.join(";"),stylesArray:e,borderStyles:i,backgroundStyles:a}}),"styles2String"),A=(0,s.K2)(((t,e)=>{const{themeVariables:r,handDrawnSeed:n}=(0,s.D7)(),{nodeBorder:i,mainBkg:a}=r,{stylesMap:o}=_(t);return Object.assign({roughness:.7,fill:o.get("fill")||a,fillStyle:"hachure",fillWeight:4,hachureGap:5.2,stroke:o.get("stroke")||i,seed:n,strokeWidth:o.get("stroke-width")?.replace("px","")||1.3,fillLineDash:[0,0]},e)}),"userNodeOverrides"),T=(0,s.K2)((async(t,e)=>{s.Rm.info("Creating subgraph rect for ",e.id,e);const r=(0,s.D7)(),{themeVariables:n,handDrawnSeed:o}=r,{clusterBkg:h,clusterBorder:u}=n,{labelStyles:d,nodeStyles:p,borderStyles:f,backgroundStyles:g}=S(e),m=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),x=(0,s._3)(r.flowchart.htmlLabels),b=m.insert("g").attr("class","cluster-label "),k=await(0,a.GZ)(b,e.label,{style:e.labelStyle,useHtmlLabels:x,isNode:!0});let w=k.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=k.children[0],e=(0,l.Ltv)(k);w=t.getBoundingClientRect(),e.attr("width",w.width),e.attr("height",w.height)}const _=e.width<=w.width+e.padding?w.width+e.padding:e.width;e.width<=w.width+e.padding?e.diff=(_-e.width)/2-e.padding:e.diff=-e.padding;const v=e.height,T=e.x-_/2,M=e.y-v/2;let B;if(s.Rm.trace("Data ",e,JSON.stringify(e)),"handDrawn"===e.look){const t=c.A.svg(m),r=A(e,{roughness:.7,fill:h,stroke:u,fillWeight:3,seed:o}),n=t.path(C(T,M,_,v,0),r);B=m.insert((()=>(s.Rm.debug("Rough node insert CXC",n),n)),":first-child"),B.select("path:nth-child(2)").attr("style",f.join(";")),B.select("path").attr("style",g.join(";").replace("fill","stroke"))}else B=m.insert("rect",":first-child"),B.attr("style",p).attr("rx",e.rx).attr("ry",e.ry).attr("x",T).attr("y",M).attr("width",_).attr("height",v);const{subGraphTitleTopMargin:L}=(0,i.O)(r);if(b.attr("transform",`translate(${e.x-w.width/2}, ${e.y-e.height/2+L})`),d){const t=b.select("span");t&&t.attr("style",d)}const F=B.node().getBBox();return e.offsetX=0,e.width=F.width,e.height=F.height,e.offsetY=w.height-e.padding/2,e.intersect=function(t){return y(e,t)},{cluster:m,labelBBox:w}}),"rect"),M=(0,s.K2)(((t,e)=>{const r=t.insert("g").attr("class","note-cluster").attr("id",e.id),n=r.insert("rect",":first-child"),i=0*e.padding,a=i/2;n.attr("rx",e.rx).attr("ry",e.ry).attr("x",e.x-e.width/2-a).attr("y",e.y-e.height/2-a).attr("width",e.width+i).attr("height",e.height+i).attr("fill","none");const o=n.node().getBBox();return e.width=o.width,e.height=o.height,e.intersect=function(t){return y(e,t)},{cluster:r,labelBBox:{width:0,height:0}}}),"noteGroup"),B=(0,s.K2)((async(t,e)=>{const r=(0,s.D7)(),{themeVariables:n,handDrawnSeed:i}=r,{altBackground:a,compositeBackground:o,compositeTitleBackground:h,nodeBorder:u}=n,d=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-id",e.id).attr("data-look",e.look),p=d.insert("g",":first-child"),f=d.insert("g").attr("class","cluster-label");let g=d.append("rect");const m=f.node().appendChild(await k(e.label,e.labelStyle,void 0,!0));let x=m.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=m.children[0],e=(0,l.Ltv)(m);x=t.getBoundingClientRect(),e.attr("width",x.width),e.attr("height",x.height)}const b=0*e.padding,w=b/2,_=(e.width<=x.width+e.padding?x.width+e.padding:e.width)+b;e.width<=x.width+e.padding?e.diff=(_-e.width)/2-e.padding:e.diff=-e.padding;const v=e.height+b,S=e.height+b-x.height-6,A=e.x-_/2,T=e.y-v/2;e.width=_;const M=e.y-e.height/2-w+x.height+2;let B;if("handDrawn"===e.look){const t=e.cssClasses.includes("statediagram-cluster-alt"),r=c.A.svg(d),n=e.rx||e.ry?r.path(C(A,T,_,v,10),{roughness:.7,fill:h,fillStyle:"solid",stroke:u,seed:i}):r.rectangle(A,T,_,v,{seed:i});B=d.insert((()=>n),":first-child");const s=r.rectangle(A,M,_,S,{fill:t?a:o,fillStyle:t?"hachure":"solid",stroke:u,seed:i});B=d.insert((()=>n),":first-child"),g=d.insert((()=>s))}else{B=p.insert("rect",":first-child");const t="outer";B.attr("class",t).attr("x",A).attr("y",T).attr("width",_).attr("height",v).attr("data-look",e.look),g.attr("class","inner").attr("x",A).attr("y",M).attr("width",_).attr("height",S)}f.attr("transform",`translate(${e.x-x.width/2}, ${T+1-((0,s._3)(r.flowchart.htmlLabels)?0:3)})`);const L=B.node().getBBox();return e.height=L.height,e.offsetX=0,e.offsetY=x.height-e.padding/2,e.labelBBox=x,e.intersect=function(t){return y(e,t)},{cluster:d,labelBBox:x}}),"roundedWithTitle"),L=(0,s.K2)((async(t,e)=>{s.Rm.info("Creating subgraph rect for ",e.id,e);const r=(0,s.D7)(),{themeVariables:n,handDrawnSeed:o}=r,{clusterBkg:h,clusterBorder:u}=n,{labelStyles:d,nodeStyles:p,borderStyles:f,backgroundStyles:g}=S(e),m=t.insert("g").attr("class","cluster "+e.cssClasses).attr("id",e.id).attr("data-look",e.look),x=(0,s._3)(r.flowchart.htmlLabels),b=m.insert("g").attr("class","cluster-label "),k=await(0,a.GZ)(b,e.label,{style:e.labelStyle,useHtmlLabels:x,isNode:!0,width:e.width});let w=k.getBBox();if((0,s._3)(r.flowchart.htmlLabels)){const t=k.children[0],e=(0,l.Ltv)(k);w=t.getBoundingClientRect(),e.attr("width",w.width),e.attr("height",w.height)}const _=e.width<=w.width+e.padding?w.width+e.padding:e.width;e.width<=w.width+e.padding?e.diff=(_-e.width)/2-e.padding:e.diff=-e.padding;const v=e.height,T=e.x-_/2,M=e.y-v/2;let B;if(s.Rm.trace("Data ",e,JSON.stringify(e)),"handDrawn"===e.look){const t=c.A.svg(m),r=A(e,{roughness:.7,fill:h,stroke:u,fillWeight:4,seed:o}),n=t.path(C(T,M,_,v,e.rx),r);B=m.insert((()=>(s.Rm.debug("Rough node insert CXC",n),n)),":first-child"),B.select("path:nth-child(2)").attr("style",f.join(";")),B.select("path").attr("style",g.join(";").replace("fill","stroke"))}else B=m.insert("rect",":first-child"),B.attr("style",p).attr("rx",e.rx).attr("ry",e.ry).attr("x",T).attr("y",M).attr("width",_).attr("height",v);const{subGraphTitleTopMargin:L}=(0,i.O)(r);if(b.attr("transform",`translate(${e.x-w.width/2}, ${e.y-e.height/2+L})`),d){const t=b.select("span");t&&t.attr("style",d)}const F=B.node().getBBox();return e.offsetX=0,e.width=F.width,e.height=F.height,e.offsetY=w.height-e.padding/2,e.intersect=function(t){return y(e,t)},{cluster:m,labelBBox:w}}),"kanbanSection"),F={rect:T,squareRect:T,roundedWithTitle:B,noteGroup:M,divider:(0,s.K2)(((t,e)=>{const r=(0,s.D7)(),{themeVariables:n,handDrawnSeed:i}=r,{nodeBorder:a}=n,o=t.insert("g").attr("class",e.cssClasses).attr("id",e.id).attr("data-look",e.look),l=o.insert("g",":first-child"),h=0*e.padding,u=e.width+h;e.diff=-e.padding;const d=e.height+h,p=e.x-u/2,f=e.y-d/2;let g;if(e.width=u,"handDrawn"===e.look){const t=c.A.svg(o).rectangle(p,f,u,d,{fill:"lightgrey",roughness:.5,strokeLineDash:[5],stroke:a,seed:i});g=o.insert((()=>t),":first-child")}else{g=l.insert("rect",":first-child");const t="divider";g.attr("class",t).attr("x",p).attr("y",f).attr("width",u).attr("height",d).attr("data-look",e.look)}const m=g.node().getBBox();return e.height=m.height,e.offsetX=0,e.offsetY=0,e.intersect=function(t){return y(e,t)},{cluster:o,labelBBox:{}}}),"divider"),kanbanSection:L},$=new Map,E=(0,s.K2)((async(t,e)=>{const r=e.shape||"rect",n=await F[r](t,e);return $.set(e.id,n),n}),"insertCluster"),N=(0,s.K2)((()=>{$=new Map}),"clear");function D(t,e){return t.intersect(e)}(0,s.K2)(D,"intersectNode");var j=D;function I(t,e,r,n){var i=t.x,a=t.y,o=i-n.x,s=a-n.y,l=Math.sqrt(e*e*s*s+r*r*o*o),c=Math.abs(e*r*o/l);n.x<i&&(c=-c);var h=Math.abs(e*r*s/l);return n.y<a&&(h=-h),{x:i+c,y:a+h}}(0,s.K2)(I,"intersectEllipse");var O=I;function R(t,e,r){return O(t,e,e,r)}(0,s.K2)(R,"intersectCircle");var P=R;function z(t,e,r,n){var i,a,o,s,l,c,h,u,d,p,f,g,m;if(i=e.y-t.y,o=t.x-e.x,l=e.x*t.y-t.x*e.y,d=i*r.x+o*r.y+l,p=i*n.x+o*n.y+l,!(0!==d&&0!==p&&K(d,p)||(a=n.y-r.y,s=r.x-n.x,c=n.x*r.y-r.x*n.y,h=a*t.x+s*t.y+c,u=a*e.x+s*e.y+c,0!==h&&0!==u&&K(h,u)||0==(f=i*s-a*o))))return g=Math.abs(f/2),{x:(m=o*c-s*l)<0?(m-g)/f:(m+g)/f,y:(m=a*l-i*c)<0?(m-g)/f:(m+g)/f}}function K(t,e){return t*e>0}(0,s.K2)(z,"intersectLine"),(0,s.K2)(K,"sameSign");var q=z;function W(t,e,r){let n=t.x,i=t.y,a=[],o=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY;"function"==typeof e.forEach?e.forEach((function(t){o=Math.min(o,t.x),s=Math.min(s,t.y)})):(o=Math.min(o,e.x),s=Math.min(s,e.y));let l=n-t.width/2-o,c=i-t.height/2-s;for(let h=0;h<e.length;h++){let n=e[h],i=e[h<e.length-1?h+1:0],o=q(t,r,{x:l+n.x,y:c+n.y},{x:l+i.x,y:c+i.y});o&&a.push(o)}return a.length?(a.length>1&&a.sort((function(t,e){let n=t.x-r.x,i=t.y-r.y,a=Math.sqrt(n*n+i*i),o=e.x-r.x,s=e.y-r.y,l=Math.sqrt(o*o+s*s);return a<l?-1:a===l?0:1})),a[0]):t}(0,s.K2)(W,"intersectPolygon");var H={node:j,circle:P,ellipse:O,polygon:W,rect:y};function U(t,e){const{labelStyles:r}=S(e);e.labelStyle=r;const n=p(e);let i=n;n||(i="anchor");const a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),{cssStyles:l}=e,h=c.A.svg(a),u=A(e,{fill:"black",stroke:"none",fillStyle:"solid"});"handDrawn"!==e.look&&(u.roughness=0);const f=h.circle(0,0,2,u),g=a.insert((()=>f),":first-child");return g.attr("class","anchor").attr("style",(0,o.KL)(l)),d(e,g),e.intersect=function(t){return s.Rm.info("Circle intersect",e,1,t),H.circle(e,1,t)},a}function Y(t,e,r,n,i,a,o){const s=(t+r)/2,l=(e+n)/2,c=Math.atan2(n-e,r-t),h=(r-t)/2/i,u=(n-e)/2/a,d=Math.sqrt(h**2+u**2);if(d>1)throw new Error("The given radii are too small to create an arc between the points.");const p=Math.sqrt(1-d**2),f=s+p*a*Math.sin(c)*(o?-1:1),g=l-p*i*Math.cos(c)*(o?-1:1),m=Math.atan2((e-g)/a,(t-f)/i);let y=Math.atan2((n-g)/a,(r-f)/i)-m;o&&y<0&&(y+=2*Math.PI),!o&&y>0&&(y-=2*Math.PI);const x=[];for(let b=0;b<20;b++){const t=m+b/19*y,e=f+i*Math.cos(t),r=g+a*Math.sin(t);x.push({x:e,y:r})}return x}async function V(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=a.width+e.padding+20,s=a.height+e.padding,l=s/2,u=l/(2.5+s/50),{cssStyles:g}=e,m=[{x:o/2,y:-s/2},{x:-o/2,y:-s/2},...Y(-o/2,-s/2,-o/2,s/2,u,l,!1),{x:o/2,y:s/2},...Y(o/2,s/2,o/2,-s/2,u,l,!0)],y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=f(m),k=y.path(b,x),C=i.insert((()=>k),":first-child");return C.attr("class","basic label-container"),g&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",g),n&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${u/2}, 0)`),d(e,C),e.intersect=function(t){return H.polygon(e,m,t)},i}function G(t,e,r,n){return t.insert("polygon",":first-child").attr("points",n.map((function(t){return t.x+","+t.y})).join(" ")).attr("class","label-container").attr("transform","translate("+-e/2+","+r/2+")")}async function Z(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=a.height+e.padding,s=a.width+e.padding+12,l=-o,u=[{x:12,y:l},{x:s,y:l},{x:s,y:0},{x:0,y:0},{x:0,y:l+12},{x:12,y:l}];let g;const{cssStyles:m}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=f(u),a=t.path(n,r);g=i.insert((()=>a),":first-child").attr("transform",`translate(${-s/2}, ${o/2})`),m&&g.attr("style",m)}else g=G(i,s,o,u);return n&&g.attr("style",n),d(e,g),e.intersect=function(t){return H.polygon(e,u,t)},i}function X(t,e){const{nodeStyles:r}=S(e);e.label="";const n=t.insert("g").attr("class",p(e)).attr("id",e.domId??e.id),{cssStyles:i}=e,a=Math.max(28,e.width??0),o=[{x:0,y:a/2},{x:a/2,y:0},{x:0,y:-a/2},{x:-a/2,y:0}],s=c.A.svg(n),l=A(e,{});"handDrawn"!==e.look&&(l.roughness=0,l.fillStyle="solid");const h=f(o),u=s.path(h,l),d=n.insert((()=>u),":first-child");return i&&"handDrawn"!==e.look&&d.selectAll("path").attr("style",i),r&&"handDrawn"!==e.look&&d.selectAll("path").attr("style",r),e.width=28,e.height=28,e.intersect=function(t){return H.polygon(e,o,t)},n}async function Q(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,halfPadding:l}=await h(t,e,p(e)),u=a.width/2+l;let f;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=t.circle(0,0,2*u,r);f=i.insert((()=>n),":first-child"),f.attr("class","basic label-container").attr("style",(0,o.KL)(g))}else f=i.insert("circle",":first-child").attr("class","basic label-container").attr("style",n).attr("r",u).attr("cx",0).attr("cy",0);return d(e,f),e.intersect=function(t){return s.Rm.info("Circle intersect",e,u,t),H.circle(e,u,t)},i}function J(t){const e=Math.cos(Math.PI/4),r=Math.sin(Math.PI/4),n=2*t;return`M ${-n/2*e},${n/2*r} L ${n/2*e},${-n/2*r}\n M ${n/2*e},${n/2*r} L ${-n/2*e},${-n/2*r}`}function tt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r,e.label="";const i=t.insert("g").attr("class",p(e)).attr("id",e.domId??e.id),a=Math.max(30,e?.width??0),{cssStyles:o}=e,l=c.A.svg(i),h=A(e,{});"handDrawn"!==e.look&&(h.roughness=0,h.fillStyle="solid");const u=l.circle(0,0,2*a,h),f=J(a),g=l.path(f,h),m=i.insert((()=>u),":first-child");return m.insert((()=>g)),o&&"handDrawn"!==e.look&&m.selectAll("path").attr("style",o),n&&"handDrawn"!==e.look&&m.selectAll("path").attr("style",n),d(e,m),e.intersect=function(t){s.Rm.info("crossedCircle intersect",e,{radius:a,point:t});return H.circle(e,a,t)},i}function et(t,e,r,n=100,i=0,a=180){const o=[],s=i*Math.PI/180,l=(a*Math.PI/180-s)/(n-1);for(let c=0;c<n;c++){const n=s+c*l,i=t+r*Math.cos(n),a=e+r*Math.sin(n);o.push({x:-i,y:-a})}return o}async function rt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=a.width+(e.padding??0),l=a.height+(e.padding??0),u=Math.max(5,.1*l),{cssStyles:g}=e,m=[...et(s/2,-l/2,u,30,-90,0),{x:-s/2-u,y:u},...et(s/2+2*u,-u,u,20,-180,-270),...et(s/2+2*u,u,u,20,-90,-180),{x:-s/2-u,y:-l/2},...et(s/2,l/2,u,20,0,90)],y=[{x:s/2,y:-l/2-u},{x:-s/2,y:-l/2-u},...et(s/2,-l/2,u,20,-90,0),{x:-s/2-u,y:-u},...et(s/2+.1*s,-u,u,20,-180,-270),...et(s/2+.1*s,u,u,20,-90,-180),{x:-s/2-u,y:l/2},...et(s/2,l/2,u,20,0,90),{x:-s/2,y:l/2+u},{x:s/2,y:l/2+u}],x=c.A.svg(i),b=A(e,{fill:"none"});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=f(m).replace("Z",""),C=x.path(k,b),w=f(y),_=x.path(w,{...b}),v=i.insert("g",":first-child");return v.insert((()=>_),":first-child").attr("stroke-opacity",0),v.insert((()=>C),":first-child"),v.attr("class","text"),g&&"handDrawn"!==e.look&&v.selectAll("path").attr("style",g),n&&"handDrawn"!==e.look&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(${u}, 0)`),o.attr("transform",`translate(${-s/2+u-(a.x-(a.left??0))},${-l/2+(e.padding??0)/2-(a.y-(a.top??0))})`),d(e,v),e.intersect=function(t){return H.polygon(e,y,t)},i}function nt(t,e,r,n=100,i=0,a=180){const o=[],s=i*Math.PI/180,l=(a*Math.PI/180-s)/(n-1);for(let c=0;c<n;c++){const n=s+c*l,i=t+r*Math.cos(n),a=e+r*Math.sin(n);o.push({x:i,y:a})}return o}async function it(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=a.width+(e.padding??0),l=a.height+(e.padding??0),u=Math.max(5,.1*l),{cssStyles:g}=e,m=[...nt(s/2,-l/2,u,20,-90,0),{x:s/2+u,y:-u},...nt(s/2+2*u,-u,u,20,-180,-270),...nt(s/2+2*u,u,u,20,-90,-180),{x:s/2+u,y:l/2},...nt(s/2,l/2,u,20,0,90)],y=[{x:-s/2,y:-l/2-u},{x:s/2,y:-l/2-u},...nt(s/2,-l/2,u,20,-90,0),{x:s/2+u,y:-u},...nt(s/2+2*u,-u,u,20,-180,-270),...nt(s/2+2*u,u,u,20,-90,-180),{x:s/2+u,y:l/2},...nt(s/2,l/2,u,20,0,90),{x:s/2,y:l/2+u},{x:-s/2,y:l/2+u}],x=c.A.svg(i),b=A(e,{fill:"none"});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=f(m).replace("Z",""),C=x.path(k,b),w=f(y),_=x.path(w,{...b}),v=i.insert("g",":first-child");return v.insert((()=>_),":first-child").attr("stroke-opacity",0),v.insert((()=>C),":first-child"),v.attr("class","text"),g&&"handDrawn"!==e.look&&v.selectAll("path").attr("style",g),n&&"handDrawn"!==e.look&&v.selectAll("path").attr("style",n),v.attr("transform",`translate(${-u}, 0)`),o.attr("transform",`translate(${-s/2+(e.padding??0)/2-(a.x-(a.left??0))},${-l/2+(e.padding??0)/2-(a.y-(a.top??0))})`),d(e,v),e.intersect=function(t){return H.polygon(e,y,t)},i}function at(t,e,r,n=100,i=0,a=180){const o=[],s=i*Math.PI/180,l=(a*Math.PI/180-s)/(n-1);for(let c=0;c<n;c++){const n=s+c*l,i=t+r*Math.cos(n),a=e+r*Math.sin(n);o.push({x:-i,y:-a})}return o}async function ot(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=a.width+(e.padding??0),l=a.height+(e.padding??0),u=Math.max(5,.1*l),{cssStyles:g}=e,m=[...at(s/2,-l/2,u,30,-90,0),{x:-s/2-u,y:u},...at(s/2+2*u,-u,u,20,-180,-270),...at(s/2+2*u,u,u,20,-90,-180),{x:-s/2-u,y:-l/2},...at(s/2,l/2,u,20,0,90)],y=[...at(-s/2+u+u/2,-l/2,u,20,-90,-180),{x:s/2-u/2,y:u},...at(-s/2-u/2,-u,u,20,0,90),...at(-s/2-u/2,u,u,20,-90,0),{x:s/2-u/2,y:-u},...at(-s/2+u+u/2,l/2,u,30,-180,-270)],x=[{x:s/2,y:-l/2-u},{x:-s/2,y:-l/2-u},...at(s/2,-l/2,u,20,-90,0),{x:-s/2-u,y:-u},...at(s/2+2*u,-u,u,20,-180,-270),...at(s/2+2*u,u,u,20,-90,-180),{x:-s/2-u,y:l/2},...at(s/2,l/2,u,20,0,90),{x:-s/2,y:l/2+u},{x:s/2-u-u/2,y:l/2+u},...at(-s/2+u+u/2,-l/2,u,20,-90,-180),{x:s/2-u/2,y:u},...at(-s/2-u/2,-u,u,20,0,90),...at(-s/2-u/2,u,u,20,-90,0),{x:s/2-u/2,y:-u},...at(-s/2+u+u/2,l/2,u,30,-180,-270)],b=c.A.svg(i),k=A(e,{fill:"none"});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const C=f(m).replace("Z",""),w=b.path(C,k),_=f(y).replace("Z",""),v=b.path(_,k),T=f(x),M=b.path(T,{...k}),B=i.insert("g",":first-child");return B.insert((()=>M),":first-child").attr("stroke-opacity",0),B.insert((()=>w),":first-child"),B.insert((()=>v),":first-child"),B.attr("class","text"),g&&"handDrawn"!==e.look&&B.selectAll("path").attr("style",g),n&&"handDrawn"!==e.look&&B.selectAll("path").attr("style",n),B.attr("transform",`translate(${u-u/4}, 0)`),o.attr("transform",`translate(${-s/2+(e.padding??0)/2-(a.x-(a.left??0))},${-l/2+(e.padding??0)/2-(a.y-(a.top??0))})`),d(e,B),e.intersect=function(t){return H.polygon(e,x,t)},i}async function st(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(80,1.25*(a.width+2*(e.padding??0)),e?.width??0),s=Math.max(20,a.height+2*(e.padding??0),e?.height??0),l=s/2,{cssStyles:u}=e,g=c.A.svg(i),y=A(e,{});"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");const x=o-l,b=s/4,k=[{x:x,y:0},{x:b,y:0},{x:0,y:s/2},{x:b,y:s},{x:x,y:s},...m(-x,-s/2,l,50,270,90)],C=f(k),w=g.path(C,y),_=i.insert((()=>w),":first-child");return _.attr("class","basic label-container"),u&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",u),n&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",n),_.attr("transform",`translate(${-o/2}, ${-s/2})`),d(e,_),e.intersect=function(t){return H.polygon(e,k,t)},i}(0,s.K2)(U,"anchor"),(0,s.K2)(Y,"generateArcPoints"),(0,s.K2)(V,"bowTieRect"),(0,s.K2)(G,"insertPolygonShape"),(0,s.K2)(Z,"card"),(0,s.K2)(X,"choice"),(0,s.K2)(Q,"circle"),(0,s.K2)(J,"createLine"),(0,s.K2)(tt,"crossedCircle"),(0,s.K2)(et,"generateCirclePoints"),(0,s.K2)(rt,"curlyBraceLeft"),(0,s.K2)(nt,"generateCirclePoints"),(0,s.K2)(it,"curlyBraceRight"),(0,s.K2)(at,"generateCirclePoints"),(0,s.K2)(ot,"curlyBraces"),(0,s.K2)(st,"curvedTrapezoid");var lt=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,"l0,"+-n].join(" ")),"createCylinderPathD"),ct=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,"l0,"+-n].join(" ")),"createOuterCylinderPathD"),ht=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" ")),"createInnerCylinderPathD");async function ut(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:s}=await h(t,e,p(e)),l=Math.max(a.width+e.padding,e.width??0),u=l/2,f=u/(2.5+l/50),g=Math.max(a.height+f+e.padding,e.height??0);let m;const{cssStyles:y}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=ct(0,0,l,g,u,f),n=ht(0,f,l,g,u,f),a=t.path(r,A(e,{})),o=t.path(n,A(e,{fill:"none"}));m=i.insert((()=>o),":first-child"),m=i.insert((()=>a),":first-child"),m.attr("class","basic label-container"),y&&m.attr("style",y)}else{const t=lt(0,0,l,g,u,f);m=i.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(y)).attr("style",n)}return m.attr("label-offset-y",f),m.attr("transform",`translate(${-l/2}, ${-(g/2+f)})`),d(e,m),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-a.height/2+(e.padding??0)/1.5-(a.y-(a.top??0))})`),e.intersect=function(t){const r=H.rect(e,t),n=r.x-(e.x??0);if(0!=u&&(Math.abs(n)<(e.width??0)/2||Math.abs(n)==(e.width??0)/2&&Math.abs(r.y-(e.y??0))>(e.height??0)/2-f)){let i=f*f*(1-n*n/(u*u));i>0&&(i=Math.sqrt(i)),i=f-i,t.y-(e.y??0)>0&&(i=-i),r.y+=i}return r},i}async function dt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=a.width+e.padding,l=a.height+e.padding,u=.2*l,f=-s/2,g=-l/2-u/2,{cssStyles:m}=e,y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=[{x:f,y:g+u},{x:-f,y:g+u},{x:-f,y:-g},{x:f,y:-g},{x:f,y:g},{x:-f,y:g},{x:-f,y:g+u}],k=y.polygon(b.map((t=>[t.x,t.y])),x),C=i.insert((()=>k),":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),n&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",n),o.attr("transform",`translate(${f+(e.padding??0)/2-(a.x-(a.left??0))}, ${g+u+(e.padding??0)/2-(a.y-(a.top??0))})`),d(e,C),e.intersect=function(t){return H.rect(e,t)},i}async function pt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,halfPadding:l}=await h(t,e,p(e)),u=a.width/2+l+5,f=a.width/2+l;let g;const{cssStyles:m}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{roughness:.2,strokeWidth:2.5}),n=A(e,{roughness:.2,strokeWidth:1.5}),a=t.circle(0,0,2*u,r),s=t.circle(0,0,2*f,n);g=i.insert("g",":first-child"),g.attr("class",(0,o.KL)(e.cssClasses)).attr("style",(0,o.KL)(m)),g.node()?.appendChild(a),g.node()?.appendChild(s)}else{g=i.insert("g",":first-child");const t=g.insert("circle",":first-child"),e=g.insert("circle");g.attr("class","basic label-container").attr("style",n),t.attr("class","outer-circle").attr("style",n).attr("r",u).attr("cx",0).attr("cy",0),e.attr("class","inner-circle").attr("style",n).attr("r",f).attr("cx",0).attr("cy",0)}return d(e,g),e.intersect=function(t){return s.Rm.info("DoubleCircle intersect",e,u,t),H.circle(e,u,t)},i}function ft(t,e,{config:{themeVariables:r}}){const{labelStyles:n,nodeStyles:i}=S(e);e.label="",e.labelStyle=n;const a=t.insert("g").attr("class",p(e)).attr("id",e.domId??e.id),{cssStyles:o}=e,l=c.A.svg(a),{nodeBorder:h}=r,u=A(e,{fillStyle:"solid"});"handDrawn"!==e.look&&(u.roughness=0);const f=l.circle(0,0,14,u),g=a.insert((()=>f),":first-child");return g.selectAll("path").attr("style",`fill: ${h} !important;`),o&&o.length>0&&"handDrawn"!==e.look&&g.selectAll("path").attr("style",o),i&&"handDrawn"!==e.look&&g.selectAll("path").attr("style",i),d(e,g),e.intersect=function(t){s.Rm.info("filledCircle intersect",e,{radius:7,point:t});return H.circle(e,7,t)},a}async function gt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),l=a.width+(e.padding??0),u=l+a.height,g=l+a.height,m=[{x:0,y:-u},{x:g,y:-u},{x:g/2,y:0}],{cssStyles:y}=e,x=c.A.svg(i),b=A(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=f(m),C=x.path(k,b),w=i.insert((()=>C),":first-child").attr("transform",`translate(${-u/2}, ${u/2})`);return y&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",y),n&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",n),e.width=l,e.height=u,d(e,w),o.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-u/2+(e.padding??0)/2+(a.y-(a.top??0))})`),e.intersect=function(t){return s.Rm.info("Triangle intersect",e,m,t),H.polygon(e,m,t)},i}function mt(t,e,{dir:r,config:{state:n,themeVariables:i}}){const{nodeStyles:a}=S(e);e.label="";const o=t.insert("g").attr("class",p(e)).attr("id",e.domId??e.id),{cssStyles:s}=e;let l=Math.max(70,e?.width??0),h=Math.max(10,e?.height??0);"LR"===r&&(l=Math.max(10,e?.width??0),h=Math.max(70,e?.height??0));const u=-1*l/2,f=-1*h/2,g=c.A.svg(o),m=A(e,{stroke:i.lineColor,fill:i.lineColor});"handDrawn"!==e.look&&(m.roughness=0,m.fillStyle="solid");const y=g.rectangle(u,f,l,h,m),x=o.insert((()=>y),":first-child");s&&"handDrawn"!==e.look&&x.selectAll("path").attr("style",s),a&&"handDrawn"!==e.look&&x.selectAll("path").attr("style",a),d(e,x);const b=n?.padding??0;return e.width&&e.height&&(e.width+=b/2||0,e.height+=b/2||0),e.intersect=function(t){return H.rect(e,t)},o}async function yt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(80,a.width+2*(e.padding??0),e?.width??0),l=Math.max(50,a.height+2*(e.padding??0),e?.height??0),u=l/2,{cssStyles:g}=e,y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=[{x:-o/2,y:-l/2},{x:o/2-u,y:-l/2},...m(-o/2+u,0,u,50,90,270),{x:o/2-u,y:l/2},{x:-o/2,y:l/2}],k=f(b),C=y.path(k,x),w=i.insert((()=>C),":first-child");return w.attr("class","basic label-container"),g&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",g),n&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",n),d(e,w),e.intersect=function(t){s.Rm.info("Pill intersect",e,{radius:u,point:t});return H.polygon(e,b,t)},i}(0,s.K2)(ut,"cylinder"),(0,s.K2)(dt,"dividedRectangle"),(0,s.K2)(pt,"doublecircle"),(0,s.K2)(ft,"filledCircle"),(0,s.K2)(gt,"flippedTriangle"),(0,s.K2)(mt,"forkJoin"),(0,s.K2)(yt,"halfRoundedRectangle");var xt=(0,s.K2)(((t,e,r,n,i)=>[`M${t+i},${e}`,`L${t+r-i},${e}`,`L${t+r},${e-n/2}`,`L${t+r-i},${e-n}`,`L${t+i},${e-n}`,`L${t},${e-n/2}`,"Z"].join(" ")),"createHexagonPathD");async function bt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=a.height+e.padding,s=o/4,l=a.width+2*s+e.padding,u=[{x:s,y:0},{x:l-s,y:0},{x:l,y:-o/2},{x:l-s,y:-o},{x:s,y:-o},{x:0,y:-o/2}];let f;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=xt(0,0,l,o,s),a=t.path(n,r);f=i.insert((()=>a),":first-child").attr("transform",`translate(${-l/2}, ${o/2})`),g&&f.attr("style",g)}else f=G(i,l,o,u);return n&&f.attr("style",n),e.width=l,e.height=o,d(e,f),e.intersect=function(t){return H.polygon(e,u,t)},i}async function kt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.label="",e.labelStyle=r;const{shapeSvg:i}=await h(t,e,p(e)),a=Math.max(30,e?.width??0),o=Math.max(30,e?.height??0),{cssStyles:l}=e,u=c.A.svg(i),g=A(e,{});"handDrawn"!==e.look&&(g.roughness=0,g.fillStyle="solid");const m=[{x:0,y:0},{x:a,y:0},{x:0,y:o},{x:a,y:o}],y=f(m),x=u.path(y,g),b=i.insert((()=>x),":first-child");return b.attr("class","basic label-container"),l&&"handDrawn"!==e.look&&b.selectChildren("path").attr("style",l),n&&"handDrawn"!==e.look&&b.selectChildren("path").attr("style",n),b.attr("transform",`translate(${-a/2}, ${-o/2})`),d(e,b),e.intersect=function(t){s.Rm.info("Pill intersect",e,{points:m});return H.polygon(e,m,t)},i}async function Ct(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:a}=S(e);e.labelStyle=a;const o=e.assetHeight??48,l=e.assetWidth??48,u=Math.max(o,l),p=i?.wrappingWidth;e.width=Math.max(u,p??0);const{shapeSvg:f,bbox:g,label:m}=await h(t,e,"icon-shape default"),y="t"===e.pos,x=u,b=u,{nodeBorder:k}=r,{stylesMap:C}=_(e),w=-b/2,v=-x/2,T=e.label?8:0,M=c.A.svg(f),B=A(e,{stroke:"none",fill:"none"});"handDrawn"!==e.look&&(B.roughness=0,B.fillStyle="solid");const L=M.rectangle(w,v,b,x,B),F=Math.max(b,g.width),$=x+g.height+T,E=M.rectangle(-F/2,-$/2,F,$,{...B,fill:"transparent",stroke:"none"}),N=f.insert((()=>L),":first-child"),D=f.insert((()=>E));if(e.icon){const t=f.append("g");t.html(`<g>${await(0,n.WY)(e.icon,{height:u,width:u,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,a=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${y?g.height/2+T/2-a/2-s:-g.height/2-T/2-a/2-s})`),t.attr("style",`color: ${C.get("stroke")??k};`)}return m.attr("transform",`translate(${-g.width/2-(g.x-(g.left??0))},${y?-$/2:$/2-g.height})`),N.attr("transform",`translate(0,${y?g.height/2+T/2:-g.height/2-T/2})`),d(e,D),e.intersect=function(t){if(s.Rm.info("iconSquare intersect",e,t),!e.label)return H.rect(e,t);const r=e.x??0,n=e.y??0,i=e.height??0;let a=[];a=y?[{x:r-g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2+g.height+T},{x:r+b/2,y:n-i/2+g.height+T},{x:r+b/2,y:n+i/2},{x:r-b/2,y:n+i/2},{x:r-b/2,y:n-i/2+g.height+T},{x:r-g.width/2,y:n-i/2+g.height+T}]:[{x:r-b/2,y:n-i/2},{x:r+b/2,y:n-i/2},{x:r+b/2,y:n-i/2+x},{x:r+g.width/2,y:n-i/2+x},{x:r+g.width/2/2,y:n+i/2},{x:r-g.width/2,y:n+i/2},{x:r-g.width/2,y:n-i/2+x},{x:r-b/2,y:n-i/2+x}];return H.polygon(e,a,t)},f}async function wt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:a}=S(e);e.labelStyle=a;const o=e.assetHeight??48,l=e.assetWidth??48,u=Math.max(o,l),p=i?.wrappingWidth;e.width=Math.max(u,p??0);const{shapeSvg:f,bbox:g,label:m}=await h(t,e,"icon-shape default"),y=e.label?8:0,x="t"===e.pos,{nodeBorder:b,mainBkg:k}=r,{stylesMap:C}=_(e),w=c.A.svg(f),v=A(e,{});"handDrawn"!==e.look&&(v.roughness=0,v.fillStyle="solid");const T=C.get("fill");v.stroke=T??k;const M=f.append("g");e.icon&&M.html(`<g>${await(0,n.WY)(e.icon,{height:u,width:u,fallbackPrefix:""})}</g>`);const B=M.node().getBBox(),L=B.width,F=B.height,$=B.x,E=B.y,N=Math.max(L,F)*Math.SQRT2+40,D=w.circle(0,0,N,v),j=Math.max(N,g.width),I=N+g.height+y,O=w.rectangle(-j/2,-I/2,j,I,{...v,fill:"transparent",stroke:"none"}),R=f.insert((()=>D),":first-child"),P=f.insert((()=>O));return M.attr("transform",`translate(${-L/2-$},${x?g.height/2+y/2-F/2-E:-g.height/2-y/2-F/2-E})`),M.attr("style",`color: ${C.get("stroke")??b};`),m.attr("transform",`translate(${-g.width/2-(g.x-(g.left??0))},${x?-I/2:I/2-g.height})`),R.attr("transform",`translate(0,${x?g.height/2+y/2:-g.height/2-y/2})`),d(e,P),e.intersect=function(t){s.Rm.info("iconSquare intersect",e,t);return H.rect(e,t)},f}async function _t(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:a}=S(e);e.labelStyle=a;const o=e.assetHeight??48,l=e.assetWidth??48,u=Math.max(o,l),p=i?.wrappingWidth;e.width=Math.max(u,p??0);const{shapeSvg:f,bbox:g,halfPadding:m,label:y}=await h(t,e,"icon-shape default"),x="t"===e.pos,b=u+2*m,k=u+2*m,{nodeBorder:w,mainBkg:v}=r,{stylesMap:T}=_(e),M=-k/2,B=-b/2,L=e.label?8:0,F=c.A.svg(f),$=A(e,{});"handDrawn"!==e.look&&($.roughness=0,$.fillStyle="solid");const E=T.get("fill");$.stroke=E??v;const N=F.path(C(M,B,k,b,5),$),D=Math.max(k,g.width),j=b+g.height+L,I=F.rectangle(-D/2,-j/2,D,j,{...$,fill:"transparent",stroke:"none"}),O=f.insert((()=>N),":first-child").attr("class","icon-shape2"),R=f.insert((()=>I));if(e.icon){const t=f.append("g");t.html(`<g>${await(0,n.WY)(e.icon,{height:u,width:u,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,a=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${x?g.height/2+L/2-a/2-s:-g.height/2-L/2-a/2-s})`),t.attr("style",`color: ${T.get("stroke")??w};`)}return y.attr("transform",`translate(${-g.width/2-(g.x-(g.left??0))},${x?-j/2:j/2-g.height})`),O.attr("transform",`translate(0,${x?g.height/2+L/2:-g.height/2-L/2})`),d(e,R),e.intersect=function(t){if(s.Rm.info("iconSquare intersect",e,t),!e.label)return H.rect(e,t);const r=e.x??0,n=e.y??0,i=e.height??0;let a=[];a=x?[{x:r-g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2+g.height+L},{x:r+k/2,y:n-i/2+g.height+L},{x:r+k/2,y:n+i/2},{x:r-k/2,y:n+i/2},{x:r-k/2,y:n-i/2+g.height+L},{x:r-g.width/2,y:n-i/2+g.height+L}]:[{x:r-k/2,y:n-i/2},{x:r+k/2,y:n-i/2},{x:r+k/2,y:n-i/2+b},{x:r+g.width/2,y:n-i/2+b},{x:r+g.width/2/2,y:n+i/2},{x:r-g.width/2,y:n+i/2},{x:r-g.width/2,y:n-i/2+b},{x:r-k/2,y:n-i/2+b}];return H.polygon(e,a,t)},f}async function vt(t,e,{config:{themeVariables:r,flowchart:i}}){const{labelStyles:a}=S(e);e.labelStyle=a;const o=e.assetHeight??48,l=e.assetWidth??48,u=Math.max(o,l),p=i?.wrappingWidth;e.width=Math.max(u,p??0);const{shapeSvg:f,bbox:g,halfPadding:m,label:y}=await h(t,e,"icon-shape default"),x="t"===e.pos,b=u+2*m,k=u+2*m,{nodeBorder:w,mainBkg:v}=r,{stylesMap:T}=_(e),M=-k/2,B=-b/2,L=e.label?8:0,F=c.A.svg(f),$=A(e,{});"handDrawn"!==e.look&&($.roughness=0,$.fillStyle="solid");const E=T.get("fill");$.stroke=E??v;const N=F.path(C(M,B,k,b,.1),$),D=Math.max(k,g.width),j=b+g.height+L,I=F.rectangle(-D/2,-j/2,D,j,{...$,fill:"transparent",stroke:"none"}),O=f.insert((()=>N),":first-child"),R=f.insert((()=>I));if(e.icon){const t=f.append("g");t.html(`<g>${await(0,n.WY)(e.icon,{height:u,width:u,fallbackPrefix:""})}</g>`);const r=t.node().getBBox(),i=r.width,a=r.height,o=r.x,s=r.y;t.attr("transform",`translate(${-i/2-o},${x?g.height/2+L/2-a/2-s:-g.height/2-L/2-a/2-s})`),t.attr("style",`color: ${T.get("stroke")??w};`)}return y.attr("transform",`translate(${-g.width/2-(g.x-(g.left??0))},${x?-j/2:j/2-g.height})`),O.attr("transform",`translate(0,${x?g.height/2+L/2:-g.height/2-L/2})`),d(e,R),e.intersect=function(t){if(s.Rm.info("iconSquare intersect",e,t),!e.label)return H.rect(e,t);const r=e.x??0,n=e.y??0,i=e.height??0;let a=[];a=x?[{x:r-g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2},{x:r+g.width/2,y:n-i/2+g.height+L},{x:r+k/2,y:n-i/2+g.height+L},{x:r+k/2,y:n+i/2},{x:r-k/2,y:n+i/2},{x:r-k/2,y:n-i/2+g.height+L},{x:r-g.width/2,y:n-i/2+g.height+L}]:[{x:r-k/2,y:n-i/2},{x:r+k/2,y:n-i/2},{x:r+k/2,y:n-i/2+b},{x:r+g.width/2,y:n-i/2+b},{x:r+g.width/2/2,y:n+i/2},{x:r-g.width/2,y:n+i/2},{x:r-g.width/2,y:n-i/2+b},{x:r-k/2,y:n-i/2+b}];return H.polygon(e,a,t)},f}async function St(t,e,{config:{flowchart:r}}){const n=new Image;n.src=e?.img??"",await n.decode();const i=Number(n.naturalWidth.toString().replace("px","")),a=Number(n.naturalHeight.toString().replace("px",""));e.imageAspectRatio=i/a;const{labelStyles:o}=S(e);e.labelStyle=o;const l=r?.wrappingWidth;e.defaultWidth=r?.wrappingWidth;const u=Math.max(e.label?l??0:0,e?.assetWidth??i),p="on"===e.constraint&&e?.assetHeight?e.assetHeight*e.imageAspectRatio:u,f="on"===e.constraint?p/e.imageAspectRatio:e?.assetHeight??a;e.width=Math.max(p,l??0);const{shapeSvg:g,bbox:m,label:y}=await h(t,e,"image-shape default"),x="t"===e.pos,b=-p/2,k=-f/2,C=e.label?8:0,w=c.A.svg(g),_=A(e,{});"handDrawn"!==e.look&&(_.roughness=0,_.fillStyle="solid");const v=w.rectangle(b,k,p,f,_),T=Math.max(p,m.width),M=f+m.height+C,B=w.rectangle(-T/2,-M/2,T,M,{..._,fill:"none",stroke:"none"}),L=g.insert((()=>v),":first-child"),F=g.insert((()=>B));if(e.img){const t=g.append("image");t.attr("href",e.img),t.attr("width",p),t.attr("height",f),t.attr("preserveAspectRatio","none"),t.attr("transform",`translate(${-p/2},${x?M/2-f:-M/2})`)}return y.attr("transform",`translate(${-m.width/2-(m.x-(m.left??0))},${x?-f/2-m.height/2-C/2:f/2-m.height/2+C/2})`),L.attr("transform",`translate(0,${x?m.height/2+C/2:-m.height/2-C/2})`),d(e,F),e.intersect=function(t){if(s.Rm.info("iconSquare intersect",e,t),!e.label)return H.rect(e,t);const r=e.x??0,n=e.y??0,i=e.height??0;let a=[];a=x?[{x:r-m.width/2,y:n-i/2},{x:r+m.width/2,y:n-i/2},{x:r+m.width/2,y:n-i/2+m.height+C},{x:r+p/2,y:n-i/2+m.height+C},{x:r+p/2,y:n+i/2},{x:r-p/2,y:n+i/2},{x:r-p/2,y:n-i/2+m.height+C},{x:r-m.width/2,y:n-i/2+m.height+C}]:[{x:r-p/2,y:n-i/2},{x:r+p/2,y:n-i/2},{x:r+p/2,y:n-i/2+f},{x:r+m.width/2,y:n-i/2+f},{x:r+m.width/2/2,y:n+i/2},{x:r-m.width/2,y:n+i/2},{x:r-m.width/2,y:n-i/2+f},{x:r-p/2,y:n-i/2+f}];return H.polygon(e,a,t)},g}async function At(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+2*(e.padding??0),e?.width??0),s=Math.max(a.height+2*(e.padding??0),e?.height??0),l=[{x:0,y:0},{x:o,y:0},{x:o+3*s/6,y:-s},{x:-3*s/6,y:-s}];let u;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=f(l),a=t.path(n,r);u=i.insert((()=>a),":first-child").attr("transform",`translate(${-o/2}, ${s/2})`),g&&u.attr("style",g)}else u=G(i,o,s,l);return n&&u.attr("style",n),e.width=o,e.height=s,d(e,u),e.intersect=function(t){return H.polygon(e,l,t)},i}async function Tt(t,e,r){const{labelStyles:n,nodeStyles:i}=S(e);e.labelStyle=n;const{shapeSvg:a,bbox:s}=await h(t,e,p(e)),l=Math.max(s.width+2*r.labelPaddingX,e?.width||0),u=Math.max(s.height+2*r.labelPaddingY,e?.height||0),f=-l/2,g=-u/2;let m,{rx:y,ry:x}=e;const{cssStyles:b}=e;if(r?.rx&&r.ry&&(y=r.rx,x=r.ry),"handDrawn"===e.look){const t=c.A.svg(a),r=A(e,{}),n=y||x?t.path(C(f,g,l,u,y||0),r):t.rectangle(f,g,l,u,r);m=a.insert((()=>n),":first-child"),m.attr("class","basic label-container").attr("style",(0,o.KL)(b))}else m=a.insert("rect",":first-child"),m.attr("class","basic label-container").attr("style",i).attr("rx",(0,o.KL)(y)).attr("ry",(0,o.KL)(x)).attr("x",f).attr("y",g).attr("width",l).attr("height",u);return d(e,m),e.intersect=function(t){return H.rect(e,t)},a}async function Mt(t,e){const{shapeSvg:r,bbox:n,label:i}=await h(t,e,"label"),a=r.insert("rect",":first-child");return a.attr("width",.1).attr("height",.1),r.attr("class","label edgeLabel"),i.attr("transform",`translate(${-n.width/2-(n.x-(n.left??0))}, ${-n.height/2-(n.y-(n.top??0))})`),d(e,a),e.intersect=function(t){return H.rect(e,t)},r}async function Bt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+(e.padding??0),e?.width??0),s=Math.max(a.height+(e.padding??0),e?.height??0),l=[{x:0,y:0},{x:o+3*s/6,y:0},{x:o,y:-s},{x:-3*s/6,y:-s}];let u;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=f(l),a=t.path(n,r);u=i.insert((()=>a),":first-child").attr("transform",`translate(${-o/2}, ${s/2})`),g&&u.attr("style",g)}else u=G(i,o,s,l);return n&&u.attr("style",n),e.width=o,e.height=s,d(e,u),e.intersect=function(t){return H.polygon(e,l,t)},i}async function Lt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+(e.padding??0),e?.width??0),s=Math.max(a.height+(e.padding??0),e?.height??0),l=[{x:-3*s/6,y:0},{x:o,y:0},{x:o+3*s/6,y:-s},{x:0,y:-s}];let u;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=f(l),a=t.path(n,r);u=i.insert((()=>a),":first-child").attr("transform",`translate(${-o/2}, ${s/2})`),g&&u.attr("style",g)}else u=G(i,o,s,l);return n&&u.attr("style",n),e.width=o,e.height=s,d(e,u),e.intersect=function(t){return H.polygon(e,l,t)},i}function Ft(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.label="",e.labelStyle=r;const i=t.insert("g").attr("class",p(e)).attr("id",e.domId??e.id),{cssStyles:a}=e,o=Math.max(35,e?.width??0),l=Math.max(35,e?.height??0),h=[{x:o,y:0},{x:0,y:l+3.5},{x:o-14,y:l+3.5},{x:0,y:2*l},{x:o,y:l-3.5},{x:14,y:l-3.5}],u=c.A.svg(i),g=A(e,{});"handDrawn"!==e.look&&(g.roughness=0,g.fillStyle="solid");const m=f(h),y=u.path(m,g),x=i.insert((()=>y),":first-child");return a&&"handDrawn"!==e.look&&x.selectAll("path").attr("style",a),n&&"handDrawn"!==e.look&&x.selectAll("path").attr("style",n),x.attr("transform",`translate(-${o/2},${-l})`),d(e,x),e.intersect=function(t){s.Rm.info("lightningBolt intersect",e,t);return H.polygon(e,h,t)},i}(0,s.K2)(bt,"hexagon"),(0,s.K2)(kt,"hourglass"),(0,s.K2)(Ct,"icon"),(0,s.K2)(wt,"iconCircle"),(0,s.K2)(_t,"iconRounded"),(0,s.K2)(vt,"iconSquare"),(0,s.K2)(St,"imageSquare"),(0,s.K2)(At,"inv_trapezoid"),(0,s.K2)(Tt,"drawRect"),(0,s.K2)(Mt,"labelRect"),(0,s.K2)(Bt,"lean_left"),(0,s.K2)(Lt,"lean_right"),(0,s.K2)(Ft,"lightningBolt");var $t=(0,s.K2)(((t,e,r,n,i,a,o)=>[`M${t},${e+a}`,`a${i},${a} 0,0,0 ${r},0`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,"l0,"+-n,`M${t},${e+a+o}`,`a${i},${a} 0,0,0 ${r},0`].join(" ")),"createCylinderPathD"),Et=(0,s.K2)(((t,e,r,n,i,a,o)=>[`M${t},${e+a}`,`M${t+r},${e+a}`,`a${i},${a} 0,0,0 ${-r},0`,`l0,${n}`,`a${i},${a} 0,0,0 ${r},0`,"l0,"+-n,`M${t},${e+a+o}`,`a${i},${a} 0,0,0 ${r},0`].join(" ")),"createOuterCylinderPathD"),Nt=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t-r/2},${-n/2}`,`a${i},${a} 0,0,0 ${r},0`].join(" ")),"createInnerCylinderPathD");async function Dt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:s}=await h(t,e,p(e)),l=Math.max(a.width+(e.padding??0),e.width??0),u=l/2,f=u/(2.5+l/50),g=Math.max(a.height+f+(e.padding??0),e.height??0),m=.1*g;let y;const{cssStyles:x}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=Et(0,0,l,g,u,f,m),n=Nt(0,f,l,g,u,f),a=A(e,{}),o=t.path(r,a),s=t.path(n,a);i.insert((()=>s),":first-child").attr("class","line"),y=i.insert((()=>o),":first-child"),y.attr("class","basic label-container"),x&&y.attr("style",x)}else{const t=$t(0,0,l,g,u,f,m);y=i.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(x)).attr("style",n)}return y.attr("label-offset-y",f),y.attr("transform",`translate(${-l/2}, ${-(g/2+f)})`),d(e,y),s.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${-a.height/2+f-(a.y-(a.top??0))})`),e.intersect=function(t){const r=H.rect(e,t),n=r.x-(e.x??0);if(0!=u&&(Math.abs(n)<(e.width??0)/2||Math.abs(n)==(e.width??0)/2&&Math.abs(r.y-(e.y??0))>(e.height??0)/2-f)){let i=f*f*(1-n*n/(u*u));i>0&&(i=Math.sqrt(i)),i=f-i,t.y-(e.y??0)>0&&(i=-i),r.y+=i}return r},i}async function jt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=l/4,f=l+u,{cssStyles:m}=e,y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=[{x:-s/2-s/2*.1,y:-f/2},{x:-s/2-s/2*.1,y:f/2},...g(-s/2-s/2*.1,f/2,s/2+s/2*.1,f/2,u,.8),{x:s/2+s/2*.1,y:-f/2},{x:-s/2-s/2*.1,y:-f/2},{x:-s/2,y:-f/2},{x:-s/2,y:f/2*1.1},{x:-s/2,y:-f/2}],k=y.polygon(b.map((t=>[t.x,t.y])),x),C=i.insert((()=>k),":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),n&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(0,${-u/2})`),o.attr("transform",`translate(${-s/2+(e.padding??0)+s/2*.1/2-(a.x-(a.left??0))},${-l/2+(e.padding??0)-u/2-(a.y-(a.top??0))})`),d(e,C),e.intersect=function(t){return H.polygon(e,b,t)},i}async function It(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=-s/2,g=-l/2,{cssStyles:m}=e,y=c.A.svg(i),x=A(e,{}),b=[{x:u-5,y:g+5},{x:u-5,y:g+l+5},{x:u+s-5,y:g+l+5},{x:u+s-5,y:g+l},{x:u+s,y:g+l},{x:u+s,y:g+l-5},{x:u+s+5,y:g+l-5},{x:u+s+5,y:g-5},{x:u+5,y:g-5},{x:u+5,y:g},{x:u,y:g},{x:u,y:g+5}],k=[{x:u,y:g+5},{x:u+s-5,y:g+5},{x:u+s-5,y:g+l},{x:u+s,y:g+l},{x:u+s,y:g},{x:u,y:g}];"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const C=f(b),w=y.path(C,x),_=f(k),v=y.path(_,{...x,fill:"none"}),T=i.insert((()=>v),":first-child");return T.insert((()=>w),":first-child"),T.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",m),n&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",n),o.attr("transform",`translate(${-a.width/2-5-(a.x-(a.left??0))}, ${-a.height/2+5-(a.y-(a.top??0))})`),d(e,T),e.intersect=function(t){return H.polygon(e,b,t)},i}async function Ot(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=l/4,m=l+u,y=-s/2,x=-m/2,{cssStyles:b}=e,k=g(y-5,x+m+5,y+s-5,x+m+5,u,.8),C=k?.[k.length-1],w=[{x:y-5,y:x+5},{x:y-5,y:x+m+5},...k,{x:y+s-5,y:C.y-5},{x:y+s,y:C.y-5},{x:y+s,y:C.y-10},{x:y+s+5,y:C.y-10},{x:y+s+5,y:x-5},{x:y+5,y:x-5},{x:y+5,y:x},{x:y,y:x},{x:y,y:x+5}],_=[{x:y,y:x+5},{x:y+s-5,y:x+5},{x:y+s-5,y:C.y-5},{x:y+s,y:C.y-5},{x:y+s,y:x},{x:y,y:x}],v=c.A.svg(i),T=A(e,{});"handDrawn"!==e.look&&(T.roughness=0,T.fillStyle="solid");const M=f(w),B=v.path(M,T),L=f(_),F=v.path(L,T),$=i.insert((()=>B),":first-child");return $.insert((()=>F)),$.attr("class","basic label-container"),b&&"handDrawn"!==e.look&&$.selectAll("path").attr("style",b),n&&"handDrawn"!==e.look&&$.selectAll("path").attr("style",n),$.attr("transform",`translate(0,${-u/2})`),o.attr("transform",`translate(${-a.width/2-5-(a.x-(a.left??0))}, ${-a.height/2+5-u/2-(a.y-(a.top??0))})`),d(e,$),e.intersect=function(t){return H.polygon(e,w,t)},i}async function Rt(t,e,{config:{themeVariables:r}}){const{labelStyles:n,nodeStyles:i}=S(e);e.labelStyle=n;e.useHtmlLabels||!1!==(0,s.zj)().flowchart?.htmlLabels||(e.centerLabel=!0);const{shapeSvg:a,bbox:o}=await h(t,e,p(e)),l=Math.max(o.width+2*(e.padding??0),e?.width??0),u=Math.max(o.height+2*(e.padding??0),e?.height??0),f=-l/2,g=-u/2,{cssStyles:m}=e,y=c.A.svg(a),x=A(e,{fill:r.noteBkgColor,stroke:r.noteBorderColor});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=y.rectangle(f,g,l,u,x),k=a.insert((()=>b),":first-child");return k.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&k.selectAll("path").attr("style",m),i&&"handDrawn"!==e.look&&k.selectAll("path").attr("style",i),d(e,k),e.intersect=function(t){return H.rect(e,t)},a}(0,s.K2)(Dt,"linedCylinder"),(0,s.K2)(jt,"linedWaveEdgedRect"),(0,s.K2)(It,"multiRect"),(0,s.K2)(Ot,"multiWaveEdgedRectangle"),(0,s.K2)(Rt,"note");var Pt=(0,s.K2)(((t,e,r)=>[`M${t+r/2},${e}`,`L${t+r},${e-r/2}`,`L${t+r/2},${e-r}`,`L${t},${e-r/2}`,"Z"].join(" ")),"createDecisionBoxPathD");async function zt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=a.width+e.padding+(a.height+e.padding),l=[{x:o/2,y:0},{x:o,y:-o/2},{x:o/2,y:-o},{x:0,y:-o/2}];let u;const{cssStyles:f}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=Pt(0,0,o),a=t.path(n,r);u=i.insert((()=>a),":first-child").attr("transform",`translate(${-o/2}, ${o/2})`),f&&u.attr("style",f)}else u=G(i,o,o,l);return n&&u.attr("style",n),d(e,u),e.intersect=function(t){return s.Rm.debug("APA12 Intersect called SPLIT\npoint:",t,"\nnode:\n",e,"\nres:",H.polygon(e,l,t)),H.polygon(e,l,t)},i}async function Kt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=-Math.max(a.width+(e.padding??0),e?.width??0)/2,l=-Math.max(a.height+(e.padding??0),e?.height??0)/2,u=l/2,g=[{x:s+u,y:l},{x:s,y:0},{x:s+u,y:-l},{x:-s,y:-l},{x:-s,y:l}],{cssStyles:m}=e,y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=f(g),k=y.path(b,x),C=i.insert((()=>k),":first-child");return C.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",m),n&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",n),C.attr("transform",`translate(${-u/2},0)`),o.attr("transform",`translate(${-u/2-a.width/2-(a.x-(a.left??0))}, ${-a.height/2-(a.y-(a.top??0))})`),d(e,C),e.intersect=function(t){return H.polygon(e,g,t)},i}async function qt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);let i;e.labelStyle=r,i=e.cssClasses?"node "+e.cssClasses:"node default";const a=t.insert("g").attr("class",i).attr("id",e.domId||e.id),o=a.insert("g"),h=a.insert("g").attr("class","label").attr("style",n),u=e.description,p=e.label,f=h.node().appendChild(await k(p,e.labelStyle,!0,!0));let g={width:0,height:0};if((0,s._3)((0,s.D7)()?.flowchart?.htmlLabels)){const t=f.children[0],e=(0,l.Ltv)(f);g=t.getBoundingClientRect(),e.attr("width",g.width),e.attr("height",g.height)}s.Rm.info("Text 2",u);const m=u||[],y=f.getBBox(),x=h.node().appendChild(await k(m.join?m.join("<br/>"):m,e.labelStyle,!0,!0)),b=x.children[0],w=(0,l.Ltv)(x);g=b.getBoundingClientRect(),w.attr("width",g.width),w.attr("height",g.height);const _=(e.padding||0)/2;(0,l.Ltv)(x).attr("transform","translate( "+(g.width>y.width?0:(y.width-g.width)/2)+", "+(y.height+_+5)+")"),(0,l.Ltv)(f).attr("transform","translate( "+(g.width<y.width?0:-(y.width-g.width)/2)+", 0)"),g=h.node().getBBox(),h.attr("transform","translate("+-g.width/2+", "+(-g.height/2-_+3)+")");const v=g.width+(e.padding||0),T=g.height+(e.padding||0),M=-g.width/2-_,B=-g.height/2-_;let L,F;if("handDrawn"===e.look){const t=c.A.svg(a),r=A(e,{}),n=t.path(C(M,B,v,T,e.rx||0),r),i=t.line(-g.width/2-_,-g.height/2-_+y.height+_,g.width/2+_,-g.height/2-_+y.height+_,r);F=a.insert((()=>(s.Rm.debug("Rough node insert CXC",n),i)),":first-child"),L=a.insert((()=>(s.Rm.debug("Rough node insert CXC",n),n)),":first-child")}else L=o.insert("rect",":first-child"),F=o.insert("line"),L.attr("class","outer title-state").attr("style",n).attr("x",-g.width/2-_).attr("y",-g.height/2-_).attr("width",g.width+(e.padding||0)).attr("height",g.height+(e.padding||0)),F.attr("class","divider").attr("x1",-g.width/2-_).attr("x2",g.width/2+_).attr("y1",-g.height/2-_+y.height+_).attr("y2",-g.height/2-_+y.height+_);return d(e,L),e.intersect=function(t){return H.rect(e,t)},a}async function Wt(t,e){return Tt(t,e,{rx:5,ry:5,classes:"",labelPaddingX:1*(e?.padding||0),labelPaddingY:1*(e?.padding||0)})}async function Ht(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:s}=await h(t,e,p(e)),l=e?.padding??0,u=Math.max(a.width+2*(e.padding??0),e?.width??0),f=Math.max(a.height+2*(e.padding??0),e?.height??0),g=-a.width/2-l,m=-a.height/2-l,{cssStyles:y}=e,x=c.A.svg(i),b=A(e,{});"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const k=[{x:g,y:m},{x:g+u+8,y:m},{x:g+u+8,y:m+f},{x:g-8,y:m+f},{x:g-8,y:m},{x:g,y:m},{x:g,y:m+f}],C=x.polygon(k.map((t=>[t.x,t.y])),b),w=i.insert((()=>C),":first-child");return w.attr("class","basic label-container").attr("style",(0,o.KL)(y)),n&&"handDrawn"!==e.look&&w.selectAll("path").attr("style",n),y&&"handDrawn"!==e.look&&w.selectAll("path").attr("style",n),s.attr("transform",`translate(${-u/2+4+(e.padding??0)-(a.x-(a.left??0))},${-f/2+(e.padding??0)-(a.y-(a.top??0))})`),d(e,w),e.intersect=function(t){return H.rect(e,t)},i}async function Ut(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=-s/2,g=-l/2,{cssStyles:m}=e,y=c.A.svg(i),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=[{x:u,y:g},{x:u,y:g+l},{x:u+s,y:g+l},{x:u+s,y:g-l/2}],k=f(b),C=y.path(k,x),w=i.insert((()=>C),":first-child");return w.attr("class","basic label-container"),m&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",m),n&&"handDrawn"!==e.look&&w.selectChildren("path").attr("style",n),w.attr("transform",`translate(0, ${l/4})`),o.attr("transform",`translate(${-s/2+(e.padding??0)-(a.x-(a.left??0))}, ${-l/4+(e.padding??0)-(a.y-(a.top??0))})`),d(e,w),e.intersect=function(t){return H.polygon(e,b,t)},i}async function Yt(t,e){return Tt(t,e,{rx:0,ry:0,classes:"",labelPaddingX:2*(e?.padding||0),labelPaddingY:1*(e?.padding||0)})}async function Vt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),s=a.height+e.padding,l=a.width+s/4+e.padding;let u;const{cssStyles:f}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=C(-l/2,-s/2,l,s,s/2),a=t.path(n,r);u=i.insert((()=>a),":first-child"),u.attr("class","basic label-container").attr("style",(0,o.KL)(f))}else u=i.insert("rect",":first-child"),u.attr("class","basic label-container").attr("style",n).attr("rx",s/2).attr("ry",s/2).attr("x",-l/2).attr("y",-s/2).attr("width",l).attr("height",s);return d(e,u),e.intersect=function(t){return H.rect(e,t)},i}async function Gt(t,e){return Tt(t,e,{rx:5,ry:5,classes:"flowchart-node"})}function Zt(t,e,{config:{themeVariables:r}}){const{labelStyles:n,nodeStyles:i}=S(e);e.labelStyle=n;const{cssStyles:a}=e,{lineColor:o,stateBorder:s,nodeBorder:l}=r,h=t.insert("g").attr("class","node default").attr("id",e.domId||e.id),u=c.A.svg(h),p=A(e,{});"handDrawn"!==e.look&&(p.roughness=0,p.fillStyle="solid");const f=u.circle(0,0,14,{...p,stroke:o,strokeWidth:2}),g=s??l,m=u.circle(0,0,5,{...p,fill:g,stroke:g,strokeWidth:2,fillStyle:"solid"}),y=h.insert((()=>f),":first-child");return y.insert((()=>m)),a&&y.selectAll("path").attr("style",a),i&&y.selectAll("path").attr("style",i),d(e,y),e.intersect=function(t){return H.circle(e,7,t)},h}function Xt(t,e,{config:{themeVariables:r}}){const{lineColor:n}=r,i=t.insert("g").attr("class","node default").attr("id",e.domId||e.id);let a;if("handDrawn"===e.look){const t=c.A.svg(i).circle(0,0,14,w(n));a=i.insert((()=>t)),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14)}else a=i.insert("circle",":first-child"),a.attr("class","state-start").attr("r",7).attr("width",14).attr("height",14);return d(e,a),e.intersect=function(t){return H.circle(e,7,t)},i}async function Qt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),s=(e?.padding||0)/2,l=a.width+e.padding,u=a.height+e.padding,f=-a.width/2-s,g=-a.height/2-s,m=[{x:0,y:0},{x:l,y:0},{x:l,y:-u},{x:0,y:-u},{x:0,y:0},{x:-8,y:0},{x:l+8,y:0},{x:l+8,y:-u},{x:-8,y:-u},{x:-8,y:0}];if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=t.rectangle(f-8,g,l+16,u,r),a=t.line(f,g,f,g+u,r),s=t.line(f+l,g,f+l,g+u,r);i.insert((()=>a),":first-child"),i.insert((()=>s),":first-child");const h=i.insert((()=>n),":first-child"),{cssStyles:p}=e;h.attr("class","basic label-container").attr("style",(0,o.KL)(p)),d(e,h)}else{const t=G(i,l,u,m);n&&t.attr("style",n),d(e,t)}return e.intersect=function(t){return H.polygon(e,m,t)},i}async function Jt(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+2*(e.padding??0),e?.width??0),s=Math.max(a.height+2*(e.padding??0),e?.height??0),l=-o/2,u=-s/2,g=.2*s,m=.2*s,{cssStyles:y}=e,x=c.A.svg(i),b=A(e,{}),k=[{x:l-g/2,y:u},{x:l+o+g/2,y:u},{x:l+o+g/2,y:u+s},{x:l-g/2,y:u+s}],C=[{x:l+o-g/2,y:u+s},{x:l+o+g/2,y:u+s},{x:l+o+g/2,y:u+s-m}];"handDrawn"!==e.look&&(b.roughness=0,b.fillStyle="solid");const w=f(k),_=x.path(w,b),v=f(C),T=x.path(v,{...b,fillStyle:"solid"}),M=i.insert((()=>T),":first-child");return M.insert((()=>_),":first-child"),M.attr("class","basic label-container"),y&&"handDrawn"!==e.look&&M.selectAll("path").attr("style",y),n&&"handDrawn"!==e.look&&M.selectAll("path").attr("style",n),d(e,M),e.intersect=function(t){return H.polygon(e,k,t)},i}async function te(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=l/4,m=.2*s,y=.2*l,x=l+u,{cssStyles:b}=e,k=c.A.svg(i),C=A(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const w=[{x:-s/2-s/2*.1,y:x/2},...g(-s/2-s/2*.1,x/2,s/2+s/2*.1,x/2,u,.8),{x:s/2+s/2*.1,y:-x/2},{x:-s/2-s/2*.1,y:-x/2}],_=-s/2+s/2*.1,v=-x/2-.4*y,T=[{x:_+s-m,y:1.4*(v+l)},{x:_+s,y:v+l-y},{x:_+s,y:.9*(v+l)},...g(_+s,1.3*(v+l),_+s-m,1.5*(v+l),.03*-l,.5)],M=f(w),B=k.path(M,C),L=f(T),F=k.path(L,{...C,fillStyle:"solid"}),$=i.insert((()=>F),":first-child");return $.insert((()=>B),":first-child"),$.attr("class","basic label-container"),b&&"handDrawn"!==e.look&&$.selectAll("path").attr("style",b),n&&"handDrawn"!==e.look&&$.selectAll("path").attr("style",n),$.attr("transform",`translate(0,${-u/2})`),o.attr("transform",`translate(${-s/2+(e.padding??0)-(a.x-(a.left??0))},${-l/2+(e.padding??0)-u/2-(a.y-(a.top??0))})`),d(e,$),e.intersect=function(t){return H.polygon(e,w,t)},i}async function ee(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+e.padding,e?.width||0),s=Math.max(a.height+e.padding,e?.height||0),l=-o/2,c=-s/2,u=i.insert("rect",":first-child");return u.attr("class","text").attr("style",n).attr("rx",0).attr("ry",0).attr("x",l).attr("y",c).attr("width",o).attr("height",s),d(e,u),e.intersect=function(t){return H.rect(e,t)},i}(0,s.K2)(zt,"question"),(0,s.K2)(Kt,"rect_left_inv_arrow"),(0,s.K2)(qt,"rectWithTitle"),(0,s.K2)(Wt,"roundedRect"),(0,s.K2)(Ht,"shadedProcess"),(0,s.K2)(Ut,"slopedRect"),(0,s.K2)(Yt,"squareRect"),(0,s.K2)(Vt,"stadium"),(0,s.K2)(Gt,"state"),(0,s.K2)(Zt,"stateEnd"),(0,s.K2)(Xt,"stateStart"),(0,s.K2)(Qt,"subroutine"),(0,s.K2)(Jt,"taggedRect"),(0,s.K2)(te,"taggedWaveEdgedRectangle"),(0,s.K2)(ee,"text");var re=(0,s.K2)(((t,e,r,n,i,a)=>`M${t},${e}\n a${i},${a} 0,0,1 0,${-n}\n l${r},0\n a${i},${a} 0,0,1 0,${n}\n M${r},${-n}\n a${i},${a} 0,0,0 0,${n}\n l${-r},0`),"createCylinderPathD"),ne=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t},${e}`,`M${t+r},${e}`,`a${i},${a} 0,0,0 0,${-n}`,`l${-r},0`,`a${i},${a} 0,0,0 0,${n}`,`l${r},0`].join(" ")),"createOuterCylinderPathD"),ie=(0,s.K2)(((t,e,r,n,i,a)=>[`M${t+r/2},${-n/2}`,`a${i},${a} 0,0,0 0,${n}`].join(" ")),"createInnerCylinderPathD");async function ae(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:s,halfPadding:l}=await h(t,e,p(e)),u="neo"===e.look?2*l:l,f=a.height+u,g=f/2,m=g/(2.5+f/50),y=a.width+m+u,{cssStyles:x}=e;let b;if("handDrawn"===e.look){const t=c.A.svg(i),r=ne(0,0,y,f,m,g),n=ie(0,0,y,f,m,g),a=t.path(r,A(e,{})),o=t.path(n,A(e,{fill:"none"}));b=i.insert((()=>o),":first-child"),b=i.insert((()=>a),":first-child"),b.attr("class","basic label-container"),x&&b.attr("style",x)}else{const t=re(0,0,y,f,m,g);b=i.insert("path",":first-child").attr("d",t).attr("class","basic label-container").attr("style",(0,o.KL)(x)).attr("style",n),b.attr("class","basic label-container"),x&&b.selectAll("path").attr("style",x),n&&b.selectAll("path").attr("style",n)}return b.attr("label-offset-x",m),b.attr("transform",`translate(${-y/2}, ${f/2} )`),s.attr("transform",`translate(${-a.width/2-m-(a.x-(a.left??0))}, ${-a.height/2-(a.y-(a.top??0))})`),d(e,b),e.intersect=function(t){const r=H.rect(e,t),n=r.y-(e.y??0);if(0!=g&&(Math.abs(n)<(e.height??0)/2||Math.abs(n)==(e.height??0)/2&&Math.abs(r.x-(e.x??0))>(e.width??0)/2-m)){let i=m*m*(1-n*n/(g*g));0!=i&&(i=Math.sqrt(i)),i=m-i,t.x-(e.x??0)>0&&(i=-i),r.x+=i}return r},i}async function oe(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=a.width+e.padding,s=a.height+e.padding,l=[{x:-3*s/6,y:0},{x:o+3*s/6,y:0},{x:o,y:-s},{x:0,y:-s}];let u;const{cssStyles:g}=e;if("handDrawn"===e.look){const t=c.A.svg(i),r=A(e,{}),n=f(l),a=t.path(n,r);u=i.insert((()=>a),":first-child").attr("transform",`translate(${-o/2}, ${s/2})`),g&&u.attr("style",g)}else u=G(i,o,s,l);return n&&u.attr("style",n),e.width=o,e.height=s,d(e,u),e.intersect=function(t){return H.polygon(e,l,t)},i}async function se(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(60,a.width+2*(e.padding??0),e?.width??0),s=Math.max(20,a.height+2*(e.padding??0),e?.height??0),{cssStyles:l}=e,u=c.A.svg(i),g=A(e,{});"handDrawn"!==e.look&&(g.roughness=0,g.fillStyle="solid");const m=[{x:-o/2*.8,y:-s/2},{x:o/2*.8,y:-s/2},{x:o/2,y:-s/2*.6},{x:o/2,y:s/2},{x:-o/2,y:s/2},{x:-o/2,y:-s/2*.6}],y=f(m),x=u.path(y,g),b=i.insert((()=>x),":first-child");return b.attr("class","basic label-container"),l&&"handDrawn"!==e.look&&b.selectChildren("path").attr("style",l),n&&"handDrawn"!==e.look&&b.selectChildren("path").attr("style",n),d(e,b),e.intersect=function(t){return H.polygon(e,m,t)},i}async function le(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),l=(0,s._3)((0,s.D7)().flowchart?.htmlLabels),u=a.width+(e.padding??0),g=u+a.height,m=u+a.height,y=[{x:0,y:0},{x:m,y:0},{x:m/2,y:-g}],{cssStyles:x}=e,b=c.A.svg(i),k=A(e,{});"handDrawn"!==e.look&&(k.roughness=0,k.fillStyle="solid");const C=f(y),w=b.path(C,k),_=i.insert((()=>w),":first-child").attr("transform",`translate(${-g/2}, ${g/2})`);return x&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",x),n&&"handDrawn"!==e.look&&_.selectChildren("path").attr("style",n),e.width=u,e.height=g,d(e,_),o.attr("transform",`translate(${-a.width/2-(a.x-(a.left??0))}, ${g/2-(a.height+(e.padding??0)/(l?2:1)-(a.y-(a.top??0)))})`),e.intersect=function(t){return s.Rm.info("Triangle intersect",e,y,t),H.polygon(e,y,t)},i}async function ce(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=l/8,m=l+u,{cssStyles:y}=e,x=70-s,b=x>0?x/2:0,k=c.A.svg(i),C=A(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const w=[{x:-s/2-b,y:m/2},...g(-s/2-b,m/2,s/2+b,m/2,u,.8),{x:s/2+b,y:-m/2},{x:-s/2-b,y:-m/2}],_=f(w),v=k.path(_,C),T=i.insert((()=>v),":first-child");return T.attr("class","basic label-container"),y&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",y),n&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",n),T.attr("transform",`translate(0,${-u/2})`),o.attr("transform",`translate(${-s/2+(e.padding??0)-(a.x-(a.left??0))},${-l/2+(e.padding??0)-u-(a.y-(a.top??0))})`),d(e,T),e.intersect=function(t){return H.polygon(e,w,t)},i}async function he(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a}=await h(t,e,p(e)),o=Math.max(a.width+2*(e.padding??0),e?.width??0),s=Math.max(a.height+2*(e.padding??0),e?.height??0),l=o/s;let u=o,m=s;u>m*l?m=u/l:u=m*l,u=Math.max(u,100),m=Math.max(m,50);const y=Math.min(.2*m,m/4),x=m+2*y,{cssStyles:b}=e,k=c.A.svg(i),C=A(e,{});"handDrawn"!==e.look&&(C.roughness=0,C.fillStyle="solid");const w=[{x:-u/2,y:x/2},...g(-u/2,x/2,u/2,x/2,y,1),{x:u/2,y:-x/2},...g(u/2,-x/2,-u/2,-x/2,y,-1)],_=f(w),v=k.path(_,C),T=i.insert((()=>v),":first-child");return T.attr("class","basic label-container"),b&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",b),n&&"handDrawn"!==e.look&&T.selectAll("path").attr("style",n),d(e,T),e.intersect=function(t){return H.polygon(e,w,t)},i}async function ue(t,e){const{labelStyles:r,nodeStyles:n}=S(e);e.labelStyle=r;const{shapeSvg:i,bbox:a,label:o}=await h(t,e,p(e)),s=Math.max(a.width+2*(e.padding??0),e?.width??0),l=Math.max(a.height+2*(e.padding??0),e?.height??0),u=-s/2,f=-l/2,{cssStyles:g}=e,m=c.A.svg(i),y=A(e,{}),x=[{x:u-5,y:f-5},{x:u-5,y:f+l},{x:u+s,y:f+l},{x:u+s,y:f-5}],b=`M${u-5},${f-5} L${u+s},${f-5} L${u+s},${f+l} L${u-5},${f+l} L${u-5},${f-5}\n M${u-5},${f} L${u+s},${f}\n M${u},${f-5} L${u},${f+l}`;"handDrawn"!==e.look&&(y.roughness=0,y.fillStyle="solid");const k=m.path(b,y),C=i.insert((()=>k),":first-child");return C.attr("transform","translate(2.5, 2.5)"),C.attr("class","basic label-container"),g&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",g),n&&"handDrawn"!==e.look&&C.selectAll("path").attr("style",n),o.attr("transform",`translate(${-a.width/2+2.5-(a.x-(a.left??0))}, ${-a.height/2+2.5-(a.y-(a.top??0))})`),d(e,C),e.intersect=function(t){return H.polygon(e,x,t)},i}async function de(t,e,r,n,i=r.class.padding??12){const a=n?0:3,o=t.insert("g").attr("class",p(e)).attr("id",e.domId||e.id);let s=null,l=null,c=null,h=null,u=0,d=0,f=0;if(s=o.insert("g").attr("class","annotation-group text"),e.annotations.length>0){const t=e.annotations[0];await pe(s,{text:`\xab${t}\xbb`},0);u=s.node().getBBox().height}l=o.insert("g").attr("class","label-group text"),await pe(l,e,0,["font-weight: bolder"]);const g=l.node().getBBox();d=g.height,c=o.insert("g").attr("class","members-group text");let m=0;for(const p of e.members){m+=await pe(c,p,m,[p.parseClassifier()])+a}f=c.node().getBBox().height,f<=0&&(f=i/2),h=o.insert("g").attr("class","methods-group text");let y=0;for(const p of e.methods){y+=await pe(h,p,y,[p.parseClassifier()])+a}let x=o.node().getBBox();if(null!==s){const t=s.node().getBBox();s.attr("transform",`translate(${-t.width/2})`)}return l.attr("transform",`translate(${-g.width/2}, ${u})`),x=o.node().getBBox(),c.attr("transform",`translate(0, ${u+d+2*i})`),x=o.node().getBBox(),h.attr("transform",`translate(0, ${u+d+(f?f+4*i:2*i)})`),x=o.node().getBBox(),{shapeSvg:o,bbox:x}}async function pe(t,e,r,n=[]){const i=t.insert("g").attr("class","label").attr("style",n.join("; ")),c=(0,s.zj)();let h="useHtmlLabels"in e?e.useHtmlLabels:(0,s._3)(c.htmlLabels)??!0,u="";u="text"in e?e.text:e.label,!h&&u.startsWith("\\")&&(u=u.substring(1)),(0,s.Wi)(u)&&(h=!0);const d=await(0,a.GZ)(i,(0,s.oB)((0,o.Sm)(u)),{width:(0,o.Un)(u,c)+50,classes:"markdown-node-label",useHtmlLabels:h},c);let p,f=1;if(h){const t=d.children[0],e=(0,l.Ltv)(d);f=t.innerHTML.split("<br>").length,t.innerHTML.includes("</math>")&&(f+=t.innerHTML.split("<mrow>").length-1);const r=t.getElementsByTagName("img");if(r){const t=""===u.replace(/<img[^>]*>/g,"").trim();await Promise.all([...r].map((e=>new Promise((r=>{function n(){if(e.style.display="flex",e.style.flexDirection="column",t){const t=c.fontSize?.toString()??window.getComputedStyle(document.body).fontSize,r=5,n=parseInt(t,10)*r+"px";e.style.minWidth=n,e.style.maxWidth=n}else e.style.width="100%";r(e)}(0,s.K2)(n,"setupImage"),setTimeout((()=>{e.complete&&n()})),e.addEventListener("error",n),e.addEventListener("load",n)})))))}p=t.getBoundingClientRect(),e.attr("width",p.width),e.attr("height",p.height)}else{n.includes("font-weight: bolder")&&(0,l.Ltv)(d).selectAll("tspan").attr("font-weight",""),f=d.children.length;const t=d.children[0];if(""===d.textContent||d.textContent.includes(">")){t.textContent=u[0]+u.substring(1).replaceAll(">",">").replaceAll("<","<").trim();" "===u[1]&&(t.textContent=t.textContent[0]+" "+t.textContent.substring(1))}"undefined"===t.textContent&&(t.textContent=""),p=d.getBBox()}return i.attr("transform","translate(0,"+(-p.height/(2*f)+r)+")"),p.height}async function fe(t,e){const r=(0,s.D7)(),n=r.class.padding??12,i=n,a=e.useHtmlLabels??(0,s._3)(r.htmlLabels)??!0,o=e;o.annotations=o.annotations??[],o.members=o.members??[],o.methods=o.methods??[];const{shapeSvg:h,bbox:u}=await de(t,e,r,a,i),{labelStyles:p,nodeStyles:f}=S(e);e.labelStyle=p,e.cssStyles=o.styles||"";const g=o.styles?.join(";")||f||"";e.cssStyles||(e.cssStyles=g.replaceAll("!important","").split(";"));const m=0===o.members.length&&0===o.methods.length&&!r.class?.hideEmptyMembersBox,y=c.A.svg(h),x=A(e,{});"handDrawn"!==e.look&&(x.roughness=0,x.fillStyle="solid");const b=u.width;let k=u.height;0===o.members.length&&0===o.methods.length?k+=i:o.members.length>0&&0===o.methods.length&&(k+=2*i);const C=-b/2,w=-k/2,_=y.rectangle(C-n,w-n-(m?n:0===o.members.length&&0===o.methods.length?-n/2:0),b+2*n,k+2*n+(m?2*n:0===o.members.length&&0===o.methods.length?-n:0),x),v=h.insert((()=>_),":first-child");v.attr("class","basic label-container");const T=v.node().getBBox();h.selectAll(".text").each(((t,e,r)=>{const i=(0,l.Ltv)(r[e]),s=i.attr("transform");let c=0;if(s){const t=RegExp(/translate\(([^,]+),([^)]+)\)/).exec(s);t&&(c=parseFloat(t[2]))}let u=c+w+n-(m?n:0===o.members.length&&0===o.methods.length?-n/2:0);a||(u-=4);let d=C;(i.attr("class").includes("label-group")||i.attr("class").includes("annotation-group"))&&(d=-i.node()?.getBBox().width/2||0,h.selectAll("text").each((function(t,e,r){"middle"===window.getComputedStyle(r[e]).textAnchor&&(d=0)}))),i.attr("transform",`translate(${d}, ${u})`)}));const M=h.select(".annotation-group").node().getBBox().height-(m?n/2:0)||0,B=h.select(".label-group").node().getBBox().height-(m?n/2:0)||0,L=h.select(".members-group").node().getBBox().height-(m?n/2:0)||0;if(o.members.length>0||o.methods.length>0||m){const t=y.line(T.x,M+B+w+n,T.x+T.width,M+B+w+n,x);h.insert((()=>t)).attr("class","divider").attr("style",g)}if(m||o.members.length>0||o.methods.length>0){const t=y.line(T.x,M+B+L+w+2*i+n,T.x+T.width,M+B+L+w+n+2*i,x);h.insert((()=>t)).attr("class","divider").attr("style",g)}if("handDrawn"!==o.look&&h.selectAll("path").attr("style",g),v.select(":nth-child(2)").attr("style",g),h.selectAll(".divider").select("path").attr("style",g),e.labelStyle?h.selectAll("span").attr("style",e.labelStyle):h.selectAll("span").attr("style",g),!a){const t=RegExp(/color\s*:\s*([^;]*)/),e=t.exec(g);if(e){const t=e[0].replace("color","fill");h.selectAll("tspan").attr("style",t)}else if(p){const e=t.exec(p);if(e){const t=e[0].replace("color","fill");h.selectAll("tspan").attr("style",t)}}}return d(e,v),e.intersect=function(t){return H.rect(e,t)},h}(0,s.K2)(ae,"tiltedCylinder"),(0,s.K2)(oe,"trapezoid"),(0,s.K2)(se,"trapezoidalPentagon"),(0,s.K2)(le,"triangle"),(0,s.K2)(ce,"waveEdgedRectangle"),(0,s.K2)(he,"waveRectangle"),(0,s.K2)(ue,"windowPane"),(0,s.K2)(de,"textHelper"),(0,s.K2)(pe,"addText"),(0,s.K2)(fe,"classBox");var ge=(0,s.K2)((t=>{switch(t){case"Very High":return"red";case"High":return"orange";case"Medium":return null;case"Low":return"blue";case"Very Low":return"lightblue"}}),"colorFromPriority");async function me(t,e,{config:r}){const{labelStyles:n,nodeStyles:i}=S(e);e.labelStyle=n||"";const a=e.width;e.width=(e.width??200)-10;const{shapeSvg:o,bbox:s,label:l}=await h(t,e,p(e)),f=e.padding||10;let g,m="";"ticket"in e&&e.ticket&&r?.kanban?.ticketBaseUrl&&(m=r?.kanban?.ticketBaseUrl.replace("#TICKET#",e.ticket),g=o.insert("svg:a",":first-child").attr("class","kanban-ticket-link").attr("xlink:href",m).attr("target","_blank"));const y={useHtmlLabels:e.useHtmlLabels,labelStyle:e.labelStyle||"",width:e.width,img:e.img,padding:e.padding||8,centerLabel:!1};let x,b;({label:x,bbox:b}=g?await u(g,"ticket"in e&&e.ticket||"",y):await u(o,"ticket"in e&&e.ticket||"",y));const{label:k,bbox:w}=await u(o,"assigned"in e&&e.assigned||"",y);e.width=a;const _=e?.width||0,v=Math.max(b.height,w.height)/2,T=Math.max(s.height+20,e?.height||0)+v,M=-_/2,B=-T/2;let L;l.attr("transform","translate("+(f-_/2)+", "+(-v-s.height/2)+")"),x.attr("transform","translate("+(f-_/2)+", "+(-v+s.height/2)+")"),k.attr("transform","translate("+(f+_/2-w.width-20)+", "+(-v+s.height/2)+")");const{rx:F,ry:$}=e,{cssStyles:E}=e;if("handDrawn"===e.look){const t=c.A.svg(o),r=A(e,{}),n=F||$?t.path(C(M,B,_,T,F||0),r):t.rectangle(M,B,_,T,r);L=o.insert((()=>n),":first-child"),L.attr("class","basic label-container").attr("style",E||null)}else{L=o.insert("rect",":first-child"),L.attr("class","basic label-container __APA__").attr("style",i).attr("rx",F??5).attr("ry",$??5).attr("x",M).attr("y",B).attr("width",_).attr("height",T);const t="priority"in e&&e.priority;if(t){const e=o.append("line"),r=M+2,n=B+Math.floor((F??0)/2),i=B+T-Math.floor((F??0)/2);e.attr("x1",r).attr("y1",n).attr("x2",r).attr("y2",i).attr("stroke-width","4").attr("stroke",ge(t))}}return d(e,L),e.height=T,e.intersect=function(t){return H.rect(e,t)},o}(0,s.K2)(me,"kanbanItem");var ye=[{semanticName:"Process",name:"Rectangle",shortName:"rect",description:"Standard process shape",aliases:["proc","process","rectangle"],internalAliases:["squareRect"],handler:Yt},{semanticName:"Event",name:"Rounded Rectangle",shortName:"rounded",description:"Represents an event",aliases:["event"],internalAliases:["roundedRect"],handler:Wt},{semanticName:"Terminal Point",name:"Stadium",shortName:"stadium",description:"Terminal point",aliases:["terminal","pill"],handler:Vt},{semanticName:"Subprocess",name:"Framed Rectangle",shortName:"fr-rect",description:"Subprocess",aliases:["subprocess","subproc","framed-rectangle","subroutine"],handler:Qt},{semanticName:"Database",name:"Cylinder",shortName:"cyl",description:"Database storage",aliases:["db","database","cylinder"],handler:ut},{semanticName:"Start",name:"Circle",shortName:"circle",description:"Starting point",aliases:["circ"],handler:Q},{semanticName:"Decision",name:"Diamond",shortName:"diam",description:"Decision-making step",aliases:["decision","diamond","question"],handler:zt},{semanticName:"Prepare Conditional",name:"Hexagon",shortName:"hex",description:"Preparation or condition step",aliases:["hexagon","prepare"],handler:bt},{semanticName:"Data Input/Output",name:"Lean Right",shortName:"lean-r",description:"Represents input or output",aliases:["lean-right","in-out"],internalAliases:["lean_right"],handler:Lt},{semanticName:"Data Input/Output",name:"Lean Left",shortName:"lean-l",description:"Represents output or input",aliases:["lean-left","out-in"],internalAliases:["lean_left"],handler:Bt},{semanticName:"Priority Action",name:"Trapezoid Base Bottom",shortName:"trap-b",description:"Priority action",aliases:["priority","trapezoid-bottom","trapezoid"],handler:oe},{semanticName:"Manual Operation",name:"Trapezoid Base Top",shortName:"trap-t",description:"Represents a manual task",aliases:["manual","trapezoid-top","inv-trapezoid"],internalAliases:["inv_trapezoid"],handler:At},{semanticName:"Stop",name:"Double Circle",shortName:"dbl-circ",description:"Represents a stop point",aliases:["double-circle"],internalAliases:["doublecircle"],handler:pt},{semanticName:"Text Block",name:"Text Block",shortName:"text",description:"Text block",handler:ee},{semanticName:"Card",name:"Notched Rectangle",shortName:"notch-rect",description:"Represents a card",aliases:["card","notched-rectangle"],handler:Z},{semanticName:"Lined/Shaded Process",name:"Lined Rectangle",shortName:"lin-rect",description:"Lined process shape",aliases:["lined-rectangle","lined-process","lin-proc","shaded-process"],handler:Ht},{semanticName:"Start",name:"Small Circle",shortName:"sm-circ",description:"Small starting point",aliases:["start","small-circle"],internalAliases:["stateStart"],handler:Xt},{semanticName:"Stop",name:"Framed Circle",shortName:"fr-circ",description:"Stop point",aliases:["stop","framed-circle"],internalAliases:["stateEnd"],handler:Zt},{semanticName:"Fork/Join",name:"Filled Rectangle",shortName:"fork",description:"Fork or join in process flow",aliases:["join"],internalAliases:["forkJoin"],handler:mt},{semanticName:"Collate",name:"Hourglass",shortName:"hourglass",description:"Represents a collate operation",aliases:["hourglass","collate"],handler:kt},{semanticName:"Comment",name:"Curly Brace",shortName:"brace",description:"Adds a comment",aliases:["comment","brace-l"],handler:rt},{semanticName:"Comment Right",name:"Curly Brace",shortName:"brace-r",description:"Adds a comment",handler:it},{semanticName:"Comment with braces on both sides",name:"Curly Braces",shortName:"braces",description:"Adds a comment",handler:ot},{semanticName:"Com Link",name:"Lightning Bolt",shortName:"bolt",description:"Communication link",aliases:["com-link","lightning-bolt"],handler:Ft},{semanticName:"Document",name:"Document",shortName:"doc",description:"Represents a document",aliases:["doc","document"],handler:ce},{semanticName:"Delay",name:"Half-Rounded Rectangle",shortName:"delay",description:"Represents a delay",aliases:["half-rounded-rectangle"],handler:yt},{semanticName:"Direct Access Storage",name:"Horizontal Cylinder",shortName:"h-cyl",description:"Direct access storage",aliases:["das","horizontal-cylinder"],handler:ae},{semanticName:"Disk Storage",name:"Lined Cylinder",shortName:"lin-cyl",description:"Disk storage",aliases:["disk","lined-cylinder"],handler:Dt},{semanticName:"Display",name:"Curved Trapezoid",shortName:"curv-trap",description:"Represents a display",aliases:["curved-trapezoid","display"],handler:st},{semanticName:"Divided Process",name:"Divided Rectangle",shortName:"div-rect",description:"Divided process shape",aliases:["div-proc","divided-rectangle","divided-process"],handler:dt},{semanticName:"Extract",name:"Triangle",shortName:"tri",description:"Extraction process",aliases:["extract","triangle"],handler:le},{semanticName:"Internal Storage",name:"Window Pane",shortName:"win-pane",description:"Internal storage",aliases:["internal-storage","window-pane"],handler:ue},{semanticName:"Junction",name:"Filled Circle",shortName:"f-circ",description:"Junction point",aliases:["junction","filled-circle"],handler:ft},{semanticName:"Loop Limit",name:"Trapezoidal Pentagon",shortName:"notch-pent",description:"Loop limit step",aliases:["loop-limit","notched-pentagon"],handler:se},{semanticName:"Manual File",name:"Flipped Triangle",shortName:"flip-tri",description:"Manual file operation",aliases:["manual-file","flipped-triangle"],handler:gt},{semanticName:"Manual Input",name:"Sloped Rectangle",shortName:"sl-rect",description:"Manual input step",aliases:["manual-input","sloped-rectangle"],handler:Ut},{semanticName:"Multi-Document",name:"Stacked Document",shortName:"docs",description:"Multiple documents",aliases:["documents","st-doc","stacked-document"],handler:Ot},{semanticName:"Multi-Process",name:"Stacked Rectangle",shortName:"st-rect",description:"Multiple processes",aliases:["procs","processes","stacked-rectangle"],handler:It},{semanticName:"Stored Data",name:"Bow Tie Rectangle",shortName:"bow-rect",description:"Stored data",aliases:["stored-data","bow-tie-rectangle"],handler:V},{semanticName:"Summary",name:"Crossed Circle",shortName:"cross-circ",description:"Summary",aliases:["summary","crossed-circle"],handler:tt},{semanticName:"Tagged Document",name:"Tagged Document",shortName:"tag-doc",description:"Tagged document",aliases:["tag-doc","tagged-document"],handler:te},{semanticName:"Tagged Process",name:"Tagged Rectangle",shortName:"tag-rect",description:"Tagged process",aliases:["tagged-rectangle","tag-proc","tagged-process"],handler:Jt},{semanticName:"Paper Tape",name:"Flag",shortName:"flag",description:"Paper tape",aliases:["paper-tape"],handler:he},{semanticName:"Odd",name:"Odd",shortName:"odd",description:"Odd shape",internalAliases:["rect_left_inv_arrow"],handler:Kt},{semanticName:"Lined Document",name:"Lined Document",shortName:"lin-doc",description:"Lined document",aliases:["lined-document"],handler:jt}],xe=(0,s.K2)((()=>{const t={state:Gt,choice:X,note:Rt,rectWithTitle:qt,labelRect:Mt,iconSquare:vt,iconCircle:wt,icon:Ct,iconRounded:_t,imageSquare:St,anchor:U,kanbanItem:me,classBox:fe},e=[...Object.entries(t),...ye.flatMap((t=>[t.shortName,..."aliases"in t?t.aliases:[],..."internalAliases"in t?t.internalAliases:[]].map((e=>[e,t.handler]))))];return Object.fromEntries(e)}),"generateShapeMap")();function be(t){return t in xe}(0,s.K2)(be,"isValidShape");var ke=new Map;async function Ce(t,e,r){let n,i;"rect"===e.shape&&(e.rx&&e.ry?e.shape="roundedRect":e.shape="squareRect");const a=e.shape?xe[e.shape]:void 0;if(!a)throw new Error(`No such shape: ${e.shape}. Please check your syntax.`);if(e.link){let o;"sandbox"===r.config.securityLevel?o="_top":e.linkTarget&&(o=e.linkTarget||"_blank"),n=t.insert("svg:a").attr("xlink:href",e.link).attr("target",o??null),i=await a(n,e,r)}else i=await a(t,e,r),n=i;return e.tooltip&&i.attr("title",e.tooltip),ke.set(e.id,n),e.haveCallback&&n.attr("class",n.attr("class")+" clickable"),n}(0,s.K2)(Ce,"insertNode");var we=(0,s.K2)(((t,e)=>{ke.set(e.id,t)}),"setNodeElem"),_e=(0,s.K2)((()=>{ke.clear()}),"clear"),ve=(0,s.K2)((t=>{const e=ke.get(t.id);s.Rm.trace("Transforming node",t.diff,t,"translate("+(t.x-t.width/2-5)+", "+t.width/2+")");const r=t.diff||0;return t.clusterNode?e.attr("transform","translate("+(t.x+r-t.width/2)+", "+(t.y-t.height/2-8)+")"):e.attr("transform","translate("+t.x+", "+t.y+")"),r}),"positionNode")},85039:(t,e,r)=>{"use strict";r.d(e,{$C:()=>T,$t:()=>q,C4:()=>H,I5:()=>K,Ib:()=>g,KL:()=>V,Sm:()=>U,Un:()=>D,_K:()=>W,bH:()=>$,dq:()=>P,pe:()=>l,rY:()=>Y,ru:()=>N,sM:()=>S,vU:()=>p,yT:()=>B});var n=r(45567),i=r(16750),a=r(20007),o=r(46632),s=r(42837),l="\u200b",c={curveBasis:a.qrM,curveBasisClosed:a.Yu4,curveBasisOpen:a.IA3,curveBumpX:a.Wi0,curveBumpY:a.PGM,curveBundle:a.OEq,curveCardinalClosed:a.olC,curveCardinalOpen:a.IrU,curveCardinal:a.y8u,curveCatmullRomClosed:a.Q7f,curveCatmullRomOpen:a.cVp,curveCatmullRom:a.oDi,curveLinear:a.lUB,curveLinearClosed:a.Lx9,curveMonotoneX:a.nVG,curveMonotoneY:a.uxU,curveNatural:a.Xf2,curveStep:a.GZz,curveStepAfter:a.UPb,curveStepBefore:a.dyv},h=/\s*(?:(\w+)(?=:):|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,u=(0,n.K2)((function(t,e){const r=d(t,/(?:init\b)|(?:initialize\b)/);let i={};if(Array.isArray(r)){const t=r.map((t=>t.args));(0,n.$i)(t),i=(0,n.hH)(i,[...t])}else i=r.args;if(!i)return;let a=(0,n.Ch)(t,e);const o="config";return void 0!==i[o]&&("flowchart-v2"===a&&(a="flowchart"),i[a]=i[o],delete i[o]),i}),"detectInit"),d=(0,n.K2)((function(t,e=null){try{const r=new RegExp(`[%]{2}(?![{]${h.source})(?=[}][%]{2}).*\n`,"ig");let i;t=t.trim().replace(r,"").replace(/'/gm,'"'),n.Rm.debug(`Detecting diagram directive${null!==e?" type:"+e:""} based on the text:${t}`);const a=[];for(;null!==(i=n.DB.exec(t));)if(i.index===n.DB.lastIndex&&n.DB.lastIndex++,i&&!e||e&&i[1]?.match(e)||e&&i[2]?.match(e)){const t=i[1]?i[1]:i[2],e=i[3]?i[3].trim():i[4]?JSON.parse(i[4].trim()):null;a.push({type:t,args:e})}return 0===a.length?{type:t,args:null}:1===a.length?a[0]:a}catch(r){return n.Rm.error(`ERROR: ${r.message} - Unable to parse directive type: '${e}' based on the text: '${t}'`),{type:void 0,args:null}}}),"detectDirective"),p=(0,n.K2)((function(t){return t.replace(n.DB,"")}),"removeDirectives"),f=(0,n.K2)((function(t,e){for(const[r,n]of e.entries())if(n.match(t))return r;return-1}),"isSubstringInArray");function g(t,e){if(!t)return e;const r=`curve${t.charAt(0).toUpperCase()+t.slice(1)}`;return c[r]??e}function m(t,e){const r=t.trim();if(r)return"loose"!==e.securityLevel?(0,i.J)(r):r}(0,n.K2)(g,"interpolateToCurve"),(0,n.K2)(m,"formatUrl");var y=(0,n.K2)(((t,...e)=>{const r=t.split("."),i=r.length-1,a=r[i];let o=window;for(let s=0;s<i;s++)if(o=o[r[s]],!o)return void n.Rm.error(`Function name: ${t} not found in window`);o[a](...e)}),"runFunc");function x(t,e){return t&&e?Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2)):0}function b(t){let e,r=0;t.forEach((t=>{r+=x(t,e),e=t}));return w(t,r/2)}function k(t){return 1===t.length?t[0]:b(t)}(0,n.K2)(x,"distance"),(0,n.K2)(b,"traverseEdge"),(0,n.K2)(k,"calcLabelPosition");var C=(0,n.K2)(((t,e=2)=>{const r=Math.pow(10,e);return Math.round(t*r)/r}),"roundNumber"),w=(0,n.K2)(((t,e)=>{let r,n=e;for(const i of t){if(r){const t=x(i,r);if(t<n)n-=t;else{const e=n/t;if(e<=0)return r;if(e>=1)return{x:i.x,y:i.y};if(e>0&&e<1)return{x:C((1-e)*r.x+e*i.x,5),y:C((1-e)*r.y+e*i.y,5)}}}r=i}throw new Error("Could not find a suitable point for the given distance")}),"calculatePoint"),_=(0,n.K2)(((t,e,r)=>{n.Rm.info(`our points ${JSON.stringify(e)}`),e[0]!==r&&(e=e.reverse());const i=w(e,25),a=t?10:5,o=Math.atan2(e[0].y-i.y,e[0].x-i.x),s={x:0,y:0};return s.x=Math.sin(o)*a+(e[0].x+i.x)/2,s.y=-Math.cos(o)*a+(e[0].y+i.y)/2,s}),"calcCardinalityPosition");function v(t,e,r){const i=structuredClone(r);n.Rm.info("our points",i),"start_left"!==e&&"start_right"!==e&&i.reverse();const a=w(i,25+t),o=10+.5*t,s=Math.atan2(i[0].y-a.y,i[0].x-a.x),l={x:0,y:0};return"start_left"===e?(l.x=Math.sin(s+Math.PI)*o+(i[0].x+a.x)/2,l.y=-Math.cos(s+Math.PI)*o+(i[0].y+a.y)/2):"end_right"===e?(l.x=Math.sin(s-Math.PI)*o+(i[0].x+a.x)/2-5,l.y=-Math.cos(s-Math.PI)*o+(i[0].y+a.y)/2-5):"end_left"===e?(l.x=Math.sin(s)*o+(i[0].x+a.x)/2-5,l.y=-Math.cos(s)*o+(i[0].y+a.y)/2-5):(l.x=Math.sin(s)*o+(i[0].x+a.x)/2,l.y=-Math.cos(s)*o+(i[0].y+a.y)/2),l}function S(t){let e="",r="";for(const n of t)void 0!==n&&(n.startsWith("color:")||n.startsWith("text-align:")?r=r+n+";":e=e+n+";");return{style:e,labelStyle:r}}(0,n.K2)(v,"calcTerminalLabelPosition"),(0,n.K2)(S,"getStylesFromArray");var A=0,T=(0,n.K2)((()=>(A++,"id-"+Math.random().toString(36).substr(2,12)+"-"+A)),"generateId");function M(t){let e="";const r="0123456789abcdef";for(let n=0;n<t;n++)e+=r.charAt(Math.floor(16*Math.random()));return e}(0,n.K2)(M,"makeRandomHex");var B=(0,n.K2)((t=>M(t.length)),"random"),L=(0,n.K2)((function(){return{x:0,y:0,fill:void 0,anchor:"start",style:"#666",width:100,height:100,textMargin:0,rx:0,ry:0,valign:void 0,text:""}}),"getTextObj"),F=(0,n.K2)((function(t,e){const r=e.text.replace(n.Y2.lineBreakRegex," "),[,i]=K(e.fontSize),a=t.append("text");a.attr("x",e.x),a.attr("y",e.y),a.style("text-anchor",e.anchor),a.style("font-family",e.fontFamily),a.style("font-size",i),a.style("font-weight",e.fontWeight),a.attr("fill",e.fill),void 0!==e.class&&a.attr("class",e.class);const o=a.append("tspan");return o.attr("x",e.x+2*e.textMargin),o.attr("fill",e.fill),o.text(r),a}),"drawSimpleText"),$=(0,o.A)(((t,e,r)=>{if(!t)return t;if(r=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",joinWith:"<br/>"},r),n.Y2.lineBreakRegex.test(t))return t;const i=t.split(" ").filter(Boolean),a=[];let o="";return i.forEach(((t,n)=>{const s=D(`${t} `,r),l=D(o,r);if(s>e){const{hyphenatedStrings:n,remainingWord:i}=E(t,e,"-",r);a.push(o,...n),o=i}else l+s>=e?(a.push(o),o=t):o=[o,t].filter(Boolean).join(" ");n+1===i.length&&a.push(o)})),a.filter((t=>""!==t)).join(r.joinWith)}),((t,e,r)=>`${t}${e}${r.fontSize}${r.fontWeight}${r.fontFamily}${r.joinWith}`)),E=(0,o.A)(((t,e,r="-",n)=>{n=Object.assign({fontSize:12,fontWeight:400,fontFamily:"Arial",margin:0},n);const i=[...t],a=[];let o="";return i.forEach(((t,s)=>{const l=`${o}${t}`;if(D(l,n)>=e){const t=s+1,e=i.length===t,n=`${l}${r}`;a.push(e?l:n),o=""}else o=l})),{hyphenatedStrings:a,remainingWord:o}}),((t,e,r="-",n)=>`${t}${e}${r}${n.fontSize}${n.fontWeight}${n.fontFamily}`));function N(t,e){return I(t,e).height}function D(t,e){return I(t,e).width}(0,n.K2)(N,"calculateTextHeight"),(0,n.K2)(D,"calculateTextWidth");var j,I=(0,o.A)(((t,e)=>{const{fontSize:r=12,fontFamily:i="Arial",fontWeight:o=400}=e;if(!t)return{width:0,height:0};const[,s]=K(r),c=["sans-serif",i],h=t.split(n.Y2.lineBreakRegex),u=[],d=(0,a.Ltv)("body");if(!d.remove)return{width:0,height:0,lineHeight:0};const p=d.append("svg");for(const n of c){let t=0;const e={width:0,height:0,lineHeight:0};for(const r of h){const i=L();i.text=r||l;const a=F(p,i).style("font-size",s).style("font-weight",o).style("font-family",n),c=(a._groups||a)[0][0].getBBox();if(0===c.width&&0===c.height)throw new Error("svg element not in render tree");e.width=Math.round(Math.max(e.width,c.width)),t=Math.round(c.height),e.height+=t,e.lineHeight=Math.round(Math.max(e.lineHeight,t))}u.push(e)}p.remove();return u[isNaN(u[1].height)||isNaN(u[1].width)||isNaN(u[1].lineHeight)||u[0].height>u[1].height&&u[0].width>u[1].width&&u[0].lineHeight>u[1].lineHeight?0:1]}),((t,e)=>`${t}${e.fontSize}${e.fontWeight}${e.fontFamily}`)),O=class{constructor(t=!1,e){this.count=0,this.count=e?e.length:0,this.next=t?()=>this.count++:()=>Date.now()}static{(0,n.K2)(this,"InitIDGenerator")}},R=(0,n.K2)((function(t){return j=j||document.createElement("div"),t=escape(t).replace(/%26/g,"&").replace(/%23/g,"#").replace(/%3B/g,";"),j.innerHTML=t,unescape(j.textContent)}),"entityDecode");function P(t){return"str"in t}(0,n.K2)(P,"isDetailedError");var z=(0,n.K2)(((t,e,r,n)=>{if(!n)return;const i=t.node()?.getBBox();i&&t.append("text").text(n).attr("text-anchor","middle").attr("x",i.x+i.width/2).attr("y",-r).attr("class",e)}),"insertTitle"),K=(0,n.K2)((t=>{if("number"==typeof t)return[t,t+"px"];const e=parseInt(t??"",10);return Number.isNaN(e)?[void 0,void 0]:t===String(e)?[e,t+"px"]:[e,t]}),"parseFontSize");function q(t,e){return(0,s.A)({},t,e)}(0,n.K2)(q,"cleanAndMerge");var W={assignWithDepth:n.hH,wrapLabel:$,calculateTextHeight:N,calculateTextWidth:D,calculateTextDimensions:I,cleanAndMerge:q,detectInit:u,detectDirective:d,isSubstringInArray:f,interpolateToCurve:g,calcLabelPosition:k,calcCardinalityPosition:_,calcTerminalLabelPosition:v,formatUrl:m,getStylesFromArray:S,generateId:T,random:B,runFunc:y,entityDecode:R,insertTitle:z,parseFontSize:K,InitIDGenerator:O},H=(0,n.K2)((function(t){let e=t;return e=e.replace(/style.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/classDef.*:\S*#.*;/g,(function(t){return t.substring(0,t.length-1)})),e=e.replace(/#\w+;/g,(function(t){const e=t.substring(1,t.length-1);return/^\+?\d+$/.test(e)?"\ufb02\xb0\xb0"+e+"\xb6\xdf":"\ufb02\xb0"+e+"\xb6\xdf"})),e}),"encodeEntities"),U=(0,n.K2)((function(t){return t.replace(/\ufb02\xb0\xb0/g,"&#").replace(/\ufb02\xb0/g,"&").replace(/\xb6\xdf/g,";")}),"decodeEntities"),Y=(0,n.K2)(((t,e,{counter:r=0,prefix:n,suffix:i})=>`${n?`${n}_`:""}${t}_${e}_${r}${i?`_${i}`:""}`),"getEdgeId");function V(t){return t??null}(0,n.K2)(V,"handleUndefinedAttr")},45567:(t,e,r)=>{"use strict";r.d(e,{C0:()=>S,VA:()=>y,K2:()=>m,xA:()=>ut,hH:()=>$,Dl:()=>Pt,IU:()=>re,Wt:()=>Xt,Y2:()=>Kt,a$:()=>Ht,sb:()=>J,ME:()=>pe,UI:()=>Z,Ch:()=>T,mW:()=>A,DB:()=>_,_3:()=>Lt,EJ:()=>w,m7:()=>oe,iN:()=>ie,zj:()=>ct,D7:()=>ue,Gs:()=>be,J$:()=>L,ab:()=>le,Q2:()=>st,P$:()=>z,Wi:()=>Rt,H1:()=>yt,Rm:()=>b,QO:()=>Et,Js:()=>xe,Xd:()=>M,VJ:()=>zt,cL:()=>dt,$i:()=>X,jZ:()=>_t,oB:()=>fe,wZ:()=>at,EI:()=>ae,SV:()=>ne,Nk:()=>lt,XV:()=>de,ke:()=>se,He:()=>k,UU:()=>it,ot:()=>Ut,mj:()=>ge,tM:()=>Zt,H$:()=>H,B6:()=>ot});var n=r(74353),i=r(74886),a=r(8232);const o=(t,e)=>{const r=i.A.parse(t),n={};for(const i in e)e[i]&&(n[i]=r[i]+e[i]);return(0,a.A)(t,n)};var s=r(25582);const l=(t,e,r=50)=>{const{r:n,g:a,b:o,a:l}=i.A.parse(t),{r:c,g:h,b:u,a:d}=i.A.parse(e),p=r/100,f=2*p-1,g=l-d,m=((f*g==-1?f:(f+g)/(1+f*g))+1)/2,y=1-m,x=n*m+c*y,b=a*m+h*y,k=o*m+u*y,C=l*p+d*(1-p);return(0,s.A)(x,b,k,C)},c=(t,e=100)=>{const r=i.A.parse(t);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,l(r,t,e)};var h,u=r(75263),d=r(78041),p=r(3219),f=r(42838),g=Object.defineProperty,m=(t,e)=>g(t,"name",{value:e,configurable:!0}),y=(t,e)=>{for(var r in e)g(t,r,{get:e[r],enumerable:!0})},x={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},b={trace:m(((...t)=>{}),"trace"),debug:m(((...t)=>{}),"debug"),info:m(((...t)=>{}),"info"),warn:m(((...t)=>{}),"warn"),error:m(((...t)=>{}),"error"),fatal:m(((...t)=>{}),"fatal")},k=m((function(t="fatal"){let e=x.fatal;"string"==typeof t?t.toLowerCase()in x&&(e=x[t]):"number"==typeof t&&(e=t),b.trace=()=>{},b.debug=()=>{},b.info=()=>{},b.warn=()=>{},b.error=()=>{},b.fatal=()=>{},e<=x.fatal&&(b.fatal=console.error?console.error.bind(console,C("FATAL"),"color: orange"):console.log.bind(console,"\x1b[35m",C("FATAL"))),e<=x.error&&(b.error=console.error?console.error.bind(console,C("ERROR"),"color: orange"):console.log.bind(console,"\x1b[31m",C("ERROR"))),e<=x.warn&&(b.warn=console.warn?console.warn.bind(console,C("WARN"),"color: orange"):console.log.bind(console,"\x1b[33m",C("WARN"))),e<=x.info&&(b.info=console.info?console.info.bind(console,C("INFO"),"color: lightblue"):console.log.bind(console,"\x1b[34m",C("INFO"))),e<=x.debug&&(b.debug=console.debug?console.debug.bind(console,C("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",C("DEBUG"))),e<=x.trace&&(b.trace=console.debug?console.debug.bind(console,C("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1b[32m",C("TRACE")))}),"setLogLevel"),C=m((t=>`%c${n().format("ss.SSS")} : ${t} : `),"format"),w=/^-{3}\s*[\n\r](.*?)[\n\r]-{3}\s*[\n\r]+/s,_=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,v=/\s*%%.*\n/gm,S=class extends Error{static{m(this,"UnknownDiagramError")}constructor(t){super(t),this.name="UnknownDiagramError"}},A={},T=m((function(t,e){t=t.replace(w,"").replace(_,"").replace(v,"\n");for(const[r,{detector:n}]of Object.entries(A)){if(n(t,e))return r}throw new S(`No diagram type detected matching given configuration for text: ${t}`)}),"detectType"),M=m(((...t)=>{for(const{id:e,detector:r,loader:n}of t)B(e,r,n)}),"registerLazyLoadedDiagrams"),B=m(((t,e,r)=>{A[t]&&b.warn(`Detector with key ${t} already exists. Overwriting.`),A[t]={detector:e,loader:r},b.debug(`Detector with key ${t} added${r?" with loader":""}`)}),"addDetector"),L=m((t=>A[t].loader),"getDiagramLoader"),F=m(((t,e,{depth:r=2,clobber:n=!1}={})=>{const i={depth:r,clobber:n};return Array.isArray(e)&&!Array.isArray(t)?(e.forEach((e=>F(t,e,i))),t):Array.isArray(e)&&Array.isArray(t)?(e.forEach((e=>{t.includes(e)||t.push(e)})),t):void 0===t||r<=0?null!=t&&"object"==typeof t&&"object"==typeof e?Object.assign(t,e):e:(void 0!==e&&"object"==typeof t&&"object"==typeof e&&Object.keys(e).forEach((i=>{"object"!=typeof e[i]||void 0!==t[i]&&"object"!=typeof t[i]?(n||"object"!=typeof t[i]&&"object"!=typeof e[i])&&(t[i]=e[i]):(void 0===t[i]&&(t[i]=Array.isArray(e[i])?[]:{}),t[i]=F(t[i],e[i],{depth:r-1,clobber:n}))})),t)}),"assignWithDepth"),$=F,E="#ffffff",N="#f2f2f2",D=m(((t,e)=>o(t,e?{s:-40,l:10}:{s:-40,l:-10})),"mkBorder"),j=class{static{m(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||o(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||o(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||D(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||D(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||D(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||D(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||c(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||c(this.tertiaryColor),this.lineColor=this.lineColor||c(this.background),this.arrowheadColor=this.arrowheadColor||c(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||(0,u.A)(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||c(this.lineColor),this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||(0,d.A)(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.darkMode)for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=(0,u.A)(this["cScale"+e],75);else for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=(0,u.A)(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||c(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this.darkMode?this["cScalePeer"+e]=this["cScalePeer"+e]||(0,d.A)(this["cScale"+e],10):this["cScalePeer"+e]=this["cScalePeer"+e]||(0,u.A)(this["cScale"+e],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;const t=this.darkMode?-4:-1;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||o(this.mainBkg,{h:180,s:-15,l:t*(5+3*e)}),this["surfacePeer"+e]=this["surfacePeer"+e]||o(this.mainBkg,{h:180,s:-15,l:t*(8+3*e)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||o(this.primaryColor,{h:64}),this.fillType3=this.fillType3||o(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||o(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||o(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||o(this.primaryColor,{h:128}),this.fillType7=this.fillType7||o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||o(this.primaryColor,{l:-10}),this.pie5=this.pie5||o(this.secondaryColor,{l:-10}),this.pie6=this.pie6||o(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||o(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.archEdgeColor=this.archEdgeColor||"#777",this.archEdgeArrowColor=this.archEdgeArrowColor||"#777",this.archEdgeWidth=this.archEdgeWidth||"3",this.archGroupBorderColor=this.archGroupBorderColor||"#000",this.archGroupBorderWidth=this.archGroupBorderWidth||"2px",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||E,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||N}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}},I=m((t=>{const e=new j;return e.calculate(t),e}),"getThemeVariables"),O=class{static{m(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=(0,d.A)(this.primaryColor,16),this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=c(this.background),this.secondaryBorderColor=D(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=D(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=(0,d.A)(c("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=(0,s.A)(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.sectionBkgColor=(0,u.A)("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=(0,u.A)(this.sectionBkgColor,10),this.taskBorderColor=(0,s.A)(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=(0,s.A)(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd"}updateColors(){this.secondBkg=(0,d.A)(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=(0,d.A)(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.altSectionBkgColor=this.background,this.taskBkgColor=(0,d.A)(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=this.darkTextColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||c(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScalePeer"+t]=this["cScalePeer"+t]||(0,d.A)(this["cScale"+t],10);for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,s:-30,l:-(4*t-10)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,s:-30,l:-(4*t-7)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.background},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?(0,u.A)(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,d.A)(this.secondaryColor,20),this.git1=(0,d.A)(this.pie2||this.secondaryColor,20),this.git2=(0,d.A)(this.pie3||this.tertiaryColor,20),this.git3=(0,d.A)(this.pie4||o(this.primaryColor,{h:-30}),20),this.git4=(0,d.A)(this.pie5||o(this.primaryColor,{h:-60}),20),this.git5=(0,d.A)(this.pie6||o(this.primaryColor,{h:-90}),10),this.git6=(0,d.A)(this.pie7||o(this.primaryColor,{h:60}),10),this.git7=(0,d.A)(this.pie8||o(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||(0,d.A)(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||(0,d.A)(this.background,2),this.nodeBorder=this.nodeBorder||"#999"}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}},R=m((t=>{const e=new O;return e.calculate(t),e}),"getThemeVariables"),P=class{static{m(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=o(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=D(this.primaryColor,this.darkMode),this.secondaryBorderColor=D(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=D(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.sectionBkgColor=(0,s.A)(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,u.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,u.A)(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=(0,u.A)(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||o(this["cScale"+t],{h:180});for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,l:-(7+5*t)});if(this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,"calculated"!==this.labelTextColor){this.cScaleLabel0=this.cScaleLabel0||c(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||c(this.labelTextColor);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=(0,d.A)(this.border1,23),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||o(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||o(this.primaryColor,{l:-10}),this.pie5=this.pie5||o(this.secondaryColor,{l:-30}),this.pie6=this.pie6||o(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||o(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||(0,u.A)(c(this.git0),25),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||E,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||N}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}},z=m((t=>{const e=new P;return e.calculate(t),e}),"getThemeVariables"),K=class{static{m(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=(0,d.A)("#cde498",10),this.primaryBorderColor=D(this.primaryColor,this.darkMode),this.secondaryBorderColor=D(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=D(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.primaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.actorBorder=(0,u.A)(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||o(this.primaryColor,{h:30}),this.cScale4=this.cScale4||o(this.primaryColor,{h:60}),this.cScale5=this.cScale5||o(this.primaryColor,{h:90}),this.cScale6=this.cScale6||o(this.primaryColor,{h:120}),this.cScale7=this.cScale7||o(this.primaryColor,{h:150}),this.cScale8=this.cScale8||o(this.primaryColor,{h:210}),this.cScale9=this.cScale9||o(this.primaryColor,{h:270}),this.cScale10=this.cScale10||o(this.primaryColor,{h:300}),this.cScale11=this.cScale11||o(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||(0,u.A)(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||(0,u.A)(this.tertiaryColor,40);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=(0,u.A)(this["cScale"+t],10),this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||o(this["cScale"+t],{h:180});this.scaleLabelColor="calculated"!==this.scaleLabelColor&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{h:30,s:-30,l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{h:30,s:-30,l:-(8+5*t)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||o(this.primaryColor,{l:-30}),this.pie5=this.pie5||o(this.secondaryColor,{l:-30}),this.pie6=this.pie6||o(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||o(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||o(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||o(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||o(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||o(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||o(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.mainBkg},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||o(this.primaryColor,{h:-30}),this.git4=this.git4||o(this.primaryColor,{h:-60}),this.git5=this.git5||o(this.primaryColor,{h:-90}),this.git6=this.git6||o(this.primaryColor,{h:60}),this.git7=this.git7||o(this.primaryColor,{h:120}),this.darkMode?(this.git0=(0,d.A)(this.git0,25),this.git1=(0,d.A)(this.git1,25),this.git2=(0,d.A)(this.git2,25),this.git3=(0,d.A)(this.git3,25),this.git4=(0,d.A)(this.git4,25),this.git5=(0,d.A)(this.git5,25),this.git6=(0,d.A)(this.git6,25),this.git7=(0,d.A)(this.git7,25)):(this.git0=(0,u.A)(this.git0,25),this.git1=(0,u.A)(this.git1,25),this.git2=(0,u.A)(this.git2,25),this.git3=(0,u.A)(this.git3,25),this.git4=(0,u.A)(this.git4,25),this.git5=(0,u.A)(this.git5,25),this.git6=(0,u.A)(this.git6,25),this.git7=(0,u.A)(this.git7,25)),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||c(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||c(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||E,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||N}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}},q=m((t=>{const e=new K;return e.calculate(t),e}),"getThemeVariables"),W=class{static{m(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=(0,d.A)(this.contrast,55),this.background="#ffffff",this.tertiaryColor=o(this.primaryColor,{h:-160}),this.primaryBorderColor=D(this.primaryColor,this.darkMode),this.secondaryBorderColor=D(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=D(this.tertiaryColor,this.darkMode),this.primaryTextColor=c(this.primaryColor),this.secondaryTextColor=c(this.secondaryColor),this.tertiaryTextColor=c(this.tertiaryColor),this.lineColor=c(this.background),this.textColor=c(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222"}updateColors(){this.secondBkg=(0,d.A)(this.contrast,55),this.border2=this.contrast,this.actorBorder=(0,d.A)(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||c(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||(0,d.A)(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||(0,u.A)(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||o(this.mainBkg,{l:-(5+5*t)}),this["surfacePeer"+t]=this["surfacePeer"+t]||o(this.mainBkg,{l:-(8+5*t)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=(0,d.A)(this.contrast,30),this.sectionBkgColor2=(0,d.A)(this.contrast,30),this.taskBorderColor=(0,u.A)(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=(0,d.A)(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=(0,u.A)(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=o(this.primaryColor,{h:64}),this.fillType3=o(this.secondaryColor,{h:64}),this.fillType4=o(this.primaryColor,{h:-64}),this.fillType5=o(this.secondaryColor,{h:-64}),this.fillType6=o(this.primaryColor,{h:128}),this.fillType7=o(this.secondaryColor,{h:128});for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["pie"+t]=this["cScale"+t];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||o(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||o(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||o(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||o(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||o(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||o(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||(0,p.A)(this.quadrant1Fill)?(0,d.A)(this.quadrant1Fill):(0,u.A)(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=(0,u.A)(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||o(this.primaryColor,{h:-30}),this.git4=this.pie5||o(this.primaryColor,{h:-60}),this.git5=this.pie6||o(this.primaryColor,{h:-90}),this.git6=this.pie7||o(this.primaryColor,{h:60}),this.git7=this.pie8||o(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||c(this.git0),this.gitInv1=this.gitInv1||c(this.git1),this.gitInv2=this.gitInv2||c(this.git2),this.gitInv3=this.gitInv3||c(this.git3),this.gitInv4=this.gitInv4||c(this.git4),this.gitInv5=this.gitInv5||c(this.git5),this.gitInv6=this.gitInv6||c(this.git6),this.gitInv7=this.gitInv7||c(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||E,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||N}calculate(t){if("object"!=typeof t)return void this.updateColors();const e=Object.keys(t);e.forEach((e=>{this[e]=t[e]})),this.updateColors(),e.forEach((e=>{this[e]=t[e]}))}},H={base:{getThemeVariables:I},dark:{getThemeVariables:R},default:{getThemeVariables:z},forest:{getThemeVariables:q},neutral:{getThemeVariables:m((t=>{const e=new W;return e.calculate(t),e}),"getThemeVariables")}},U={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:!0,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"]},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:""},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1},Y={...U,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF"},themeCSS:void 0,themeVariables:H.default.getThemeVariables(),sequence:{...U.sequence,messageFont:m((function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}),"messageFont"),noteFont:m((function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}}),"noteFont"),actorFont:m((function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}}),"actorFont")},class:{hideEmptyMembersBox:!1},gantt:{...U.gantt,tickInterval:void 0,useWidth:void 0},c4:{...U.c4,useWidth:void 0,personFont:m((function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}}),"personFont"),external_personFont:m((function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}}),"external_personFont"),systemFont:m((function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}}),"systemFont"),external_systemFont:m((function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}}),"external_systemFont"),system_dbFont:m((function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}}),"system_dbFont"),external_system_dbFont:m((function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}}),"external_system_dbFont"),system_queueFont:m((function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}}),"system_queueFont"),external_system_queueFont:m((function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}}),"external_system_queueFont"),containerFont:m((function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}}),"containerFont"),external_containerFont:m((function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}}),"external_containerFont"),container_dbFont:m((function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}}),"container_dbFont"),external_container_dbFont:m((function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}}),"external_container_dbFont"),container_queueFont:m((function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}}),"container_queueFont"),external_container_queueFont:m((function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}}),"external_container_queueFont"),componentFont:m((function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}}),"componentFont"),external_componentFont:m((function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}}),"external_componentFont"),component_dbFont:m((function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}}),"component_dbFont"),external_component_dbFont:m((function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}}),"external_component_dbFont"),component_queueFont:m((function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}}),"component_queueFont"),external_component_queueFont:m((function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}}),"external_component_queueFont"),boundaryFont:m((function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}}),"boundaryFont"),messageFont:m((function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}}),"messageFont")},pie:{...U.pie,useWidth:984},xyChart:{...U.xyChart,useWidth:void 0},requirement:{...U.requirement,useWidth:void 0},packet:{...U.packet}},V=m(((t,e="")=>Object.keys(t).reduce(((r,n)=>Array.isArray(t[n])?r:"object"==typeof t[n]&&null!==t[n]?[...r,e+n,...V(t[n],"")]:[...r,e+n]),[])),"keyify"),G=new Set(V(Y,"")),Z=Y,X=m((t=>{if(b.debug("sanitizeDirective called with",t),"object"==typeof t&&null!=t)if(Array.isArray(t))t.forEach((t=>X(t)));else{for(const e of Object.keys(t)){if(b.debug("Checking key",e),e.startsWith("__")||e.includes("proto")||e.includes("constr")||!G.has(e)||null==t[e]){b.debug("sanitize deleting key: ",e),delete t[e];continue}if("object"==typeof t[e]){b.debug("sanitizing object",e),X(t[e]);continue}const r=["themeCSS","fontFamily","altFontFamily"];for(const n of r)e.includes(n)&&(b.debug("sanitizing css option",e),t[e]=Q(t[e]))}if(t.themeVariables)for(const e of Object.keys(t.themeVariables)){const r=t.themeVariables[e];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(t.themeVariables[e]="")}b.debug("After sanitization",t)}}),"sanitizeDirective"),Q=m((t=>{let e=0,r=0;for(const n of t){if(e<r)return"{ /* ERROR: Unbalanced CSS */ }";"{"===n?e++:"}"===n&&r++}return e!==r?"{ /* ERROR: Unbalanced CSS */ }":t}),"sanitizeCss"),J=Object.freeze(Z),tt=$({},J),et=[],rt=$({},J),nt=m(((t,e)=>{let r=$({},t),n={};for(const i of e)ht(i),n=$(n,i);if(r=$(r,n),n.theme&&n.theme in H){const t=$({},h),e=$(t.themeVariables||{},n.themeVariables);r.theme&&r.theme in H&&(r.themeVariables=H[r.theme].getThemeVariables(e))}return mt(rt=r),rt}),"updateCurrentConfig"),it=m((t=>(tt=$({},J),tt=$(tt,t),t.theme&&H[t.theme]&&(tt.themeVariables=H[t.theme].getThemeVariables(t.themeVariables)),nt(tt,et),tt)),"setSiteConfig"),at=m((t=>{h=$({},t)}),"saveConfigFromInitialize"),ot=m((t=>(tt=$(tt,t),nt(tt,et),tt)),"updateSiteConfig"),st=m((()=>$({},tt)),"getSiteConfig"),lt=m((t=>(mt(t),$(rt,t),ct())),"setConfig"),ct=m((()=>$({},rt)),"getConfig"),ht=m((t=>{t&&(["secure",...tt.secure??[]].forEach((e=>{Object.hasOwn(t,e)&&(b.debug(`Denied attempt to modify a secure key ${e}`,t[e]),delete t[e])})),Object.keys(t).forEach((e=>{e.startsWith("__")&&delete t[e]})),Object.keys(t).forEach((e=>{"string"==typeof t[e]&&(t[e].includes("<")||t[e].includes(">")||t[e].includes("url(data:"))&&delete t[e],"object"==typeof t[e]&&ht(t[e])})))}),"sanitize"),ut=m((t=>{X(t),t.fontFamily&&!t.themeVariables?.fontFamily&&(t.themeVariables={...t.themeVariables,fontFamily:t.fontFamily}),et.push(t),nt(tt,et)}),"addDirective"),dt=m(((t=tt)=>{nt(t,et=[])}),"reset"),pt={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead."},ft={},gt=m((t=>{ft[t]||(b.warn(pt[t]),ft[t]=!0)}),"issueWarning"),mt=m((t=>{t&&(t.lazyLoadedDiagrams||t.loadExternalDiagramsAtStartup)&>("LAZY_LOAD_DEPRECATED")}),"checkConfig"),yt=/<br\s*\/?>/gi,xt=m((t=>{if(!t)return[""];return Mt(t).replace(/\\n/g,"#br#").split("#br#")}),"getRows"),bt=(()=>{let t=!1;return()=>{t||(kt(),t=!0)}})();function kt(){const t="data-temp-href-target";f.addHook("beforeSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute("target")&&e.setAttribute(t,e.getAttribute("target")??"")})),f.addHook("afterSanitizeAttributes",(e=>{"A"===e.tagName&&e.hasAttribute(t)&&(e.setAttribute("target",e.getAttribute(t)??""),e.removeAttribute(t),"_blank"===e.getAttribute("target")&&e.setAttribute("rel","noopener"))}))}m(kt,"setupDompurifyHooks");var Ct=m((t=>{bt();return f.sanitize(t)}),"removeScript"),wt=m(((t,e)=>{if(!1!==e.flowchart?.htmlLabels){const r=e.securityLevel;"antiscript"===r||"strict"===r?t=Ct(t):"loose"!==r&&(t=(t=(t=Mt(t)).replace(/</g,"<").replace(/>/g,">")).replace(/=/g,"="),t=Tt(t))}return t}),"sanitizeMore"),_t=m(((t,e)=>t?t=e.dompurifyConfig?f.sanitize(wt(t,e),e.dompurifyConfig).toString():f.sanitize(wt(t,e),{FORBID_TAGS:["style"]}).toString():t),"sanitizeText"),vt=m(((t,e)=>"string"==typeof t?_t(t,e):t.flat().map((t=>_t(t,e)))),"sanitizeTextOrArray"),St=m((t=>yt.test(t)),"hasBreaks"),At=m((t=>t.split(yt)),"splitBreaks"),Tt=m((t=>t.replace(/#br#/g,"<br/>")),"placeholderToBreak"),Mt=m((t=>t.replace(yt,"#br#")),"breakToPlaceholder"),Bt=m((t=>{let e="";return t&&(e=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,e=e.replaceAll(/\(/g,"\\("),e=e.replaceAll(/\)/g,"\\)")),e}),"getUrl"),Lt=m((t=>!1!==t&&!["false","null","0"].includes(String(t).trim().toLowerCase())),"evaluate"),Ft=m((function(...t){const e=t.filter((t=>!isNaN(t)));return Math.max(...e)}),"getMax"),$t=m((function(...t){const e=t.filter((t=>!isNaN(t)));return Math.min(...e)}),"getMin"),Et=m((function(t){const e=t.split(/(,)/),r=[];for(let n=0;n<e.length;n++){let t=e[n];if(","===t&&n>0&&n+1<e.length){const i=e[n-1],a=e[n+1];Dt(i,a)&&(t=i+","+a,n++,r.pop())}r.push(jt(t))}return r.join("")}),"parseGenericTypes"),Nt=m(((t,e)=>Math.max(0,t.split(e).length-1)),"countOccurrence"),Dt=m(((t,e)=>{const r=Nt(t,"~"),n=Nt(e,"~");return 1===r&&1===n}),"shouldCombineSets"),jt=m((t=>{const e=Nt(t,"~");let r=!1;if(e<=1)return t;e%2!=0&&t.startsWith("~")&&(t=t.substring(1),r=!0);const n=[...t];let i=n.indexOf("~"),a=n.lastIndexOf("~");for(;-1!==i&&-1!==a&&i!==a;)n[i]="<",n[a]=">",i=n.indexOf("~"),a=n.lastIndexOf("~");return r&&n.unshift("~"),n.join("")}),"processSet"),It=m((()=>void 0!==window.MathMLElement),"isMathMLSupported"),Ot=/\$\$(.*)\$\$/g,Rt=m((t=>(t.match(Ot)?.length??0)>0),"hasKatex"),Pt=m((async(t,e)=>{t=await zt(t,e);const r=document.createElement("div");r.innerHTML=t,r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0";const n=document.querySelector("body");n?.insertAdjacentElement("beforeend",r);const i={width:r.clientWidth,height:r.clientHeight};return r.remove(),i}),"calculateMathMLDimensions"),zt=m((async(t,e)=>{if(!Rt(t))return t;if(!(It()||e.legacyMathML||e.forceLegacyMathML))return t.replace(Ot,"MathML is unsupported in this environment.");const{default:n}=await r.e(2130).then(r.bind(r,22130)),i=e.forceLegacyMathML||!It()&&e.legacyMathML?"htmlAndMathml":"mathml";return t.split(yt).map((t=>Rt(t)?`<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${t}</div>`:`<div>${t}</div>`)).join("").replace(Ot,((t,e)=>n.renderToString(e,{throwOnError:!0,displayMode:!0,output:i}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,"")))}),"renderKatex"),Kt={getRows:xt,sanitizeText:_t,sanitizeTextOrArray:vt,hasBreaks:St,splitBreaks:At,lineBreakRegex:yt,removeScript:Ct,getUrl:Bt,evaluate:Lt,getMax:Ft,getMin:$t},qt=m((function(t,e){for(let r of e)t.attr(r[0],r[1])}),"d3Attrs"),Wt=m((function(t,e,r){let n=new Map;return r?(n.set("width","100%"),n.set("style",`max-width: ${e}px;`)):(n.set("height",t),n.set("width",e)),n}),"calculateSvgSizeAttrs"),Ht=m((function(t,e,r,n){const i=Wt(e,r,n);qt(t,i)}),"configureSvgSize"),Ut=m((function(t,e,r,n){const i=e.node().getBBox(),a=i.width,o=i.height;b.info(`SVG bounds: ${a}x${o}`,i);let s=0,l=0;b.info(`Graph bounds: ${s}x${l}`,t),s=a+2*r,l=o+2*r,b.info(`Calculated bounds: ${s}x${l}`),Ht(e,l,s,n);const c=`${i.x-r} ${i.y-r} ${i.width+2*r} ${i.height+2*r}`;e.attr("viewBox",c)}),"setupGraphViewbox"),Yt={},Vt=m(((t,e,r)=>{let n="";return t in Yt&&Yt[t]?n=Yt[t](r):b.warn(`No theme found for ${t}`),` & {\n font-family: ${r.fontFamily};\n font-size: ${r.fontSize};\n fill: ${r.textColor}\n }\n\n /* Classes common for multiple diagrams */\n\n & .error-icon {\n fill: ${r.errorBkgColor};\n }\n & .error-text {\n fill: ${r.errorTextColor};\n stroke: ${r.errorTextColor};\n }\n\n & .edge-thickness-normal {\n stroke-width: 1px;\n }\n & .edge-thickness-thick {\n stroke-width: 3.5px\n }\n & .edge-pattern-solid {\n stroke-dasharray: 0;\n }\n & .edge-thickness-invisible {\n stroke-width: 0;\n fill: none;\n }\n & .edge-pattern-dashed{\n stroke-dasharray: 3;\n }\n .edge-pattern-dotted {\n stroke-dasharray: 2;\n }\n\n & .marker {\n fill: ${r.lineColor};\n stroke: ${r.lineColor};\n }\n & .marker.cross {\n stroke: ${r.lineColor};\n }\n\n & svg {\n font-family: ${r.fontFamily};\n font-size: ${r.fontSize};\n }\n & p {\n margin: 0\n }\n\n ${n}\n\n ${e}\n`}),"getStyles"),Gt=m(((t,e)=>{void 0!==e&&(Yt[t]=e)}),"addStylesForDiagram"),Zt=Vt,Xt={};y(Xt,{clear:()=>re,getAccDescription:()=>oe,getAccTitle:()=>ie,getDiagramTitle:()=>le,setAccDescription:()=>ae,setAccTitle:()=>ne,setDiagramTitle:()=>se});var Qt="",Jt="",te="",ee=m((t=>_t(t,ct())),"sanitizeText"),re=m((()=>{Qt="",te="",Jt=""}),"clear"),ne=m((t=>{Qt=ee(t).replace(/^\s+/g,"")}),"setAccTitle"),ie=m((()=>Qt),"getAccTitle"),ae=m((t=>{te=ee(t).replace(/\n\s+/g,"\n")}),"setAccDescription"),oe=m((()=>te),"getAccDescription"),se=m((t=>{Jt=ee(t)}),"setDiagramTitle"),le=m((()=>Jt),"getDiagramTitle"),ce=b,he=k,ue=ct,de=lt,pe=J,fe=m((t=>_t(t,ue())),"sanitizeText"),ge=Ut,me=m((()=>Xt),"getCommonDb"),ye={},xe=m(((t,e,r)=>{ye[t]&&ce.warn(`Diagram with id ${t} already registered. Overwriting.`),ye[t]=e,r&&B(t,r),Gt(t,e.styles),e.injectUtils?.(ce,he,ue,fe,ge,me(),(()=>{}))}),"registerDiagram"),be=m((t=>{if(t in ye)return ye[t];throw new ke(t)}),"getDiagram"),ke=class extends Error{static{m(this,"DiagramNotFoundError")}constructor(t){super(`Diagram ${t} not found.`)}}},79515:(t,e,r)=>{"use strict";r.d(e,{H:()=>Pr,r:()=>Rr});var n=r(45567);function i(t){return null==t}function a(t){return"object"==typeof t&&null!==t}function o(t){return Array.isArray(t)?t:i(t)?[]:[t]}function s(t,e){var r,n,i,a;if(e)for(r=0,n=(a=Object.keys(e)).length;r<n;r+=1)t[i=a[r]]=e[i];return t}function l(t,e){var r,n="";for(r=0;r<e;r+=1)n+=t;return n}function c(t){return 0===t&&Number.NEGATIVE_INFINITY===1/t}(0,n.K2)(i,"isNothing"),(0,n.K2)(a,"isObject"),(0,n.K2)(o,"toArray"),(0,n.K2)(s,"extend"),(0,n.K2)(l,"repeat"),(0,n.K2)(c,"isNegativeZero");var h={isNothing:i,isObject:a,toArray:o,repeat:l,isNegativeZero:c,extend:s};function u(t,e){var r="",n=t.reason||"(unknown reason)";return t.mark?(t.mark.name&&(r+='in "'+t.mark.name+'" '),r+="("+(t.mark.line+1)+":"+(t.mark.column+1)+")",!e&&t.mark.snippet&&(r+="\n\n"+t.mark.snippet),n+" "+r):n}function d(t,e){Error.call(this),this.name="YAMLException",this.reason=t,this.mark=e,this.message=u(this,!1),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack||""}(0,n.K2)(u,"formatError"),(0,n.K2)(d,"YAMLException$1"),d.prototype=Object.create(Error.prototype),d.prototype.constructor=d,d.prototype.toString=(0,n.K2)((function(t){return this.name+": "+u(this,t)}),"toString");var p=d;function f(t,e,r,n,i){var a="",o="",s=Math.floor(i/2)-1;return n-e>s&&(e=n-s+(a=" ... ").length),r-n>s&&(r=n+s-(o=" ...").length),{str:a+t.slice(e,r).replace(/\t/g,"\u2192")+o,pos:n-e+a.length}}function g(t,e){return h.repeat(" ",e-t.length)+t}function m(t,e){if(e=Object.create(e||null),!t.buffer)return null;e.maxLength||(e.maxLength=79),"number"!=typeof e.indent&&(e.indent=1),"number"!=typeof e.linesBefore&&(e.linesBefore=3),"number"!=typeof e.linesAfter&&(e.linesAfter=2);for(var r,n=/\r?\n|\r|\0/g,i=[0],a=[],o=-1;r=n.exec(t.buffer);)a.push(r.index),i.push(r.index+r[0].length),t.position<=r.index&&o<0&&(o=i.length-2);o<0&&(o=i.length-1);var s,l,c="",u=Math.min(t.line+e.linesAfter,a.length).toString().length,d=e.maxLength-(e.indent+u+3);for(s=1;s<=e.linesBefore&&!(o-s<0);s++)l=f(t.buffer,i[o-s],a[o-s],t.position-(i[o]-i[o-s]),d),c=h.repeat(" ",e.indent)+g((t.line-s+1).toString(),u)+" | "+l.str+"\n"+c;for(l=f(t.buffer,i[o],a[o],t.position,d),c+=h.repeat(" ",e.indent)+g((t.line+1).toString(),u)+" | "+l.str+"\n",c+=h.repeat("-",e.indent+u+3+l.pos)+"^\n",s=1;s<=e.linesAfter&&!(o+s>=a.length);s++)l=f(t.buffer,i[o+s],a[o+s],t.position-(i[o]-i[o+s]),d),c+=h.repeat(" ",e.indent)+g((t.line+s+1).toString(),u)+" | "+l.str+"\n";return c.replace(/\n$/,"")}(0,n.K2)(f,"getLine"),(0,n.K2)(g,"padStart"),(0,n.K2)(m,"makeSnippet");var y=m,x=["kind","multi","resolve","construct","instanceOf","predicate","represent","representName","defaultStyle","styleAliases"],b=["scalar","sequence","mapping"];function k(t){var e={};return null!==t&&Object.keys(t).forEach((function(r){t[r].forEach((function(t){e[String(t)]=r}))})),e}function C(t,e){if(e=e||{},Object.keys(e).forEach((function(e){if(-1===x.indexOf(e))throw new p('Unknown option "'+e+'" is met in definition of "'+t+'" YAML type.')})),this.options=e,this.tag=t,this.kind=e.kind||null,this.resolve=e.resolve||function(){return!0},this.construct=e.construct||function(t){return t},this.instanceOf=e.instanceOf||null,this.predicate=e.predicate||null,this.represent=e.represent||null,this.representName=e.representName||null,this.defaultStyle=e.defaultStyle||null,this.multi=e.multi||!1,this.styleAliases=k(e.styleAliases||null),-1===b.indexOf(this.kind))throw new p('Unknown kind "'+this.kind+'" is specified for "'+t+'" YAML type.')}(0,n.K2)(k,"compileStyleAliases"),(0,n.K2)(C,"Type$1");var w=C;function _(t,e){var r=[];return t[e].forEach((function(t){var e=r.length;r.forEach((function(r,n){r.tag===t.tag&&r.kind===t.kind&&r.multi===t.multi&&(e=n)})),r[e]=t})),r}function v(){var t,e,r={scalar:{},sequence:{},mapping:{},fallback:{},multi:{scalar:[],sequence:[],mapping:[],fallback:[]}};function i(t){t.multi?(r.multi[t.kind].push(t),r.multi.fallback.push(t)):r[t.kind][t.tag]=r.fallback[t.tag]=t}for((0,n.K2)(i,"collectType"),t=0,e=arguments.length;t<e;t+=1)arguments[t].forEach(i);return r}function S(t){return this.extend(t)}(0,n.K2)(_,"compileList"),(0,n.K2)(v,"compileMap"),(0,n.K2)(S,"Schema$1"),S.prototype.extend=(0,n.K2)((function(t){var e=[],r=[];if(t instanceof w)r.push(t);else if(Array.isArray(t))r=r.concat(t);else{if(!t||!Array.isArray(t.implicit)&&!Array.isArray(t.explicit))throw new p("Schema.extend argument should be a Type, [ Type ], or a schema definition ({ implicit: [...], explicit: [...] })");t.implicit&&(e=e.concat(t.implicit)),t.explicit&&(r=r.concat(t.explicit))}e.forEach((function(t){if(!(t instanceof w))throw new p("Specified list of YAML types (or a single Type object) contains a non-Type object.");if(t.loadKind&&"scalar"!==t.loadKind)throw new p("There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.");if(t.multi)throw new p("There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.")})),r.forEach((function(t){if(!(t instanceof w))throw new p("Specified list of YAML types (or a single Type object) contains a non-Type object.")}));var n=Object.create(S.prototype);return n.implicit=(this.implicit||[]).concat(e),n.explicit=(this.explicit||[]).concat(r),n.compiledImplicit=_(n,"implicit"),n.compiledExplicit=_(n,"explicit"),n.compiledTypeMap=v(n.compiledImplicit,n.compiledExplicit),n}),"extend");var A=new S({explicit:[new w("tag:yaml.org,2002:str",{kind:"scalar",construct:(0,n.K2)((function(t){return null!==t?t:""}),"construct")}),new w("tag:yaml.org,2002:seq",{kind:"sequence",construct:(0,n.K2)((function(t){return null!==t?t:[]}),"construct")}),new w("tag:yaml.org,2002:map",{kind:"mapping",construct:(0,n.K2)((function(t){return null!==t?t:{}}),"construct")})]});function T(t){if(null===t)return!0;var e=t.length;return 1===e&&"~"===t||4===e&&("null"===t||"Null"===t||"NULL"===t)}function M(){return null}function B(t){return null===t}(0,n.K2)(T,"resolveYamlNull"),(0,n.K2)(M,"constructYamlNull"),(0,n.K2)(B,"isNull");var L=new w("tag:yaml.org,2002:null",{kind:"scalar",resolve:T,construct:M,predicate:B,represent:{canonical:(0,n.K2)((function(){return"~"}),"canonical"),lowercase:(0,n.K2)((function(){return"null"}),"lowercase"),uppercase:(0,n.K2)((function(){return"NULL"}),"uppercase"),camelcase:(0,n.K2)((function(){return"Null"}),"camelcase"),empty:(0,n.K2)((function(){return""}),"empty")},defaultStyle:"lowercase"});function F(t){if(null===t)return!1;var e=t.length;return 4===e&&("true"===t||"True"===t||"TRUE"===t)||5===e&&("false"===t||"False"===t||"FALSE"===t)}function $(t){return"true"===t||"True"===t||"TRUE"===t}function E(t){return"[object Boolean]"===Object.prototype.toString.call(t)}(0,n.K2)(F,"resolveYamlBoolean"),(0,n.K2)($,"constructYamlBoolean"),(0,n.K2)(E,"isBoolean");var N=new w("tag:yaml.org,2002:bool",{kind:"scalar",resolve:F,construct:$,predicate:E,represent:{lowercase:(0,n.K2)((function(t){return t?"true":"false"}),"lowercase"),uppercase:(0,n.K2)((function(t){return t?"TRUE":"FALSE"}),"uppercase"),camelcase:(0,n.K2)((function(t){return t?"True":"False"}),"camelcase")},defaultStyle:"lowercase"});function D(t){return 48<=t&&t<=57||65<=t&&t<=70||97<=t&&t<=102}function j(t){return 48<=t&&t<=55}function I(t){return 48<=t&&t<=57}function O(t){if(null===t)return!1;var e,r=t.length,n=0,i=!1;if(!r)return!1;if("-"!==(e=t[n])&&"+"!==e||(e=t[++n]),"0"===e){if(n+1===r)return!0;if("b"===(e=t[++n])){for(n++;n<r;n++)if("_"!==(e=t[n])){if("0"!==e&&"1"!==e)return!1;i=!0}return i&&"_"!==e}if("x"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!D(t.charCodeAt(n)))return!1;i=!0}return i&&"_"!==e}if("o"===e){for(n++;n<r;n++)if("_"!==(e=t[n])){if(!j(t.charCodeAt(n)))return!1;i=!0}return i&&"_"!==e}}if("_"===e)return!1;for(;n<r;n++)if("_"!==(e=t[n])){if(!I(t.charCodeAt(n)))return!1;i=!0}return!(!i||"_"===e)}function R(t){var e,r=t,n=1;if(-1!==r.indexOf("_")&&(r=r.replace(/_/g,"")),"-"!==(e=r[0])&&"+"!==e||("-"===e&&(n=-1),e=(r=r.slice(1))[0]),"0"===r)return 0;if("0"===e){if("b"===r[1])return n*parseInt(r.slice(2),2);if("x"===r[1])return n*parseInt(r.slice(2),16);if("o"===r[1])return n*parseInt(r.slice(2),8)}return n*parseInt(r,10)}function P(t){return"[object Number]"===Object.prototype.toString.call(t)&&t%1==0&&!h.isNegativeZero(t)}(0,n.K2)(D,"isHexCode"),(0,n.K2)(j,"isOctCode"),(0,n.K2)(I,"isDecCode"),(0,n.K2)(O,"resolveYamlInteger"),(0,n.K2)(R,"constructYamlInteger"),(0,n.K2)(P,"isInteger");var z=new w("tag:yaml.org,2002:int",{kind:"scalar",resolve:O,construct:R,predicate:P,represent:{binary:(0,n.K2)((function(t){return t>=0?"0b"+t.toString(2):"-0b"+t.toString(2).slice(1)}),"binary"),octal:(0,n.K2)((function(t){return t>=0?"0o"+t.toString(8):"-0o"+t.toString(8).slice(1)}),"octal"),decimal:(0,n.K2)((function(t){return t.toString(10)}),"decimal"),hexadecimal:(0,n.K2)((function(t){return t>=0?"0x"+t.toString(16).toUpperCase():"-0x"+t.toString(16).toUpperCase().slice(1)}),"hexadecimal")},defaultStyle:"decimal",styleAliases:{binary:[2,"bin"],octal:[8,"oct"],decimal:[10,"dec"],hexadecimal:[16,"hex"]}}),K=new RegExp("^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?|[-+]?\\.(?:inf|Inf|INF)|\\.(?:nan|NaN|NAN))$");function q(t){return null!==t&&!(!K.test(t)||"_"===t[t.length-1])}function W(t){var e,r;return r="-"===(e=t.replace(/_/g,"").toLowerCase())[0]?-1:1,"+-".indexOf(e[0])>=0&&(e=e.slice(1)),".inf"===e?1===r?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:".nan"===e?NaN:r*parseFloat(e,10)}(0,n.K2)(q,"resolveYamlFloat"),(0,n.K2)(W,"constructYamlFloat");var H=/^[-+]?[0-9]+e/;function U(t,e){var r;if(isNaN(t))switch(e){case"lowercase":return".nan";case"uppercase":return".NAN";case"camelcase":return".NaN"}else if(Number.POSITIVE_INFINITY===t)switch(e){case"lowercase":return".inf";case"uppercase":return".INF";case"camelcase":return".Inf"}else if(Number.NEGATIVE_INFINITY===t)switch(e){case"lowercase":return"-.inf";case"uppercase":return"-.INF";case"camelcase":return"-.Inf"}else if(h.isNegativeZero(t))return"-0.0";return r=t.toString(10),H.test(r)?r.replace("e",".e"):r}function Y(t){return"[object Number]"===Object.prototype.toString.call(t)&&(t%1!=0||h.isNegativeZero(t))}(0,n.K2)(U,"representYamlFloat"),(0,n.K2)(Y,"isFloat");var V=new w("tag:yaml.org,2002:float",{kind:"scalar",resolve:q,construct:W,predicate:Y,represent:U,defaultStyle:"lowercase"}),G=A.extend({implicit:[L,N,z,V]}),Z=G,X=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$"),Q=new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");function J(t){return null!==t&&(null!==X.exec(t)||null!==Q.exec(t))}function tt(t){var e,r,n,i,a,o,s,l,c=0,h=null;if(null===(e=X.exec(t))&&(e=Q.exec(t)),null===e)throw new Error("Date resolve error");if(r=+e[1],n=+e[2]-1,i=+e[3],!e[4])return new Date(Date.UTC(r,n,i));if(a=+e[4],o=+e[5],s=+e[6],e[7]){for(c=e[7].slice(0,3);c.length<3;)c+="0";c=+c}return e[9]&&(h=6e4*(60*+e[10]+ +(e[11]||0)),"-"===e[9]&&(h=-h)),l=new Date(Date.UTC(r,n,i,a,o,s,c)),h&&l.setTime(l.getTime()-h),l}function et(t){return t.toISOString()}(0,n.K2)(J,"resolveYamlTimestamp"),(0,n.K2)(tt,"constructYamlTimestamp"),(0,n.K2)(et,"representYamlTimestamp");var rt=new w("tag:yaml.org,2002:timestamp",{kind:"scalar",resolve:J,construct:tt,instanceOf:Date,represent:et});function nt(t){return"<<"===t||null===t}(0,n.K2)(nt,"resolveYamlMerge");var it=new w("tag:yaml.org,2002:merge",{kind:"scalar",resolve:nt}),at="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r";function ot(t){if(null===t)return!1;var e,r,n=0,i=t.length,a=at;for(r=0;r<i;r++)if(!((e=a.indexOf(t.charAt(r)))>64)){if(e<0)return!1;n+=6}return n%8==0}function st(t){var e,r,n=t.replace(/[\r\n=]/g,""),i=n.length,a=at,o=0,s=[];for(e=0;e<i;e++)e%4==0&&e&&(s.push(o>>16&255),s.push(o>>8&255),s.push(255&o)),o=o<<6|a.indexOf(n.charAt(e));return 0===(r=i%4*6)?(s.push(o>>16&255),s.push(o>>8&255),s.push(255&o)):18===r?(s.push(o>>10&255),s.push(o>>2&255)):12===r&&s.push(o>>4&255),new Uint8Array(s)}function lt(t){var e,r,n="",i=0,a=t.length,o=at;for(e=0;e<a;e++)e%3==0&&e&&(n+=o[i>>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[63&i]),i=(i<<8)+t[e];return 0===(r=a%3)?(n+=o[i>>18&63],n+=o[i>>12&63],n+=o[i>>6&63],n+=o[63&i]):2===r?(n+=o[i>>10&63],n+=o[i>>4&63],n+=o[i<<2&63],n+=o[64]):1===r&&(n+=o[i>>2&63],n+=o[i<<4&63],n+=o[64],n+=o[64]),n}function ct(t){return"[object Uint8Array]"===Object.prototype.toString.call(t)}(0,n.K2)(ot,"resolveYamlBinary"),(0,n.K2)(st,"constructYamlBinary"),(0,n.K2)(lt,"representYamlBinary"),(0,n.K2)(ct,"isBinary");var ht=new w("tag:yaml.org,2002:binary",{kind:"scalar",resolve:ot,construct:st,predicate:ct,represent:lt}),ut=Object.prototype.hasOwnProperty,dt=Object.prototype.toString;function pt(t){if(null===t)return!0;var e,r,n,i,a,o=[],s=t;for(e=0,r=s.length;e<r;e+=1){if(n=s[e],a=!1,"[object Object]"!==dt.call(n))return!1;for(i in n)if(ut.call(n,i)){if(a)return!1;a=!0}if(!a)return!1;if(-1!==o.indexOf(i))return!1;o.push(i)}return!0}function ft(t){return null!==t?t:[]}(0,n.K2)(pt,"resolveYamlOmap"),(0,n.K2)(ft,"constructYamlOmap");var gt=new w("tag:yaml.org,2002:omap",{kind:"sequence",resolve:pt,construct:ft}),mt=Object.prototype.toString;function yt(t){if(null===t)return!0;var e,r,n,i,a,o=t;for(a=new Array(o.length),e=0,r=o.length;e<r;e+=1){if(n=o[e],"[object Object]"!==mt.call(n))return!1;if(1!==(i=Object.keys(n)).length)return!1;a[e]=[i[0],n[i[0]]]}return!0}function xt(t){if(null===t)return[];var e,r,n,i,a,o=t;for(a=new Array(o.length),e=0,r=o.length;e<r;e+=1)n=o[e],i=Object.keys(n),a[e]=[i[0],n[i[0]]];return a}(0,n.K2)(yt,"resolveYamlPairs"),(0,n.K2)(xt,"constructYamlPairs");var bt=new w("tag:yaml.org,2002:pairs",{kind:"sequence",resolve:yt,construct:xt}),kt=Object.prototype.hasOwnProperty;function Ct(t){if(null===t)return!0;var e,r=t;for(e in r)if(kt.call(r,e)&&null!==r[e])return!1;return!0}function wt(t){return null!==t?t:{}}(0,n.K2)(Ct,"resolveYamlSet"),(0,n.K2)(wt,"constructYamlSet");var _t=new w("tag:yaml.org,2002:set",{kind:"mapping",resolve:Ct,construct:wt}),vt=Z.extend({implicit:[rt,it],explicit:[ht,gt,bt,_t]}),St=Object.prototype.hasOwnProperty,At=1,Tt=2,Mt=3,Bt=4,Lt=1,Ft=2,$t=3,Et=/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Nt=/[\x85\u2028\u2029]/,Dt=/[,\[\]\{\}]/,jt=/^(?:!|!!|![a-z\-]+!)$/i,It=/^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;function Ot(t){return Object.prototype.toString.call(t)}function Rt(t){return 10===t||13===t}function Pt(t){return 9===t||32===t}function zt(t){return 9===t||32===t||10===t||13===t}function Kt(t){return 44===t||91===t||93===t||123===t||125===t}function qt(t){var e;return 48<=t&&t<=57?t-48:97<=(e=32|t)&&e<=102?e-97+10:-1}function Wt(t){return 120===t?2:117===t?4:85===t?8:0}function Ht(t){return 48<=t&&t<=57?t-48:-1}function Ut(t){return 48===t?"\0":97===t?"\x07":98===t?"\b":116===t||9===t?"\t":110===t?"\n":118===t?"\v":102===t?"\f":114===t?"\r":101===t?"\x1b":32===t?" ":34===t?'"':47===t?"/":92===t?"\\":78===t?"\x85":95===t?"\xa0":76===t?"\u2028":80===t?"\u2029":""}function Yt(t){return t<=65535?String.fromCharCode(t):String.fromCharCode(55296+(t-65536>>10),56320+(t-65536&1023))}(0,n.K2)(Ot,"_class"),(0,n.K2)(Rt,"is_EOL"),(0,n.K2)(Pt,"is_WHITE_SPACE"),(0,n.K2)(zt,"is_WS_OR_EOL"),(0,n.K2)(Kt,"is_FLOW_INDICATOR"),(0,n.K2)(qt,"fromHexCode"),(0,n.K2)(Wt,"escapedHexLen"),(0,n.K2)(Ht,"fromDecimalCode"),(0,n.K2)(Ut,"simpleEscapeSequence"),(0,n.K2)(Yt,"charFromCodepoint");var Vt,Gt=new Array(256),Zt=new Array(256);for(Vt=0;Vt<256;Vt++)Gt[Vt]=Ut(Vt)?1:0,Zt[Vt]=Ut(Vt);function Xt(t,e){this.input=t,this.filename=e.filename||null,this.schema=e.schema||vt,this.onWarning=e.onWarning||null,this.legacy=e.legacy||!1,this.json=e.json||!1,this.listener=e.listener||null,this.implicitTypes=this.schema.compiledImplicit,this.typeMap=this.schema.compiledTypeMap,this.length=t.length,this.position=0,this.line=0,this.lineStart=0,this.lineIndent=0,this.firstTabInLine=-1,this.documents=[]}function Qt(t,e){var r={name:t.filename,buffer:t.input.slice(0,-1),position:t.position,line:t.line,column:t.position-t.lineStart};return r.snippet=y(r),new p(e,r)}function Jt(t,e){throw Qt(t,e)}function te(t,e){t.onWarning&&t.onWarning.call(null,Qt(t,e))}(0,n.K2)(Xt,"State$1"),(0,n.K2)(Qt,"generateError"),(0,n.K2)(Jt,"throwError"),(0,n.K2)(te,"throwWarning");var ee={YAML:(0,n.K2)((function(t,e,r){var n,i,a;null!==t.version&&Jt(t,"duplication of %YAML directive"),1!==r.length&&Jt(t,"YAML directive accepts exactly one argument"),null===(n=/^([0-9]+)\.([0-9]+)$/.exec(r[0]))&&Jt(t,"ill-formed argument of the YAML directive"),i=parseInt(n[1],10),a=parseInt(n[2],10),1!==i&&Jt(t,"unacceptable YAML version of the document"),t.version=r[0],t.checkLineBreaks=a<2,1!==a&&2!==a&&te(t,"unsupported YAML version of the document")}),"handleYamlDirective"),TAG:(0,n.K2)((function(t,e,r){var n,i;2!==r.length&&Jt(t,"TAG directive accepts exactly two arguments"),n=r[0],i=r[1],jt.test(n)||Jt(t,"ill-formed tag handle (first argument) of the TAG directive"),St.call(t.tagMap,n)&&Jt(t,'there is a previously declared suffix for "'+n+'" tag handle'),It.test(i)||Jt(t,"ill-formed tag prefix (second argument) of the TAG directive");try{i=decodeURIComponent(i)}catch(a){Jt(t,"tag prefix is malformed: "+i)}t.tagMap[n]=i}),"handleTagDirective")};function re(t,e,r,n){var i,a,o,s;if(e<r){if(s=t.input.slice(e,r),n)for(i=0,a=s.length;i<a;i+=1)9===(o=s.charCodeAt(i))||32<=o&&o<=1114111||Jt(t,"expected valid JSON character");else Et.test(s)&&Jt(t,"the stream contains non-printable characters");t.result+=s}}function ne(t,e,r,n){var i,a,o,s;for(h.isObject(r)||Jt(t,"cannot merge mappings; the provided source object is unacceptable"),o=0,s=(i=Object.keys(r)).length;o<s;o+=1)a=i[o],St.call(e,a)||(e[a]=r[a],n[a]=!0)}function ie(t,e,r,n,i,a,o,s,l){var c,h;if(Array.isArray(i))for(c=0,h=(i=Array.prototype.slice.call(i)).length;c<h;c+=1)Array.isArray(i[c])&&Jt(t,"nested arrays are not supported inside keys"),"object"==typeof i&&"[object Object]"===Ot(i[c])&&(i[c]="[object Object]");if("object"==typeof i&&"[object Object]"===Ot(i)&&(i="[object Object]"),i=String(i),null===e&&(e={}),"tag:yaml.org,2002:merge"===n)if(Array.isArray(a))for(c=0,h=a.length;c<h;c+=1)ne(t,e,a[c],r);else ne(t,e,a,r);else t.json||St.call(r,i)||!St.call(e,i)||(t.line=o||t.line,t.lineStart=s||t.lineStart,t.position=l||t.position,Jt(t,"duplicated mapping key")),"__proto__"===i?Object.defineProperty(e,i,{configurable:!0,enumerable:!0,writable:!0,value:a}):e[i]=a,delete r[i];return e}function ae(t){var e;10===(e=t.input.charCodeAt(t.position))?t.position++:13===e?(t.position++,10===t.input.charCodeAt(t.position)&&t.position++):Jt(t,"a line break is expected"),t.line+=1,t.lineStart=t.position,t.firstTabInLine=-1}function oe(t,e,r){for(var n=0,i=t.input.charCodeAt(t.position);0!==i;){for(;Pt(i);)9===i&&-1===t.firstTabInLine&&(t.firstTabInLine=t.position),i=t.input.charCodeAt(++t.position);if(e&&35===i)do{i=t.input.charCodeAt(++t.position)}while(10!==i&&13!==i&&0!==i);if(!Rt(i))break;for(ae(t),i=t.input.charCodeAt(t.position),n++,t.lineIndent=0;32===i;)t.lineIndent++,i=t.input.charCodeAt(++t.position)}return-1!==r&&0!==n&&t.lineIndent<r&&te(t,"deficient indentation"),n}function se(t){var e,r=t.position;return!(45!==(e=t.input.charCodeAt(r))&&46!==e||e!==t.input.charCodeAt(r+1)||e!==t.input.charCodeAt(r+2)||(r+=3,0!==(e=t.input.charCodeAt(r))&&!zt(e)))}function le(t,e){1===e?t.result+=" ":e>1&&(t.result+=h.repeat("\n",e-1))}function ce(t,e,r){var n,i,a,o,s,l,c,h,u=t.kind,d=t.result;if(zt(h=t.input.charCodeAt(t.position))||Kt(h)||35===h||38===h||42===h||33===h||124===h||62===h||39===h||34===h||37===h||64===h||96===h)return!1;if((63===h||45===h)&&(zt(n=t.input.charCodeAt(t.position+1))||r&&Kt(n)))return!1;for(t.kind="scalar",t.result="",i=a=t.position,o=!1;0!==h;){if(58===h){if(zt(n=t.input.charCodeAt(t.position+1))||r&&Kt(n))break}else if(35===h){if(zt(t.input.charCodeAt(t.position-1)))break}else{if(t.position===t.lineStart&&se(t)||r&&Kt(h))break;if(Rt(h)){if(s=t.line,l=t.lineStart,c=t.lineIndent,oe(t,!1,-1),t.lineIndent>=e){o=!0,h=t.input.charCodeAt(t.position);continue}t.position=a,t.line=s,t.lineStart=l,t.lineIndent=c;break}}o&&(re(t,i,a,!1),le(t,t.line-s),i=a=t.position,o=!1),Pt(h)||(a=t.position+1),h=t.input.charCodeAt(++t.position)}return re(t,i,a,!1),!!t.result||(t.kind=u,t.result=d,!1)}function he(t,e){var r,n,i;if(39!==(r=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,n=i=t.position;0!==(r=t.input.charCodeAt(t.position));)if(39===r){if(re(t,n,t.position,!0),39!==(r=t.input.charCodeAt(++t.position)))return!0;n=t.position,t.position++,i=t.position}else Rt(r)?(re(t,n,i,!0),le(t,oe(t,!1,e)),n=i=t.position):t.position===t.lineStart&&se(t)?Jt(t,"unexpected end of the document within a single quoted scalar"):(t.position++,i=t.position);Jt(t,"unexpected end of the stream within a single quoted scalar")}function ue(t,e){var r,n,i,a,o,s;if(34!==(s=t.input.charCodeAt(t.position)))return!1;for(t.kind="scalar",t.result="",t.position++,r=n=t.position;0!==(s=t.input.charCodeAt(t.position));){if(34===s)return re(t,r,t.position,!0),t.position++,!0;if(92===s){if(re(t,r,t.position,!0),Rt(s=t.input.charCodeAt(++t.position)))oe(t,!1,e);else if(s<256&&Gt[s])t.result+=Zt[s],t.position++;else if((o=Wt(s))>0){for(i=o,a=0;i>0;i--)(o=qt(s=t.input.charCodeAt(++t.position)))>=0?a=(a<<4)+o:Jt(t,"expected hexadecimal character");t.result+=Yt(a),t.position++}else Jt(t,"unknown escape sequence");r=n=t.position}else Rt(s)?(re(t,r,n,!0),le(t,oe(t,!1,e)),r=n=t.position):t.position===t.lineStart&&se(t)?Jt(t,"unexpected end of the document within a double quoted scalar"):(t.position++,n=t.position)}Jt(t,"unexpected end of the stream within a double quoted scalar")}function de(t,e){var r,n,i,a,o,s,l,c,h,u,d,p,f=!0,g=t.tag,m=t.anchor,y=Object.create(null);if(91===(p=t.input.charCodeAt(t.position)))o=93,c=!1,a=[];else{if(123!==p)return!1;o=125,c=!0,a={}}for(null!==t.anchor&&(t.anchorMap[t.anchor]=a),p=t.input.charCodeAt(++t.position);0!==p;){if(oe(t,!0,e),(p=t.input.charCodeAt(t.position))===o)return t.position++,t.tag=g,t.anchor=m,t.kind=c?"mapping":"sequence",t.result=a,!0;f?44===p&&Jt(t,"expected the node content, but found ','"):Jt(t,"missed comma between flow collection entries"),d=null,s=l=!1,63===p&&zt(t.input.charCodeAt(t.position+1))&&(s=l=!0,t.position++,oe(t,!0,e)),r=t.line,n=t.lineStart,i=t.position,be(t,e,At,!1,!0),u=t.tag,h=t.result,oe(t,!0,e),p=t.input.charCodeAt(t.position),!l&&t.line!==r||58!==p||(s=!0,p=t.input.charCodeAt(++t.position),oe(t,!0,e),be(t,e,At,!1,!0),d=t.result),c?ie(t,a,y,u,h,d,r,n,i):s?a.push(ie(t,null,y,u,h,d,r,n,i)):a.push(h),oe(t,!0,e),44===(p=t.input.charCodeAt(t.position))?(f=!0,p=t.input.charCodeAt(++t.position)):f=!1}Jt(t,"unexpected end of the stream within a flow collection")}function pe(t,e){var r,n,i,a,o=Lt,s=!1,l=!1,c=e,u=0,d=!1;if(124===(a=t.input.charCodeAt(t.position)))n=!1;else{if(62!==a)return!1;n=!0}for(t.kind="scalar",t.result="";0!==a;)if(43===(a=t.input.charCodeAt(++t.position))||45===a)Lt===o?o=43===a?$t:Ft:Jt(t,"repeat of a chomping mode identifier");else{if(!((i=Ht(a))>=0))break;0===i?Jt(t,"bad explicit indentation width of a block scalar; it cannot be less than one"):l?Jt(t,"repeat of an indentation width identifier"):(c=e+i-1,l=!0)}if(Pt(a)){do{a=t.input.charCodeAt(++t.position)}while(Pt(a));if(35===a)do{a=t.input.charCodeAt(++t.position)}while(!Rt(a)&&0!==a)}for(;0!==a;){for(ae(t),t.lineIndent=0,a=t.input.charCodeAt(t.position);(!l||t.lineIndent<c)&&32===a;)t.lineIndent++,a=t.input.charCodeAt(++t.position);if(!l&&t.lineIndent>c&&(c=t.lineIndent),Rt(a))u++;else{if(t.lineIndent<c){o===$t?t.result+=h.repeat("\n",s?1+u:u):o===Lt&&s&&(t.result+="\n");break}for(n?Pt(a)?(d=!0,t.result+=h.repeat("\n",s?1+u:u)):d?(d=!1,t.result+=h.repeat("\n",u+1)):0===u?s&&(t.result+=" "):t.result+=h.repeat("\n",u):t.result+=h.repeat("\n",s?1+u:u),s=!0,l=!0,u=0,r=t.position;!Rt(a)&&0!==a;)a=t.input.charCodeAt(++t.position);re(t,r,t.position,!1)}}return!0}function fe(t,e){var r,n,i=t.tag,a=t.anchor,o=[],s=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=o),n=t.input.charCodeAt(t.position);0!==n&&(-1!==t.firstTabInLine&&(t.position=t.firstTabInLine,Jt(t,"tab characters must not be used in indentation")),45===n)&&zt(t.input.charCodeAt(t.position+1));)if(s=!0,t.position++,oe(t,!0,-1)&&t.lineIndent<=e)o.push(null),n=t.input.charCodeAt(t.position);else if(r=t.line,be(t,e,Mt,!1,!0),o.push(t.result),oe(t,!0,-1),n=t.input.charCodeAt(t.position),(t.line===r||t.lineIndent>e)&&0!==n)Jt(t,"bad indentation of a sequence entry");else if(t.lineIndent<e)break;return!!s&&(t.tag=i,t.anchor=a,t.kind="sequence",t.result=o,!0)}function ge(t,e,r){var n,i,a,o,s,l,c,h=t.tag,u=t.anchor,d={},p=Object.create(null),f=null,g=null,m=null,y=!1,x=!1;if(-1!==t.firstTabInLine)return!1;for(null!==t.anchor&&(t.anchorMap[t.anchor]=d),c=t.input.charCodeAt(t.position);0!==c;){if(y||-1===t.firstTabInLine||(t.position=t.firstTabInLine,Jt(t,"tab characters must not be used in indentation")),n=t.input.charCodeAt(t.position+1),a=t.line,63!==c&&58!==c||!zt(n)){if(o=t.line,s=t.lineStart,l=t.position,!be(t,r,Tt,!1,!0))break;if(t.line===a){for(c=t.input.charCodeAt(t.position);Pt(c);)c=t.input.charCodeAt(++t.position);if(58===c)zt(c=t.input.charCodeAt(++t.position))||Jt(t,"a whitespace character is expected after the key-value separator within a block mapping"),y&&(ie(t,d,p,f,g,null,o,s,l),f=g=m=null),x=!0,y=!1,i=!1,f=t.tag,g=t.result;else{if(!x)return t.tag=h,t.anchor=u,!0;Jt(t,"can not read an implicit mapping pair; a colon is missed")}}else{if(!x)return t.tag=h,t.anchor=u,!0;Jt(t,"can not read a block mapping entry; a multiline key may not be an implicit key")}}else 63===c?(y&&(ie(t,d,p,f,g,null,o,s,l),f=g=m=null),x=!0,y=!0,i=!0):y?(y=!1,i=!0):Jt(t,"incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line"),t.position+=1,c=n;if((t.line===a||t.lineIndent>e)&&(y&&(o=t.line,s=t.lineStart,l=t.position),be(t,e,Bt,!0,i)&&(y?g=t.result:m=t.result),y||(ie(t,d,p,f,g,m,o,s,l),f=g=m=null),oe(t,!0,-1),c=t.input.charCodeAt(t.position)),(t.line===a||t.lineIndent>e)&&0!==c)Jt(t,"bad indentation of a mapping entry");else if(t.lineIndent<e)break}return y&&ie(t,d,p,f,g,null,o,s,l),x&&(t.tag=h,t.anchor=u,t.kind="mapping",t.result=d),x}function me(t){var e,r,n,i,a=!1,o=!1;if(33!==(i=t.input.charCodeAt(t.position)))return!1;if(null!==t.tag&&Jt(t,"duplication of a tag property"),60===(i=t.input.charCodeAt(++t.position))?(a=!0,i=t.input.charCodeAt(++t.position)):33===i?(o=!0,r="!!",i=t.input.charCodeAt(++t.position)):r="!",e=t.position,a){do{i=t.input.charCodeAt(++t.position)}while(0!==i&&62!==i);t.position<t.length?(n=t.input.slice(e,t.position),i=t.input.charCodeAt(++t.position)):Jt(t,"unexpected end of the stream within a verbatim tag")}else{for(;0!==i&&!zt(i);)33===i&&(o?Jt(t,"tag suffix cannot contain exclamation marks"):(r=t.input.slice(e-1,t.position+1),jt.test(r)||Jt(t,"named tag handle cannot contain such characters"),o=!0,e=t.position+1)),i=t.input.charCodeAt(++t.position);n=t.input.slice(e,t.position),Dt.test(n)&&Jt(t,"tag suffix cannot contain flow indicator characters")}n&&!It.test(n)&&Jt(t,"tag name cannot contain such characters: "+n);try{n=decodeURIComponent(n)}catch(s){Jt(t,"tag name is malformed: "+n)}return a?t.tag=n:St.call(t.tagMap,r)?t.tag=t.tagMap[r]+n:"!"===r?t.tag="!"+n:"!!"===r?t.tag="tag:yaml.org,2002:"+n:Jt(t,'undeclared tag handle "'+r+'"'),!0}function ye(t){var e,r;if(38!==(r=t.input.charCodeAt(t.position)))return!1;for(null!==t.anchor&&Jt(t,"duplication of an anchor property"),r=t.input.charCodeAt(++t.position),e=t.position;0!==r&&!zt(r)&&!Kt(r);)r=t.input.charCodeAt(++t.position);return t.position===e&&Jt(t,"name of an anchor node must contain at least one character"),t.anchor=t.input.slice(e,t.position),!0}function xe(t){var e,r,n;if(42!==(n=t.input.charCodeAt(t.position)))return!1;for(n=t.input.charCodeAt(++t.position),e=t.position;0!==n&&!zt(n)&&!Kt(n);)n=t.input.charCodeAt(++t.position);return t.position===e&&Jt(t,"name of an alias node must contain at least one character"),r=t.input.slice(e,t.position),St.call(t.anchorMap,r)||Jt(t,'unidentified alias "'+r+'"'),t.result=t.anchorMap[r],oe(t,!0,-1),!0}function be(t,e,r,n,i){var a,o,s,l,c,h,u,d,p,f=1,g=!1,m=!1;if(null!==t.listener&&t.listener("open",t),t.tag=null,t.anchor=null,t.kind=null,t.result=null,a=o=s=Bt===r||Mt===r,n&&oe(t,!0,-1)&&(g=!0,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)),1===f)for(;me(t)||ye(t);)oe(t,!0,-1)?(g=!0,s=a,t.lineIndent>e?f=1:t.lineIndent===e?f=0:t.lineIndent<e&&(f=-1)):s=!1;if(s&&(s=g||i),1!==f&&Bt!==r||(d=At===r||Tt===r?e:e+1,p=t.position-t.lineStart,1===f?s&&(fe(t,p)||ge(t,p,d))||de(t,d)?m=!0:(o&&pe(t,d)||he(t,d)||ue(t,d)?m=!0:xe(t)?(m=!0,null===t.tag&&null===t.anchor||Jt(t,"alias node should not have any properties")):ce(t,d,At===r)&&(m=!0,null===t.tag&&(t.tag="?")),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):0===f&&(m=s&&fe(t,p))),null===t.tag)null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);else if("?"===t.tag){for(null!==t.result&&"scalar"!==t.kind&&Jt(t,'unacceptable node kind for !<?> tag; it should be "scalar", not "'+t.kind+'"'),l=0,c=t.implicitTypes.length;l<c;l+=1)if((u=t.implicitTypes[l]).resolve(t.result)){t.result=u.construct(t.result),t.tag=u.tag,null!==t.anchor&&(t.anchorMap[t.anchor]=t.result);break}}else if("!"!==t.tag){if(St.call(t.typeMap[t.kind||"fallback"],t.tag))u=t.typeMap[t.kind||"fallback"][t.tag];else for(u=null,l=0,c=(h=t.typeMap.multi[t.kind||"fallback"]).length;l<c;l+=1)if(t.tag.slice(0,h[l].tag.length)===h[l].tag){u=h[l];break}u||Jt(t,"unknown tag !<"+t.tag+">"),null!==t.result&&u.kind!==t.kind&&Jt(t,"unacceptable node kind for !<"+t.tag+'> tag; it should be "'+u.kind+'", not "'+t.kind+'"'),u.resolve(t.result,t.tag)?(t.result=u.construct(t.result,t.tag),null!==t.anchor&&(t.anchorMap[t.anchor]=t.result)):Jt(t,"cannot resolve a node with !<"+t.tag+"> explicit tag")}return null!==t.listener&&t.listener("close",t),null!==t.tag||null!==t.anchor||m}function ke(t){var e,r,n,i,a=t.position,o=!1;for(t.version=null,t.checkLineBreaks=t.legacy,t.tagMap=Object.create(null),t.anchorMap=Object.create(null);0!==(i=t.input.charCodeAt(t.position))&&(oe(t,!0,-1),i=t.input.charCodeAt(t.position),!(t.lineIndent>0||37!==i));){for(o=!0,i=t.input.charCodeAt(++t.position),e=t.position;0!==i&&!zt(i);)i=t.input.charCodeAt(++t.position);for(n=[],(r=t.input.slice(e,t.position)).length<1&&Jt(t,"directive name must not be less than one character in length");0!==i;){for(;Pt(i);)i=t.input.charCodeAt(++t.position);if(35===i){do{i=t.input.charCodeAt(++t.position)}while(0!==i&&!Rt(i));break}if(Rt(i))break;for(e=t.position;0!==i&&!zt(i);)i=t.input.charCodeAt(++t.position);n.push(t.input.slice(e,t.position))}0!==i&&ae(t),St.call(ee,r)?ee[r](t,r,n):te(t,'unknown document directive "'+r+'"')}oe(t,!0,-1),0===t.lineIndent&&45===t.input.charCodeAt(t.position)&&45===t.input.charCodeAt(t.position+1)&&45===t.input.charCodeAt(t.position+2)?(t.position+=3,oe(t,!0,-1)):o&&Jt(t,"directives end mark is expected"),be(t,t.lineIndent-1,Bt,!1,!0),oe(t,!0,-1),t.checkLineBreaks&&Nt.test(t.input.slice(a,t.position))&&te(t,"non-ASCII line breaks are interpreted as content"),t.documents.push(t.result),t.position===t.lineStart&&se(t)?46===t.input.charCodeAt(t.position)&&(t.position+=3,oe(t,!0,-1)):t.position<t.length-1&&Jt(t,"end of the stream or a document separator is expected")}function Ce(t,e){e=e||{},0!==(t=String(t)).length&&(10!==t.charCodeAt(t.length-1)&&13!==t.charCodeAt(t.length-1)&&(t+="\n"),65279===t.charCodeAt(0)&&(t=t.slice(1)));var r=new Xt(t,e),n=t.indexOf("\0");for(-1!==n&&(r.position=n,Jt(r,"null byte is not allowed in input")),r.input+="\0";32===r.input.charCodeAt(r.position);)r.lineIndent+=1,r.position+=1;for(;r.position<r.length-1;)ke(r);return r.documents}function we(t,e,r){null!==e&&"object"==typeof e&&void 0===r&&(r=e,e=null);var n=Ce(t,r);if("function"!=typeof e)return n;for(var i=0,a=n.length;i<a;i+=1)e(n[i])}function _e(t,e){var r=Ce(t,e);if(0!==r.length){if(1===r.length)return r[0];throw new p("expected a single document in the stream, but found more")}}(0,n.K2)(re,"captureSegment"),(0,n.K2)(ne,"mergeMappings"),(0,n.K2)(ie,"storeMappingPair"),(0,n.K2)(ae,"readLineBreak"),(0,n.K2)(oe,"skipSeparationSpace"),(0,n.K2)(se,"testDocumentSeparator"),(0,n.K2)(le,"writeFoldedLines"),(0,n.K2)(ce,"readPlainScalar"),(0,n.K2)(he,"readSingleQuotedScalar"),(0,n.K2)(ue,"readDoubleQuotedScalar"),(0,n.K2)(de,"readFlowCollection"),(0,n.K2)(pe,"readBlockScalar"),(0,n.K2)(fe,"readBlockSequence"),(0,n.K2)(ge,"readBlockMapping"),(0,n.K2)(me,"readTagProperty"),(0,n.K2)(ye,"readAnchorProperty"),(0,n.K2)(xe,"readAlias"),(0,n.K2)(be,"composeNode"),(0,n.K2)(ke,"readDocument"),(0,n.K2)(Ce,"loadDocuments"),(0,n.K2)(we,"loadAll$1"),(0,n.K2)(_e,"load$1");var ve={loadAll:we,load:_e},Se=Object.prototype.toString,Ae=Object.prototype.hasOwnProperty,Te=65279,Me=9,Be=10,Le=13,Fe=32,$e=33,Ee=34,Ne=35,De=37,je=38,Ie=39,Oe=42,Re=44,Pe=45,ze=58,Ke=61,qe=62,We=63,He=64,Ue=91,Ye=93,Ve=96,Ge=123,Ze=124,Xe=125,Qe={0:"\\0",7:"\\a",8:"\\b",9:"\\t",10:"\\n",11:"\\v",12:"\\f",13:"\\r",27:"\\e",34:'\\"',92:"\\\\",133:"\\N",160:"\\_",8232:"\\L",8233:"\\P"},Je=["y","Y","yes","Yes","YES","on","On","ON","n","N","no","No","NO","off","Off","OFF"],tr=/^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/;function er(t,e){var r,n,i,a,o,s,l;if(null===e)return{};for(r={},i=0,a=(n=Object.keys(e)).length;i<a;i+=1)o=n[i],s=String(e[o]),"!!"===o.slice(0,2)&&(o="tag:yaml.org,2002:"+o.slice(2)),(l=t.compiledTypeMap.fallback[o])&&Ae.call(l.styleAliases,s)&&(s=l.styleAliases[s]),r[o]=s;return r}function rr(t){var e,r,n;if(e=t.toString(16).toUpperCase(),t<=255)r="x",n=2;else if(t<=65535)r="u",n=4;else{if(!(t<=4294967295))throw new p("code point within a string may not be greater than 0xFFFFFFFF");r="U",n=8}return"\\"+r+h.repeat("0",n-e.length)+e}(0,n.K2)(er,"compileStyleMap"),(0,n.K2)(rr,"encodeHex");var nr=1,ir=2;function ar(t){this.schema=t.schema||vt,this.indent=Math.max(1,t.indent||2),this.noArrayIndent=t.noArrayIndent||!1,this.skipInvalid=t.skipInvalid||!1,this.flowLevel=h.isNothing(t.flowLevel)?-1:t.flowLevel,this.styleMap=er(this.schema,t.styles||null),this.sortKeys=t.sortKeys||!1,this.lineWidth=t.lineWidth||80,this.noRefs=t.noRefs||!1,this.noCompatMode=t.noCompatMode||!1,this.condenseFlow=t.condenseFlow||!1,this.quotingType='"'===t.quotingType?ir:nr,this.forceQuotes=t.forceQuotes||!1,this.replacer="function"==typeof t.replacer?t.replacer:null,this.implicitTypes=this.schema.compiledImplicit,this.explicitTypes=this.schema.compiledExplicit,this.tag=null,this.result="",this.duplicates=[],this.usedDuplicates=null}function or(t,e){for(var r,n=h.repeat(" ",e),i=0,a=-1,o="",s=t.length;i<s;)-1===(a=t.indexOf("\n",i))?(r=t.slice(i),i=s):(r=t.slice(i,a+1),i=a+1),r.length&&"\n"!==r&&(o+=n),o+=r;return o}function sr(t,e){return"\n"+h.repeat(" ",t.indent*e)}function lr(t,e){var r,n;for(r=0,n=t.implicitTypes.length;r<n;r+=1)if(t.implicitTypes[r].resolve(e))return!0;return!1}function cr(t){return t===Fe||t===Me}function hr(t){return 32<=t&&t<=126||161<=t&&t<=55295&&8232!==t&&8233!==t||57344<=t&&t<=65533&&t!==Te||65536<=t&&t<=1114111}function ur(t){return hr(t)&&t!==Te&&t!==Le&&t!==Be}function dr(t,e,r){var n=ur(t),i=n&&!cr(t);return(r?n:n&&t!==Re&&t!==Ue&&t!==Ye&&t!==Ge&&t!==Xe)&&t!==Ne&&!(e===ze&&!i)||ur(e)&&!cr(e)&&t===Ne||e===ze&&i}function pr(t){return hr(t)&&t!==Te&&!cr(t)&&t!==Pe&&t!==We&&t!==ze&&t!==Re&&t!==Ue&&t!==Ye&&t!==Ge&&t!==Xe&&t!==Ne&&t!==je&&t!==Oe&&t!==$e&&t!==Ze&&t!==Ke&&t!==qe&&t!==Ie&&t!==Ee&&t!==De&&t!==He&&t!==Ve}function fr(t){return!cr(t)&&t!==ze}function gr(t,e){var r,n=t.charCodeAt(e);return n>=55296&&n<=56319&&e+1<t.length&&(r=t.charCodeAt(e+1))>=56320&&r<=57343?1024*(n-55296)+r-56320+65536:n}function mr(t){return/^\n* /.test(t)}(0,n.K2)(ar,"State"),(0,n.K2)(or,"indentString"),(0,n.K2)(sr,"generateNextLine"),(0,n.K2)(lr,"testImplicitResolving"),(0,n.K2)(cr,"isWhitespace"),(0,n.K2)(hr,"isPrintable"),(0,n.K2)(ur,"isNsCharOrWhitespace"),(0,n.K2)(dr,"isPlainSafe"),(0,n.K2)(pr,"isPlainSafeFirst"),(0,n.K2)(fr,"isPlainSafeLast"),(0,n.K2)(gr,"codePointAt"),(0,n.K2)(mr,"needIndentIndicator");var yr=1,xr=2,br=3,kr=4,Cr=5;function wr(t,e,r,n,i,a,o,s){var l,c=0,h=null,u=!1,d=!1,p=-1!==n,f=-1,g=pr(gr(t,0))&&fr(gr(t,t.length-1));if(e||o)for(l=0;l<t.length;c>=65536?l+=2:l++){if(!hr(c=gr(t,l)))return Cr;g=g&&dr(c,h,s),h=c}else{for(l=0;l<t.length;c>=65536?l+=2:l++){if((c=gr(t,l))===Be)u=!0,p&&(d=d||l-f-1>n&&" "!==t[f+1],f=l);else if(!hr(c))return Cr;g=g&&dr(c,h,s),h=c}d=d||p&&l-f-1>n&&" "!==t[f+1]}return u||d?r>9&&mr(t)?Cr:o?a===ir?Cr:xr:d?kr:br:!g||o||i(t)?a===ir?Cr:xr:yr}function _r(t,e,r,i,a){t.dump=function(){if(0===e.length)return t.quotingType===ir?'""':"''";if(!t.noCompatMode&&(-1!==Je.indexOf(e)||tr.test(e)))return t.quotingType===ir?'"'+e+'"':"'"+e+"'";var o=t.indent*Math.max(1,r),s=-1===t.lineWidth?-1:Math.max(Math.min(t.lineWidth,40),t.lineWidth-o),l=i||t.flowLevel>-1&&r>=t.flowLevel;function c(e){return lr(t,e)}switch((0,n.K2)(c,"testAmbiguity"),wr(e,l,t.indent,s,c,t.quotingType,t.forceQuotes&&!i,a)){case yr:return e;case xr:return"'"+e.replace(/'/g,"''")+"'";case br:return"|"+vr(e,t.indent)+Sr(or(e,o));case kr:return">"+vr(e,t.indent)+Sr(or(Ar(e,s),o));case Cr:return'"'+Mr(e)+'"';default:throw new p("impossible error: invalid scalar style")}}()}function vr(t,e){var r=mr(t)?String(e):"",n="\n"===t[t.length-1];return r+(n&&("\n"===t[t.length-2]||"\n"===t)?"+":n?"":"-")+"\n"}function Sr(t){return"\n"===t[t.length-1]?t.slice(0,-1):t}function Ar(t,e){for(var r,n,i,a=/(\n+)([^\n]*)/g,o=(r=-1!==(r=t.indexOf("\n"))?r:t.length,a.lastIndex=r,Tr(t.slice(0,r),e)),s="\n"===t[0]||" "===t[0];i=a.exec(t);){var l=i[1],c=i[2];n=" "===c[0],o+=l+(s||n||""===c?"":"\n")+Tr(c,e),s=n}return o}function Tr(t,e){if(""===t||" "===t[0])return t;for(var r,n,i=/ [^ ]/g,a=0,o=0,s=0,l="";r=i.exec(t);)(s=r.index)-a>e&&(n=o>a?o:s,l+="\n"+t.slice(a,n),a=n+1),o=s;return l+="\n",t.length-a>e&&o>a?l+=t.slice(a,o)+"\n"+t.slice(o+1):l+=t.slice(a),l.slice(1)}function Mr(t){for(var e,r="",n=0,i=0;i<t.length;n>=65536?i+=2:i++)n=gr(t,i),!(e=Qe[n])&&hr(n)?(r+=t[i],n>=65536&&(r+=t[i+1])):r+=e||rr(n);return r}function Br(t,e,r){var n,i,a,o="",s=t.tag;for(n=0,i=r.length;n<i;n+=1)a=r[n],t.replacer&&(a=t.replacer.call(r,String(n),a)),(Nr(t,e,a,!1,!1)||void 0===a&&Nr(t,e,null,!1,!1))&&(""!==o&&(o+=","+(t.condenseFlow?"":" ")),o+=t.dump);t.tag=s,t.dump="["+o+"]"}function Lr(t,e,r,n){var i,a,o,s="",l=t.tag;for(i=0,a=r.length;i<a;i+=1)o=r[i],t.replacer&&(o=t.replacer.call(r,String(i),o)),(Nr(t,e+1,o,!0,!0,!1,!0)||void 0===o&&Nr(t,e+1,null,!0,!0,!1,!0))&&(n&&""===s||(s+=sr(t,e)),t.dump&&Be===t.dump.charCodeAt(0)?s+="-":s+="- ",s+=t.dump);t.tag=l,t.dump=s||"[]"}function Fr(t,e,r){var n,i,a,o,s,l="",c=t.tag,h=Object.keys(r);for(n=0,i=h.length;n<i;n+=1)s="",""!==l&&(s+=", "),t.condenseFlow&&(s+='"'),o=r[a=h[n]],t.replacer&&(o=t.replacer.call(r,a,o)),Nr(t,e,a,!1,!1)&&(t.dump.length>1024&&(s+="? "),s+=t.dump+(t.condenseFlow?'"':"")+":"+(t.condenseFlow?"":" "),Nr(t,e,o,!1,!1)&&(l+=s+=t.dump));t.tag=c,t.dump="{"+l+"}"}function $r(t,e,r,n){var i,a,o,s,l,c,h="",u=t.tag,d=Object.keys(r);if(!0===t.sortKeys)d.sort();else if("function"==typeof t.sortKeys)d.sort(t.sortKeys);else if(t.sortKeys)throw new p("sortKeys must be a boolean or a function");for(i=0,a=d.length;i<a;i+=1)c="",n&&""===h||(c+=sr(t,e)),s=r[o=d[i]],t.replacer&&(s=t.replacer.call(r,o,s)),Nr(t,e+1,o,!0,!0,!0)&&((l=null!==t.tag&&"?"!==t.tag||t.dump&&t.dump.length>1024)&&(t.dump&&Be===t.dump.charCodeAt(0)?c+="?":c+="? "),c+=t.dump,l&&(c+=sr(t,e)),Nr(t,e+1,s,!0,l)&&(t.dump&&Be===t.dump.charCodeAt(0)?c+=":":c+=": ",h+=c+=t.dump));t.tag=u,t.dump=h||"{}"}function Er(t,e,r){var n,i,a,o,s,l;for(a=0,o=(i=r?t.explicitTypes:t.implicitTypes).length;a<o;a+=1)if(((s=i[a]).instanceOf||s.predicate)&&(!s.instanceOf||"object"==typeof e&&e instanceof s.instanceOf)&&(!s.predicate||s.predicate(e))){if(r?s.multi&&s.representName?t.tag=s.representName(e):t.tag=s.tag:t.tag="?",s.represent){if(l=t.styleMap[s.tag]||s.defaultStyle,"[object Function]"===Se.call(s.represent))n=s.represent(e,l);else{if(!Ae.call(s.represent,l))throw new p("!<"+s.tag+'> tag resolver accepts not "'+l+'" style');n=s.represent[l](e,l)}t.dump=n}return!0}return!1}function Nr(t,e,r,n,i,a,o){t.tag=null,t.dump=r,Er(t,r,!1)||Er(t,r,!0);var s,l=Se.call(t.dump),c=n;n&&(n=t.flowLevel<0||t.flowLevel>e);var h,u,d="[object Object]"===l||"[object Array]"===l;if(d&&(u=-1!==(h=t.duplicates.indexOf(r))),(null!==t.tag&&"?"!==t.tag||u||2!==t.indent&&e>0)&&(i=!1),u&&t.usedDuplicates[h])t.dump="*ref_"+h;else{if(d&&u&&!t.usedDuplicates[h]&&(t.usedDuplicates[h]=!0),"[object Object]"===l)n&&0!==Object.keys(t.dump).length?($r(t,e,t.dump,i),u&&(t.dump="&ref_"+h+t.dump)):(Fr(t,e,t.dump),u&&(t.dump="&ref_"+h+" "+t.dump));else if("[object Array]"===l)n&&0!==t.dump.length?(t.noArrayIndent&&!o&&e>0?Lr(t,e-1,t.dump,i):Lr(t,e,t.dump,i),u&&(t.dump="&ref_"+h+t.dump)):(Br(t,e,t.dump),u&&(t.dump="&ref_"+h+" "+t.dump));else{if("[object String]"!==l){if("[object Undefined]"===l)return!1;if(t.skipInvalid)return!1;throw new p("unacceptable kind of an object to dump "+l)}"?"!==t.tag&&_r(t,t.dump,e,a,c)}null!==t.tag&&"?"!==t.tag&&(s=encodeURI("!"===t.tag[0]?t.tag.slice(1):t.tag).replace(/!/g,"%21"),s="!"===t.tag[0]?"!"+s:"tag:yaml.org,2002:"===s.slice(0,18)?"!!"+s.slice(18):"!<"+s+">",t.dump=s+" "+t.dump)}return!0}function Dr(t,e){var r,n,i=[],a=[];for(jr(t,i,a),r=0,n=a.length;r<n;r+=1)e.duplicates.push(i[a[r]]);e.usedDuplicates=new Array(n)}function jr(t,e,r){var n,i,a;if(null!==t&&"object"==typeof t)if(-1!==(i=e.indexOf(t)))-1===r.indexOf(i)&&r.push(i);else if(e.push(t),Array.isArray(t))for(i=0,a=t.length;i<a;i+=1)jr(t[i],e,r);else for(i=0,a=(n=Object.keys(t)).length;i<a;i+=1)jr(t[n[i]],e,r)}function Ir(t,e){var r=new ar(e=e||{});r.noRefs||Dr(t,r);var n=t;return r.replacer&&(n=r.replacer.call({"":n},"",n)),Nr(r,0,n,!0,!0)?r.dump+"\n":""}(0,n.K2)(wr,"chooseScalarStyle"),(0,n.K2)(_r,"writeScalar"),(0,n.K2)(vr,"blockHeader"),(0,n.K2)(Sr,"dropEndingNewline"),(0,n.K2)(Ar,"foldString"),(0,n.K2)(Tr,"foldLine"),(0,n.K2)(Mr,"escapeString"),(0,n.K2)(Br,"writeFlowSequence"),(0,n.K2)(Lr,"writeBlockSequence"),(0,n.K2)(Fr,"writeFlowMapping"),(0,n.K2)($r,"writeBlockMapping"),(0,n.K2)(Er,"detectType"),(0,n.K2)(Nr,"writeNode"),(0,n.K2)(Dr,"getDuplicateReferences"),(0,n.K2)(jr,"inspectNode"),(0,n.K2)(Ir,"dump$1");function Or(t,e){return function(){throw new Error("Function yaml."+t+" is removed in js-yaml 4. Use yaml."+e+" instead, which is now safe by default.")}}(0,n.K2)(Or,"renamed");var Rr=G,Pr=ve.load;Or("safeLoad","load"),Or("safeLoadAll","loadAll"),Or("safeDump","dump")},6396:(t,e,r)=>{"use strict";r.d(e,{IU:()=>m,Jo:()=>T,T_:()=>k,g0:()=>L,jP:()=>x});var n=r(5081),i=r(52294),a=r(62392),o=r(86825),s=r(85039),l=r(45567),c=r(20007),h=r(29893),u=(0,l.K2)(((t,e,r,n,i)=>{e.arrowTypeStart&&p(t,"start",e.arrowTypeStart,r,n,i),e.arrowTypeEnd&&p(t,"end",e.arrowTypeEnd,r,n,i)}),"addEdgeMarkers"),d={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},p=(0,l.K2)(((t,e,r,n,i,a)=>{const o=d[r];if(!o)return void l.Rm.warn(`Unknown arrow type: ${r}`);const s="start"===e?"Start":"End";t.attr(`marker-${e}`,`url(${n}#${i}_${a}-${o}${s})`)}),"addEdgeMarker"),f=new Map,g=new Map,m=(0,l.K2)((()=>{f.clear(),g.clear()}),"clear"),y=(0,l.K2)((t=>t?t.reduce(((t,e)=>t+";"+e),""):""),"getLabelStyles"),x=(0,l.K2)((async(t,e)=>{let r=(0,l._3)((0,l.D7)().flowchart.htmlLabels);const i=await(0,o.GZ)(t,e.label,{style:y(e.labelStyle),useHtmlLabels:r,addSvgBackground:!0,isNode:!1});l.Rm.info("abc82",e,e.labelType);const a=t.insert("g").attr("class","edgeLabel"),s=a.insert("g").attr("class","label");s.node().appendChild(i);let h,u=i.getBBox();if(r){const t=i.children[0],e=(0,c.Ltv)(i);u=t.getBoundingClientRect(),e.attr("width",u.width),e.attr("height",u.height)}if(s.attr("transform","translate("+-u.width/2+", "+-u.height/2+")"),f.set(e.id,a),e.width=u.width,e.height=u.height,e.startLabelLeft){const r=await(0,n.DA)(e.startLabelLeft,y(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");h=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),g.get(e.id)||g.set(e.id,{}),g.get(e.id).startLeft=i,b(h,e.startLabelLeft)}if(e.startLabelRight){const r=await(0,n.DA)(e.startLabelRight,y(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");h=i.node().appendChild(r),a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),g.get(e.id)||g.set(e.id,{}),g.get(e.id).startRight=i,b(h,e.startLabelRight)}if(e.endLabelLeft){const r=await(0,n.DA)(e.endLabelLeft,y(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");h=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),i.node().appendChild(r),g.get(e.id)||g.set(e.id,{}),g.get(e.id).endLeft=i,b(h,e.endLabelLeft)}if(e.endLabelRight){const r=await(0,n.DA)(e.endLabelRight,y(e.labelStyle)),i=t.insert("g").attr("class","edgeTerminals"),a=i.insert("g").attr("class","inner");h=a.node().appendChild(r);const o=r.getBBox();a.attr("transform","translate("+-o.width/2+", "+-o.height/2+")"),i.node().appendChild(r),g.get(e.id)||g.set(e.id,{}),g.get(e.id).endRight=i,b(h,e.endLabelRight)}return i}),"insertEdgeLabel");function b(t,e){(0,l.D7)().flowchart.htmlLabels&&t&&(t.style.width=9*e.length+"px",t.style.height="12px")}(0,l.K2)(b,"setTerminalWidth");var k=(0,l.K2)(((t,e)=>{l.Rm.debug("Moving label abc88 ",t.id,t.label,f.get(t.id),e);let r=e.updatedPath?e.updatedPath:e.originalPath;const n=(0,l.D7)(),{subGraphTitleTotalMargin:i}=(0,a.O)(n);if(t.label){const n=f.get(t.id);let a=t.x,o=t.y;if(r){const n=s._K.calcLabelPosition(r);l.Rm.debug("Moving label "+t.label+" from (",a,",",o,") to (",n.x,",",n.y,") abc88"),e.updatedPath&&(a=n.x,o=n.y)}n.attr("transform",`translate(${a}, ${o+i/2})`)}if(t.startLabelLeft){const e=g.get(t.id).startLeft;let n=t.x,i=t.y;if(r){const e=s._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",r);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.startLabelRight){const e=g.get(t.id).startRight;let n=t.x,i=t.y;if(r){const e=s._K.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",r);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelLeft){const e=g.get(t.id).endLeft;let n=t.x,i=t.y;if(r){const e=s._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",r);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}if(t.endLabelRight){const e=g.get(t.id).endRight;let n=t.x,i=t.y;if(r){const e=s._K.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",r);n=e.x,i=e.y}e.attr("transform",`translate(${n}, ${i})`)}}),"positionEdgeLabel"),C=(0,l.K2)(((t,e)=>{const r=t.x,n=t.y,i=Math.abs(e.x-r),a=Math.abs(e.y-n),o=t.width/2,s=t.height/2;return i>=o||a>=s}),"outsideNode"),w=(0,l.K2)(((t,e,r)=>{l.Rm.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(e)}\n insidePoint : ${JSON.stringify(r)}\n node : x:${t.x} y:${t.y} w:${t.width} h:${t.height}`);const n=t.x,i=t.y,a=Math.abs(n-r.x),o=t.width/2;let s=r.x<e.x?o-a:o+a;const c=t.height/2,h=Math.abs(e.y-r.y),u=Math.abs(e.x-r.x);if(Math.abs(i-e.y)*o>Math.abs(n-e.x)*c){let t=r.y<e.y?e.y-c-i:i-c-e.y;s=u*t/h;const n={x:r.x<e.x?r.x+s:r.x-u+s,y:r.y<e.y?r.y+h-t:r.y-h+t};return 0===s&&(n.x=e.x,n.y=e.y),0===u&&(n.x=e.x),0===h&&(n.y=e.y),l.Rm.debug(`abc89 top/bottom calc, Q ${h}, q ${t}, R ${u}, r ${s}`,n),n}{s=r.x<e.x?e.x-o-n:n-o-e.x;let t=h*s/u,i=r.x<e.x?r.x+u-s:r.x-u+s,a=r.y<e.y?r.y+t:r.y-t;return l.Rm.debug(`sides calc abc89, Q ${h}, q ${t}, R ${u}, r ${s}`,{_x:i,_y:a}),0===s&&(i=e.x,a=e.y),0===u&&(i=e.x),0===h&&(a=e.y),{x:i,y:a}}}),"intersection"),_=(0,l.K2)(((t,e)=>{l.Rm.warn("abc88 cutPathAtIntersect",t,e);let r=[],n=t[0],i=!1;return t.forEach((t=>{if(l.Rm.info("abc88 checking point",t,e),C(e,t)||i)l.Rm.warn("abc88 outside",t,n),n=t,i||r.push(t);else{const a=w(e,n,t);l.Rm.debug("abc88 inside",t,n,a),l.Rm.debug("abc88 intersection",a,e);let o=!1;r.forEach((t=>{o=o||t.x===a.x&&t.y===a.y})),r.some((t=>t.x===a.x&&t.y===a.y))?l.Rm.warn("abc88 no intersect",a,r):r.push(a),i=!0}})),l.Rm.debug("returning points",r),r}),"cutPathAtIntersect");function v(t){const e=[],r=[];for(let n=1;n<t.length-1;n++){const i=t[n-1],a=t[n],o=t[n+1];(i.x===a.x&&a.y===o.y&&Math.abs(a.x-o.x)>5&&Math.abs(a.y-i.y)>5||i.y===a.y&&a.x===o.x&&Math.abs(a.x-i.x)>5&&Math.abs(a.y-o.y)>5)&&(e.push(a),r.push(n))}return{cornerPoints:e,cornerPointPositions:r}}(0,l.K2)(v,"extractCornerPoints");var S=(0,l.K2)((function(t,e,r){const n=e.x-t.x,i=e.y-t.y,a=r/Math.sqrt(n*n+i*i);return{x:e.x-a*n,y:e.y-a*i}}),"findAdjacentPoint"),A=(0,l.K2)((function(t){const{cornerPointPositions:e}=v(t),r=[];for(let n=0;n<t.length;n++)if(e.includes(n)){const e=t[n-1],i=t[n+1],a=t[n],o=S(e,a,5),s=S(i,a,5),c=s.x-o.x,h=s.y-o.y;r.push(o);const u=2*Math.sqrt(2);let d={x:a.x,y:a.y};if(Math.abs(i.x-e.x)>10&&Math.abs(i.y-e.y)>=10){l.Rm.debug("Corner point fixing",Math.abs(i.x-e.x),Math.abs(i.y-e.y));const t=5;d=a.x===o.x?{x:c<0?o.x-t+u:o.x+t-u,y:h<0?o.y-u:o.y+u}:{x:c<0?o.x-u:o.x+u,y:h<0?o.y-t+u:o.y+t-u}}else l.Rm.debug("Corner point skipping fixing",Math.abs(i.x-e.x),Math.abs(i.y-e.y));r.push(d,s)}else r.push(t[n]);return r}),"fixCorners"),T=(0,l.K2)((function(t,e,r,n,a,o,s){const{handDrawnSeed:d}=(0,l.D7)();let p=e.points,f=!1;const g=a;var m=o;m.intersect&&g.intersect&&(p=p.slice(1,e.points.length-1),p.unshift(g.intersect(p[0])),l.Rm.debug("Last point APA12",e.start,"--\x3e",e.end,p[p.length-1],m,m.intersect(p[p.length-1])),p.push(m.intersect(p[p.length-1]))),e.toCluster&&(l.Rm.info("to cluster abc88",r.get(e.toCluster)),p=_(e.points,r.get(e.toCluster).node),f=!0),e.fromCluster&&(l.Rm.debug("from cluster abc88",r.get(e.fromCluster),JSON.stringify(p,null,2)),p=_(p.reverse(),r.get(e.fromCluster).node).reverse(),f=!0);let y=p.filter((t=>!Number.isNaN(t.y)));y=A(y);let x=c.qrM;e.curve&&(x=e.curve);const{x:b,y:k}=(0,i.R)(e),C=(0,c.n8j)().x(b).y(k).curve(x);let w,v;switch(e.thickness){case"normal":default:w="edge-thickness-normal";break;case"thick":w="edge-thickness-thick";break;case"invisible":w="edge-thickness-invisible"}switch(e.pattern){case"solid":default:w+=" edge-pattern-solid";break;case"dotted":w+=" edge-pattern-dotted";break;case"dashed":w+=" edge-pattern-dashed"}let S=C(y);const T=Array.isArray(e.style)?e.style:[e.style];if("handDrawn"===e.look){const r=h.A.svg(t);Object.assign([],y);const n=r.path(S,{roughness:.3,seed:d});w+=" transition",v=(0,c.Ltv)(n).select("path").attr("id",e.id).attr("class"," "+w+(e.classes?" "+e.classes:"")).attr("style",T?T.reduce(((t,e)=>t+";"+e),""):"");let i=v.attr("d");v.attr("d",i),t.node().appendChild(v.node())}else v=t.append("path").attr("d",S).attr("id",e.id).attr("class"," "+w+(e.classes?" "+e.classes:"")).attr("style",T?T.reduce(((t,e)=>t+";"+e),""):"");let M="";((0,l.D7)().flowchart.arrowMarkerAbsolute||(0,l.D7)().state.arrowMarkerAbsolute)&&(M=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,M=M.replace(/\(/g,"\\(").replace(/\)/g,"\\)")),l.Rm.info("arrowTypeStart",e.arrowTypeStart),l.Rm.info("arrowTypeEnd",e.arrowTypeEnd),u(v,e,M,s,n);let B={};return f&&(B.updatedPath=p),B.originalPath=e.points,B}),"insertEdge"),M=(0,l.K2)(((t,e,r,n)=>{e.forEach((e=>{B[e](t,r,n)}))}),"insertMarkers"),B={extension:(0,l.K2)(((t,e,r)=>{l.Rm.trace("Making markers for ",r),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionStart").attr("class","marker extension "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 1,7 L18,13 V 1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-extensionEnd").attr("class","marker extension "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 1,1 V 13 L18,7 Z")}),"extension"),composition:(0,l.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionStart").attr("class","marker composition "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-compositionEnd").attr("class","marker composition "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")}),"composition"),aggregation:(0,l.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationStart").attr("class","marker aggregation "+e).attr("refX",18).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-aggregationEnd").attr("class","marker aggregation "+e).attr("refX",1).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z")}),"aggregation"),dependency:(0,l.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyStart").attr("class","marker dependency "+e).attr("refX",6).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 5,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",r+"_"+e+"-dependencyEnd").attr("class","marker dependency "+e).attr("refX",13).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")}),"dependency"),lollipop:(0,l.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopStart").attr("class","marker lollipop "+e).attr("refX",13).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6),t.append("defs").append("marker").attr("id",r+"_"+e+"-lollipopEnd").attr("class","marker lollipop "+e).attr("refX",1).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("circle").attr("stroke","black").attr("fill","transparent").attr("cx",7).attr("cy",7).attr("r",6)}),"lollipop"),point:(0,l.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-pointEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-pointStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",4.5).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",8).attr("markerHeight",8).attr("orient","auto").append("path").attr("d","M 0 5 L 10 10 L 10 0 z").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")}),"point"),circle:(0,l.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-circleEnd").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",11).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-circleStart").attr("class","marker "+e).attr("viewBox","0 0 10 10").attr("refX",-1).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("circle").attr("cx","5").attr("cy","5").attr("r","5").attr("class","arrowMarkerPath").style("stroke-width",1).style("stroke-dasharray","1,0")}),"circle"),cross:(0,l.K2)(((t,e,r)=>{t.append("marker").attr("id",r+"_"+e+"-crossEnd").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",12).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0"),t.append("marker").attr("id",r+"_"+e+"-crossStart").attr("class","marker cross "+e).attr("viewBox","0 0 11 11").attr("refX",-1).attr("refY",5.2).attr("markerUnits","userSpaceOnUse").attr("markerWidth",11).attr("markerHeight",11).attr("orient","auto").append("path").attr("d","M 1,1 l 9,9 M 10,1 l -9,9").attr("class","arrowMarkerPath").style("stroke-width",2).style("stroke-dasharray","1,0")}),"cross"),barb:(0,l.K2)(((t,e,r)=>{t.append("defs").append("marker").attr("id",r+"_"+e+"-barbEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",14).attr("markerUnits","userSpaceOnUse").attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")}),"barb")},L=M},79740:(t,e,r)=>{"use strict";r.d(e,{XX:()=>h,q7:()=>u,sO:()=>c});var n=r(6396),i=r(5081),a=r(85039),o=r(45567),s={common:o.Y2,getConfig:o.zj,insertCluster:i.U,insertEdge:n.Jo,insertEdgeLabel:n.jP,insertMarkers:n.g0,insertNode:i.on,interpolateToCurve:a.Ib,labelHelper:i.Zk,log:o.Rm,positionEdgeLabel:n.T_},l={},c=(0,o.K2)((t=>{for(const e of t)l[e.name]=e}),"registerLayoutLoaders");(0,o.K2)((()=>{c([{name:"dagre",loader:(0,o.K2)((async()=>await Promise.all([r.e(3624),r.e(2334),r.e(1477)]).then(r.bind(r,81477))),"loader")}])}),"registerDefaultLayoutLoaders")();var h=(0,o.K2)((async(t,e)=>{if(!(t.layoutAlgorithm in l))throw new Error(`Unknown layout algorithm: ${t.layoutAlgorithm}`);const r=l[t.layoutAlgorithm];return(await r.loader()).render(t,e,s,{algorithm:r.algorithm})}),"render"),u=(0,o.K2)(((t="",{fallback:e="dagre"}={})=>{if(t in l)return t;if(e in l)return o.Rm.warn(`Layout algorithm ${t} is not registered. Using ${e} as fallback.`),e;throw new Error(`Both layout algorithms ${t} and ${e} are not registered.`)}),"getRegisteredLayoutAlgorithm")},86825:(t,e,r)=>{"use strict";r.d(e,{W6:()=>Tt,GZ:()=>Ft,hE:()=>Lt});var n=r(85039),i=r(45567),a=r(20007);function o(){return{async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null}}let s={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};function l(t){s=t}const c=/[&<>"']/,h=new RegExp(c.source,"g"),u=/[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/,d=new RegExp(u.source,"g"),p={"&":"&","<":"<",">":">",'"':""","'":"'"},f=t=>p[t];function g(t,e){if(e){if(c.test(t))return t.replace(h,f)}else if(u.test(t))return t.replace(d,f);return t}const m=/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/gi;const y=/(^|[^\[])\^/g;function x(t,e){let r="string"==typeof t?t:t.source;e=e||"";const n={replace:(t,e)=>{let i="string"==typeof e?e:e.source;return i=i.replace(y,"$1"),r=r.replace(t,i),n},getRegex:()=>new RegExp(r,e)};return n}function b(t){try{t=encodeURI(t).replace(/%25/g,"%")}catch{return null}return t}const k={exec:()=>null};function C(t,e){const r=t.replace(/\|/g,((t,e,r)=>{let n=!1,i=e;for(;--i>=0&&"\\"===r[i];)n=!n;return n?"|":" |"})).split(/ \|/);let n=0;if(r[0].trim()||r.shift(),r.length>0&&!r[r.length-1].trim()&&r.pop(),e)if(r.length>e)r.splice(e);else for(;r.length<e;)r.push("");for(;n<r.length;n++)r[n]=r[n].trim().replace(/\\\|/g,"|");return r}function w(t,e,r){const n=t.length;if(0===n)return"";let i=0;for(;i<n;){const a=t.charAt(n-i-1);if(a!==e||r){if(a===e||!r)break;i++}else i++}return t.slice(0,n-i)}function _(t,e,r,n){const i=e.href,a=e.title?g(e.title):null,o=t[1].replace(/\\([\[\]])/g,"$1");if("!"!==t[0].charAt(0)){n.state.inLink=!0;const t={type:"link",raw:r,href:i,title:a,text:o,tokens:n.inlineTokens(o)};return n.state.inLink=!1,t}return{type:"image",raw:r,href:i,title:a,text:g(o)}}class v{options;rules;lexer;constructor(t){this.options=t||s}space(t){const e=this.rules.block.newline.exec(t);if(e&&e[0].length>0)return{type:"space",raw:e[0]}}code(t){const e=this.rules.block.code.exec(t);if(e){const t=e[0].replace(/^ {1,4}/gm,"");return{type:"code",raw:e[0],codeBlockStyle:"indented",text:this.options.pedantic?t:w(t,"\n")}}}fences(t){const e=this.rules.block.fences.exec(t);if(e){const t=e[0],r=function(t,e){const r=t.match(/^(\s+)(?:```)/);if(null===r)return e;const n=r[1];return e.split("\n").map((t=>{const e=t.match(/^\s+/);if(null===e)return t;const[r]=e;return r.length>=n.length?t.slice(n.length):t})).join("\n")}(t,e[3]||"");return{type:"code",raw:t,lang:e[2]?e[2].trim().replace(this.rules.inline.anyPunctuation,"$1"):e[2],text:r}}}heading(t){const e=this.rules.block.heading.exec(t);if(e){let t=e[2].trim();if(/#$/.test(t)){const e=w(t,"#");this.options.pedantic?t=e.trim():e&&!/ $/.test(e)||(t=e.trim())}return{type:"heading",raw:e[0],depth:e[1].length,text:t,tokens:this.lexer.inline(t)}}}hr(t){const e=this.rules.block.hr.exec(t);if(e)return{type:"hr",raw:w(e[0],"\n")}}blockquote(t){const e=this.rules.block.blockquote.exec(t);if(e){let t=w(e[0],"\n").split("\n"),r="",n="";const i=[];for(;t.length>0;){let e=!1;const a=[];let o;for(o=0;o<t.length;o++)if(/^ {0,3}>/.test(t[o]))a.push(t[o]),e=!0;else{if(e)break;a.push(t[o])}t=t.slice(o);const s=a.join("\n"),l=s.replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g,"\n $1").replace(/^ {0,3}>[ \t]?/gm,"");r=r?`${r}\n${s}`:s,n=n?`${n}\n${l}`:l;const c=this.lexer.state.top;if(this.lexer.state.top=!0,this.lexer.blockTokens(l,i,!0),this.lexer.state.top=c,0===t.length)break;const h=i[i.length-1];if("code"===h?.type)break;if("blockquote"===h?.type){const e=h,a=e.raw+"\n"+t.join("\n"),o=this.blockquote(a);i[i.length-1]=o,r=r.substring(0,r.length-e.raw.length)+o.raw,n=n.substring(0,n.length-e.text.length)+o.text;break}if("list"!==h?.type);else{const e=h,a=e.raw+"\n"+t.join("\n"),o=this.list(a);i[i.length-1]=o,r=r.substring(0,r.length-h.raw.length)+o.raw,n=n.substring(0,n.length-e.raw.length)+o.raw,t=a.substring(i[i.length-1].raw.length).split("\n")}}return{type:"blockquote",raw:r,tokens:i,text:n}}}list(t){let e=this.rules.block.list.exec(t);if(e){let r=e[1].trim();const n=r.length>1,i={type:"list",raw:"",ordered:n,start:n?+r.slice(0,-1):"",loose:!1,items:[]};r=n?`\\d{1,9}\\${r.slice(-1)}`:`\\${r}`,this.options.pedantic&&(r=n?r:"[*+-]");const a=new RegExp(`^( {0,3}${r})((?:[\t ][^\\n]*)?(?:\\n|$))`);let o=!1;for(;t;){let r=!1,n="",s="";if(!(e=a.exec(t)))break;if(this.rules.block.hr.test(t))break;n=e[0],t=t.substring(n.length);let l=e[2].split("\n",1)[0].replace(/^\t+/,(t=>" ".repeat(3*t.length))),c=t.split("\n",1)[0],h=!l.trim(),u=0;if(this.options.pedantic?(u=2,s=l.trimStart()):h?u=e[1].length+1:(u=e[2].search(/[^ ]/),u=u>4?1:u,s=l.slice(u),u+=e[1].length),h&&/^ *$/.test(c)&&(n+=c+"\n",t=t.substring(c.length+1),r=!0),!r){const e=new RegExp(`^ {0,${Math.min(3,u-1)}}(?:[*+-]|\\d{1,9}[.)])((?:[ \t][^\\n]*)?(?:\\n|$))`),r=new RegExp(`^ {0,${Math.min(3,u-1)}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`),i=new RegExp(`^ {0,${Math.min(3,u-1)}}(?:\`\`\`|~~~)`),a=new RegExp(`^ {0,${Math.min(3,u-1)}}#`);for(;t;){const o=t.split("\n",1)[0];if(c=o,this.options.pedantic&&(c=c.replace(/^ {1,4}(?=( {4})*[^ ])/g," ")),i.test(c))break;if(a.test(c))break;if(e.test(c))break;if(r.test(t))break;if(c.search(/[^ ]/)>=u||!c.trim())s+="\n"+c.slice(u);else{if(h)break;if(l.search(/[^ ]/)>=4)break;if(i.test(l))break;if(a.test(l))break;if(r.test(l))break;s+="\n"+c}h||c.trim()||(h=!0),n+=o+"\n",t=t.substring(o.length+1),l=c.slice(u)}}i.loose||(o?i.loose=!0:/\n *\n *$/.test(n)&&(o=!0));let d,p=null;this.options.gfm&&(p=/^\[[ xX]\] /.exec(s),p&&(d="[ ] "!==p[0],s=s.replace(/^\[[ xX]\] +/,""))),i.items.push({type:"list_item",raw:n,task:!!p,checked:d,loose:!1,text:s,tokens:[]}),i.raw+=n}i.items[i.items.length-1].raw=i.items[i.items.length-1].raw.trimEnd(),i.items[i.items.length-1].text=i.items[i.items.length-1].text.trimEnd(),i.raw=i.raw.trimEnd();for(let t=0;t<i.items.length;t++)if(this.lexer.state.top=!1,i.items[t].tokens=this.lexer.blockTokens(i.items[t].text,[]),!i.loose){const e=i.items[t].tokens.filter((t=>"space"===t.type)),r=e.length>0&&e.some((t=>/\n.*\n/.test(t.raw)));i.loose=r}if(i.loose)for(let t=0;t<i.items.length;t++)i.items[t].loose=!0;return i}}html(t){const e=this.rules.block.html.exec(t);if(e){return{type:"html",block:!0,raw:e[0],pre:"pre"===e[1]||"script"===e[1]||"style"===e[1],text:e[0]}}}def(t){const e=this.rules.block.def.exec(t);if(e){const t=e[1].toLowerCase().replace(/\s+/g," "),r=e[2]?e[2].replace(/^<(.*)>$/,"$1").replace(this.rules.inline.anyPunctuation,"$1"):"",n=e[3]?e[3].substring(1,e[3].length-1).replace(this.rules.inline.anyPunctuation,"$1"):e[3];return{type:"def",tag:t,raw:e[0],href:r,title:n}}}table(t){const e=this.rules.block.table.exec(t);if(!e)return;if(!/[:|]/.test(e[2]))return;const r=C(e[1]),n=e[2].replace(/^\||\| *$/g,"").split("|"),i=e[3]&&e[3].trim()?e[3].replace(/\n[ \t]*$/,"").split("\n"):[],a={type:"table",raw:e[0],header:[],align:[],rows:[]};if(r.length===n.length){for(const t of n)/^ *-+: *$/.test(t)?a.align.push("right"):/^ *:-+: *$/.test(t)?a.align.push("center"):/^ *:-+ *$/.test(t)?a.align.push("left"):a.align.push(null);for(let t=0;t<r.length;t++)a.header.push({text:r[t],tokens:this.lexer.inline(r[t]),header:!0,align:a.align[t]});for(const t of i)a.rows.push(C(t,a.header.length).map(((t,e)=>({text:t,tokens:this.lexer.inline(t),header:!1,align:a.align[e]}))));return a}}lheading(t){const e=this.rules.block.lheading.exec(t);if(e)return{type:"heading",raw:e[0],depth:"="===e[2].charAt(0)?1:2,text:e[1],tokens:this.lexer.inline(e[1])}}paragraph(t){const e=this.rules.block.paragraph.exec(t);if(e){const t="\n"===e[1].charAt(e[1].length-1)?e[1].slice(0,-1):e[1];return{type:"paragraph",raw:e[0],text:t,tokens:this.lexer.inline(t)}}}text(t){const e=this.rules.block.text.exec(t);if(e)return{type:"text",raw:e[0],text:e[0],tokens:this.lexer.inline(e[0])}}escape(t){const e=this.rules.inline.escape.exec(t);if(e)return{type:"escape",raw:e[0],text:g(e[1])}}tag(t){const e=this.rules.inline.tag.exec(t);if(e)return!this.lexer.state.inLink&&/^<a /i.test(e[0])?this.lexer.state.inLink=!0:this.lexer.state.inLink&&/^<\/a>/i.test(e[0])&&(this.lexer.state.inLink=!1),!this.lexer.state.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(e[0])?this.lexer.state.inRawBlock=!0:this.lexer.state.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(e[0])&&(this.lexer.state.inRawBlock=!1),{type:"html",raw:e[0],inLink:this.lexer.state.inLink,inRawBlock:this.lexer.state.inRawBlock,block:!1,text:e[0]}}link(t){const e=this.rules.inline.link.exec(t);if(e){const t=e[2].trim();if(!this.options.pedantic&&/^</.test(t)){if(!/>$/.test(t))return;const e=w(t.slice(0,-1),"\\");if((t.length-e.length)%2==0)return}else{const t=function(t,e){if(-1===t.indexOf(e[1]))return-1;let r=0;for(let n=0;n<t.length;n++)if("\\"===t[n])n++;else if(t[n]===e[0])r++;else if(t[n]===e[1]&&(r--,r<0))return n;return-1}(e[2],"()");if(t>-1){const r=(0===e[0].indexOf("!")?5:4)+e[1].length+t;e[2]=e[2].substring(0,t),e[0]=e[0].substring(0,r).trim(),e[3]=""}}let r=e[2],n="";if(this.options.pedantic){const t=/^([^'"]*[^\s])\s+(['"])(.*)\2/.exec(r);t&&(r=t[1],n=t[3])}else n=e[3]?e[3].slice(1,-1):"";return r=r.trim(),/^</.test(r)&&(r=this.options.pedantic&&!/>$/.test(t)?r.slice(1):r.slice(1,-1)),_(e,{href:r?r.replace(this.rules.inline.anyPunctuation,"$1"):r,title:n?n.replace(this.rules.inline.anyPunctuation,"$1"):n},e[0],this.lexer)}}reflink(t,e){let r;if((r=this.rules.inline.reflink.exec(t))||(r=this.rules.inline.nolink.exec(t))){const t=e[(r[2]||r[1]).replace(/\s+/g," ").toLowerCase()];if(!t){const t=r[0].charAt(0);return{type:"text",raw:t,text:t}}return _(r,t,r[0],this.lexer)}}emStrong(t,e,r=""){let n=this.rules.inline.emStrongLDelim.exec(t);if(!n)return;if(n[3]&&r.match(/[\p{L}\p{N}]/u))return;if(!(n[1]||n[2]||"")||!r||this.rules.inline.punctuation.exec(r)){const r=[...n[0]].length-1;let i,a,o=r,s=0;const l="*"===n[0][0]?this.rules.inline.emStrongRDelimAst:this.rules.inline.emStrongRDelimUnd;for(l.lastIndex=0,e=e.slice(-1*t.length+r);null!=(n=l.exec(e));){if(i=n[1]||n[2]||n[3]||n[4]||n[5]||n[6],!i)continue;if(a=[...i].length,n[3]||n[4]){o+=a;continue}if((n[5]||n[6])&&r%3&&!((r+a)%3)){s+=a;continue}if(o-=a,o>0)continue;a=Math.min(a,a+o+s);const e=[...n[0]][0].length,l=t.slice(0,r+n.index+e+a);if(Math.min(r,a)%2){const t=l.slice(1,-1);return{type:"em",raw:l,text:t,tokens:this.lexer.inlineTokens(t)}}const c=l.slice(2,-2);return{type:"strong",raw:l,text:c,tokens:this.lexer.inlineTokens(c)}}}}codespan(t){const e=this.rules.inline.code.exec(t);if(e){let t=e[2].replace(/\n/g," ");const r=/[^ ]/.test(t),n=/^ /.test(t)&&/ $/.test(t);return r&&n&&(t=t.substring(1,t.length-1)),t=g(t,!0),{type:"codespan",raw:e[0],text:t}}}br(t){const e=this.rules.inline.br.exec(t);if(e)return{type:"br",raw:e[0]}}del(t){const e=this.rules.inline.del.exec(t);if(e)return{type:"del",raw:e[0],text:e[2],tokens:this.lexer.inlineTokens(e[2])}}autolink(t){const e=this.rules.inline.autolink.exec(t);if(e){let t,r;return"@"===e[2]?(t=g(e[1]),r="mailto:"+t):(t=g(e[1]),r=t),{type:"link",raw:e[0],text:t,href:r,tokens:[{type:"text",raw:t,text:t}]}}}url(t){let e;if(e=this.rules.inline.url.exec(t)){let t,r;if("@"===e[2])t=g(e[0]),r="mailto:"+t;else{let n;do{n=e[0],e[0]=this.rules.inline._backpedal.exec(e[0])?.[0]??""}while(n!==e[0]);t=g(e[0]),r="www."===e[1]?"http://"+e[0]:e[0]}return{type:"link",raw:e[0],text:t,href:r,tokens:[{type:"text",raw:t,text:t}]}}}inlineText(t){const e=this.rules.inline.text.exec(t);if(e){let t;return t=this.lexer.state.inRawBlock?e[0]:g(e[0]),{type:"text",raw:e[0],text:t}}}}const S=/^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/,A=/(?:[*+-]|\d{1,9}[.)])/,T=x(/^(?!bull |blockCode|fences|blockquote|heading|html)((?:.|\n(?!\s*?\n|bull |blockCode|fences|blockquote|heading|html))+?)\n {0,3}(=+|-+) *(?:\n+|$)/).replace(/bull/g,A).replace(/blockCode/g,/ {4}/).replace(/fences/g,/ {0,3}(?:`{3,}|~{3,})/).replace(/blockquote/g,/ {0,3}>/).replace(/heading/g,/ {0,3}#{1,6}/).replace(/html/g,/ {0,3}<[^\n>]+>\n/).getRegex(),M=/^([^\n]+(?:\n(?!hr|heading|lheading|blockquote|fences|list|html|table| +\n)[^\n]+)*)/,B=/(?!\s*\])(?:\\.|[^\[\]\\])+/,L=x(/^ {0,3}\[(label)\]: *(?:\n *)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n *)?| *\n *)(title))? *(?:\n+|$)/).replace("label",B).replace("title",/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/).getRegex(),F=x(/^( {0,3}bull)([ \t][^\n]+?)?(?:\n|$)/).replace(/bull/g,A).getRegex(),$="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",E=/<!--(?:-?>|[\s\S]*?(?:-->|$))/,N=x("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>\\n*|$)|<![A-Z][\\s\\S]*?(?:>\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n *)+\\n|$)|<(?!script|pre|style|textarea)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$)|</(?!script|pre|style|textarea)[a-z][\\w-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n *)+\\n|$))","i").replace("comment",E).replace("tag",$).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),D=x(M).replace("hr",S).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("|table","").replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",$).getRegex(),j={blockquote:x(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph",D).getRegex(),code:/^( {4}[^\n]+(?:\n(?: *(?:\n|$))*)?)+/,def:L,fences:/^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/,heading:/^ {0,3}(#{1,6})(?=\s|$)(.*)(?:\n+|$)/,hr:S,html:N,lheading:T,list:F,newline:/^(?: *(?:\n|$))+/,paragraph:D,table:k,text:/^[^\n]+/},I=x("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr",S).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("blockquote"," {0,3}>").replace("code"," {4}[^\\n]").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",$).getRegex(),O={...j,table:I,paragraph:x(M).replace("hr",S).replace("heading"," {0,3}#{1,6}(?:\\s|$)").replace("|lheading","").replace("table",I).replace("blockquote"," {0,3}>").replace("fences"," {0,3}(?:`{3,}(?=[^`\\n]*\\n)|~{3,})[^\\n]*\\n").replace("list"," {0,3}(?:[*+-]|1[.)]) ").replace("html","</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag",$).getRegex()},R={...j,html:x("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:\"[^\"]*\"|'[^']*'|\\s[^'\"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",E).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/,heading:/^(#{1,6})(.*)(?:\n+|$)/,fences:k,lheading:/^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/,paragraph:x(M).replace("hr",S).replace("heading"," *#{1,6} *[^\n]").replace("lheading",T).replace("|table","").replace("blockquote"," {0,3}>").replace("|fences","").replace("|list","").replace("|html","").replace("|tag","").getRegex()},P=/^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/,z=/^( {2,}|\\)\n(?!\s*$)/,K="\\p{P}\\p{S}",q=x(/^((?![*_])[\spunctuation])/,"u").replace(/punctuation/g,K).getRegex(),W=x(/^(?:\*+(?:((?!\*)[punct])|[^\s*]))|^_+(?:((?!_)[punct])|([^\s_]))/,"u").replace(/punct/g,K).getRegex(),H=x("^[^_*]*?__[^_*]*?\\*[^_*]*?(?=__)|[^*]+(?=[^*])|(?!\\*)[punct](\\*+)(?=[\\s]|$)|[^punct\\s](\\*+)(?!\\*)(?=[punct\\s]|$)|(?!\\*)[punct\\s](\\*+)(?=[^punct\\s])|[\\s](\\*+)(?!\\*)(?=[punct])|(?!\\*)[punct](\\*+)(?!\\*)(?=[punct])|[^punct\\s](\\*+)(?=[^punct\\s])","gu").replace(/punct/g,K).getRegex(),U=x("^[^_*]*?\\*\\*[^_*]*?_[^_*]*?(?=\\*\\*)|[^_]+(?=[^_])|(?!_)[punct](_+)(?=[\\s]|$)|[^punct\\s](_+)(?!_)(?=[punct\\s]|$)|(?!_)[punct\\s](_+)(?=[^punct\\s])|[\\s](_+)(?!_)(?=[punct])|(?!_)[punct](_+)(?!_)(?=[punct])","gu").replace(/punct/g,K).getRegex(),Y=x(/\\([punct])/,"gu").replace(/punct/g,K).getRegex(),V=x(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme",/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email",/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex(),G=x(E).replace("(?:--\x3e|$)","--\x3e").getRegex(),Z=x("^comment|^</[a-zA-Z][\\w:-]*\\s*>|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment",G).replace("attribute",/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex(),X=/(?:\[(?:\\.|[^\[\]\\])*\]|\\.|`[^`]*`|[^\[\]\\`])*?/,Q=x(/^!?\[(label)\]\(\s*(href)(?:\s+(title))?\s*\)/).replace("label",X).replace("href",/<(?:\\.|[^\n<>\\])+>|[^\s\x00-\x1f]*/).replace("title",/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex(),J=x(/^!?\[(label)\]\[(ref)\]/).replace("label",X).replace("ref",B).getRegex(),tt=x(/^!?\[(ref)\](?:\[\])?/).replace("ref",B).getRegex(),et={_backpedal:k,anyPunctuation:Y,autolink:V,blockSkip:/\[[^[\]]*?\]\([^\(\)]*?\)|`[^`]*?`|<[^<>]*?>/g,br:z,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,del:k,emStrongLDelim:W,emStrongRDelimAst:H,emStrongRDelimUnd:U,escape:P,link:Q,nolink:tt,punctuation:q,reflink:J,reflinkSearch:x("reflink|nolink(?!\\()","g").replace("reflink",J).replace("nolink",tt).getRegex(),tag:Z,text:/^(`+|[^`])(?:(?= {2,}\n)|[\s\S]*?(?:(?=[\\<!\[`*_]|\b_|$)|[^ ](?= {2,}\n)))/,url:k},rt={...et,link:x(/^!?\[(label)\]\((.*?)\)/).replace("label",X).getRegex(),reflink:x(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",X).getRegex()},nt={...et,escape:x(P).replace("])","~|])").getRegex(),url:x(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,"i").replace("email",/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/).getRegex(),_backpedal:/(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/,del:/^(~~?)(?=[^\s~])([\s\S]*?[^\s~])\1(?=[^~]|$)/,text:/^([`~]+|[^`~])(?:(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|https?:\/\/|ftp:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/},it={...nt,br:x(z).replace("{2,}","*").getRegex(),text:x(nt.text).replace("\\b_","\\b_| {2,}\\n").replace(/\{2,\}/g,"*").getRegex()},at={normal:j,gfm:O,pedantic:R},ot={normal:et,gfm:nt,breaks:it,pedantic:rt};class st{tokens;options;state;tokenizer;inlineQueue;constructor(t){this.tokens=[],this.tokens.links=Object.create(null),this.options=t||s,this.options.tokenizer=this.options.tokenizer||new v,this.tokenizer=this.options.tokenizer,this.tokenizer.options=this.options,this.tokenizer.lexer=this,this.inlineQueue=[],this.state={inLink:!1,inRawBlock:!1,top:!0};const e={block:at.normal,inline:ot.normal};this.options.pedantic?(e.block=at.pedantic,e.inline=ot.pedantic):this.options.gfm&&(e.block=at.gfm,this.options.breaks?e.inline=ot.breaks:e.inline=ot.gfm),this.tokenizer.rules=e}static get rules(){return{block:at,inline:ot}}static lex(t,e){return new st(e).lex(t)}static lexInline(t,e){return new st(e).inlineTokens(t)}lex(t){t=t.replace(/\r\n|\r/g,"\n"),this.blockTokens(t,this.tokens);for(let e=0;e<this.inlineQueue.length;e++){const t=this.inlineQueue[e];this.inlineTokens(t.src,t.tokens)}return this.inlineQueue=[],this.tokens}blockTokens(t,e=[],r=!1){let n,i,a;for(t=this.options.pedantic?t.replace(/\t/g," ").replace(/^ +$/gm,""):t.replace(/^( *)(\t+)/gm,((t,e,r)=>e+" ".repeat(r.length)));t;)if(!(this.options.extensions&&this.options.extensions.block&&this.options.extensions.block.some((r=>!!(n=r.call({lexer:this},t,e))&&(t=t.substring(n.raw.length),e.push(n),!0)))))if(n=this.tokenizer.space(t))t=t.substring(n.raw.length),1===n.raw.length&&e.length>0?e[e.length-1].raw+="\n":e.push(n);else if(n=this.tokenizer.code(t))t=t.substring(n.raw.length),i=e[e.length-1],!i||"paragraph"!==i.type&&"text"!==i.type?e.push(n):(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue[this.inlineQueue.length-1].src=i.text);else if(n=this.tokenizer.fences(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.heading(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.hr(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.blockquote(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.list(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.html(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.def(t))t=t.substring(n.raw.length),i=e[e.length-1],!i||"paragraph"!==i.type&&"text"!==i.type?this.tokens.links[n.tag]||(this.tokens.links[n.tag]={href:n.href,title:n.title}):(i.raw+="\n"+n.raw,i.text+="\n"+n.raw,this.inlineQueue[this.inlineQueue.length-1].src=i.text);else if(n=this.tokenizer.table(t))t=t.substring(n.raw.length),e.push(n);else if(n=this.tokenizer.lheading(t))t=t.substring(n.raw.length),e.push(n);else{if(a=t,this.options.extensions&&this.options.extensions.startBlock){let e=1/0;const r=t.slice(1);let n;this.options.extensions.startBlock.forEach((t=>{n=t.call({lexer:this},r),"number"==typeof n&&n>=0&&(e=Math.min(e,n))})),e<1/0&&e>=0&&(a=t.substring(0,e+1))}if(this.state.top&&(n=this.tokenizer.paragraph(a)))i=e[e.length-1],r&&"paragraph"===i?.type?(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=i.text):e.push(n),r=a.length!==t.length,t=t.substring(n.raw.length);else if(n=this.tokenizer.text(t))t=t.substring(n.raw.length),i=e[e.length-1],i&&"text"===i.type?(i.raw+="\n"+n.raw,i.text+="\n"+n.text,this.inlineQueue.pop(),this.inlineQueue[this.inlineQueue.length-1].src=i.text):e.push(n);else if(t){const e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}return this.state.top=!0,e}inline(t,e=[]){return this.inlineQueue.push({src:t,tokens:e}),e}inlineTokens(t,e=[]){let r,n,i,a,o,s,l=t;if(this.tokens.links){const t=Object.keys(this.tokens.links);if(t.length>0)for(;null!=(a=this.tokenizer.rules.inline.reflinkSearch.exec(l));)t.includes(a[0].slice(a[0].lastIndexOf("[")+1,-1))&&(l=l.slice(0,a.index)+"["+"a".repeat(a[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.reflinkSearch.lastIndex))}for(;null!=(a=this.tokenizer.rules.inline.blockSkip.exec(l));)l=l.slice(0,a.index)+"["+"a".repeat(a[0].length-2)+"]"+l.slice(this.tokenizer.rules.inline.blockSkip.lastIndex);for(;null!=(a=this.tokenizer.rules.inline.anyPunctuation.exec(l));)l=l.slice(0,a.index)+"++"+l.slice(this.tokenizer.rules.inline.anyPunctuation.lastIndex);for(;t;)if(o||(s=""),o=!1,!(this.options.extensions&&this.options.extensions.inline&&this.options.extensions.inline.some((n=>!!(r=n.call({lexer:this},t,e))&&(t=t.substring(r.raw.length),e.push(r),!0)))))if(r=this.tokenizer.escape(t))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.tag(t))t=t.substring(r.raw.length),n=e[e.length-1],n&&"text"===r.type&&"text"===n.type?(n.raw+=r.raw,n.text+=r.text):e.push(r);else if(r=this.tokenizer.link(t))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.reflink(t,this.tokens.links))t=t.substring(r.raw.length),n=e[e.length-1],n&&"text"===r.type&&"text"===n.type?(n.raw+=r.raw,n.text+=r.text):e.push(r);else if(r=this.tokenizer.emStrong(t,l,s))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.codespan(t))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.br(t))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.del(t))t=t.substring(r.raw.length),e.push(r);else if(r=this.tokenizer.autolink(t))t=t.substring(r.raw.length),e.push(r);else if(this.state.inLink||!(r=this.tokenizer.url(t))){if(i=t,this.options.extensions&&this.options.extensions.startInline){let e=1/0;const r=t.slice(1);let n;this.options.extensions.startInline.forEach((t=>{n=t.call({lexer:this},r),"number"==typeof n&&n>=0&&(e=Math.min(e,n))})),e<1/0&&e>=0&&(i=t.substring(0,e+1))}if(r=this.tokenizer.inlineText(i))t=t.substring(r.raw.length),"_"!==r.raw.slice(-1)&&(s=r.raw.slice(-1)),o=!0,n=e[e.length-1],n&&"text"===n.type?(n.raw+=r.raw,n.text+=r.text):e.push(r);else if(t){const e="Infinite loop on byte: "+t.charCodeAt(0);if(this.options.silent){console.error(e);break}throw new Error(e)}}else t=t.substring(r.raw.length),e.push(r);return e}}class lt{options;parser;constructor(t){this.options=t||s}space(t){return""}code({text:t,lang:e,escaped:r}){const n=(e||"").match(/^\S*/)?.[0],i=t.replace(/\n$/,"")+"\n";return n?'<pre><code class="language-'+g(n)+'">'+(r?i:g(i,!0))+"</code></pre>\n":"<pre><code>"+(r?i:g(i,!0))+"</code></pre>\n"}blockquote({tokens:t}){return`<blockquote>\n${this.parser.parse(t)}</blockquote>\n`}html({text:t}){return t}heading({tokens:t,depth:e}){return`<h${e}>${this.parser.parseInline(t)}</h${e}>\n`}hr(t){return"<hr>\n"}list(t){const e=t.ordered,r=t.start;let n="";for(let a=0;a<t.items.length;a++){const e=t.items[a];n+=this.listitem(e)}const i=e?"ol":"ul";return"<"+i+(e&&1!==r?' start="'+r+'"':"")+">\n"+n+"</"+i+">\n"}listitem(t){let e="";if(t.task){const r=this.checkbox({checked:!!t.checked});t.loose?t.tokens.length>0&&"paragraph"===t.tokens[0].type?(t.tokens[0].text=r+" "+t.tokens[0].text,t.tokens[0].tokens&&t.tokens[0].tokens.length>0&&"text"===t.tokens[0].tokens[0].type&&(t.tokens[0].tokens[0].text=r+" "+t.tokens[0].tokens[0].text)):t.tokens.unshift({type:"text",raw:r+" ",text:r+" "}):e+=r+" "}return e+=this.parser.parse(t.tokens,!!t.loose),`<li>${e}</li>\n`}checkbox({checked:t}){return"<input "+(t?'checked="" ':"")+'disabled="" type="checkbox">'}paragraph({tokens:t}){return`<p>${this.parser.parseInline(t)}</p>\n`}table(t){let e="",r="";for(let i=0;i<t.header.length;i++)r+=this.tablecell(t.header[i]);e+=this.tablerow({text:r});let n="";for(let i=0;i<t.rows.length;i++){const e=t.rows[i];r="";for(let t=0;t<e.length;t++)r+=this.tablecell(e[t]);n+=this.tablerow({text:r})}return n&&(n=`<tbody>${n}</tbody>`),"<table>\n<thead>\n"+e+"</thead>\n"+n+"</table>\n"}tablerow({text:t}){return`<tr>\n${t}</tr>\n`}tablecell(t){const e=this.parser.parseInline(t.tokens),r=t.header?"th":"td";return(t.align?`<${r} align="${t.align}">`:`<${r}>`)+e+`</${r}>\n`}strong({tokens:t}){return`<strong>${this.parser.parseInline(t)}</strong>`}em({tokens:t}){return`<em>${this.parser.parseInline(t)}</em>`}codespan({text:t}){return`<code>${t}</code>`}br(t){return"<br>"}del({tokens:t}){return`<del>${this.parser.parseInline(t)}</del>`}link({href:t,title:e,tokens:r}){const n=this.parser.parseInline(r),i=b(t);if(null===i)return n;let a='<a href="'+(t=i)+'"';return e&&(a+=' title="'+e+'"'),a+=">"+n+"</a>",a}image({href:t,title:e,text:r}){const n=b(t);if(null===n)return r;let i=`<img src="${t=n}" alt="${r}"`;return e&&(i+=` title="${e}"`),i+=">",i}text(t){return"tokens"in t&&t.tokens?this.parser.parseInline(t.tokens):t.text}}class ct{strong({text:t}){return t}em({text:t}){return t}codespan({text:t}){return t}del({text:t}){return t}html({text:t}){return t}text({text:t}){return t}link({text:t}){return""+t}image({text:t}){return""+t}br(){return""}}class ht{options;renderer;textRenderer;constructor(t){this.options=t||s,this.options.renderer=this.options.renderer||new lt,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new ct}static parse(t,e){return new ht(e).parse(t)}static parseInline(t,e){return new ht(e).parseInline(t)}parse(t,e=!0){let r="";for(let n=0;n<t.length;n++){const i=t[n];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const t=i,e=this.options.extensions.renderers[t.type].call({parser:this},t);if(!1!==e||!["space","hr","heading","code","table","blockquote","list","html","paragraph","text"].includes(t.type)){r+=e||"";continue}}const a=i;switch(a.type){case"space":r+=this.renderer.space(a);continue;case"hr":r+=this.renderer.hr(a);continue;case"heading":r+=this.renderer.heading(a);continue;case"code":r+=this.renderer.code(a);continue;case"table":r+=this.renderer.table(a);continue;case"blockquote":r+=this.renderer.blockquote(a);continue;case"list":r+=this.renderer.list(a);continue;case"html":r+=this.renderer.html(a);continue;case"paragraph":r+=this.renderer.paragraph(a);continue;case"text":{let i=a,o=this.renderer.text(i);for(;n+1<t.length&&"text"===t[n+1].type;)i=t[++n],o+="\n"+this.renderer.text(i);r+=e?this.renderer.paragraph({type:"paragraph",raw:o,text:o,tokens:[{type:"text",raw:o,text:o}]}):o;continue}default:{const t='Token with "'+a.type+'" type was not found.';if(this.options.silent)return console.error(t),"";throw new Error(t)}}}return r}parseInline(t,e){e=e||this.renderer;let r="";for(let n=0;n<t.length;n++){const i=t[n];if(this.options.extensions&&this.options.extensions.renderers&&this.options.extensions.renderers[i.type]){const t=this.options.extensions.renderers[i.type].call({parser:this},i);if(!1!==t||!["escape","html","link","image","strong","em","codespan","br","del","text"].includes(i.type)){r+=t||"";continue}}const a=i;switch(a.type){case"escape":case"text":r+=e.text(a);break;case"html":r+=e.html(a);break;case"link":r+=e.link(a);break;case"image":r+=e.image(a);break;case"strong":r+=e.strong(a);break;case"em":r+=e.em(a);break;case"codespan":r+=e.codespan(a);break;case"br":r+=e.br(a);break;case"del":r+=e.del(a);break;default:{const t='Token with "'+a.type+'" type was not found.';if(this.options.silent)return console.error(t),"";throw new Error(t)}}}return r}}class ut{options;constructor(t){this.options=t||s}static passThroughHooks=new Set(["preprocess","postprocess","processAllTokens"]);preprocess(t){return t}postprocess(t){return t}processAllTokens(t){return t}}const dt=new class{defaults={async:!1,breaks:!1,extensions:null,gfm:!0,hooks:null,pedantic:!1,renderer:null,silent:!1,tokenizer:null,walkTokens:null};options=this.setOptions;parse=this.#t(st.lex,ht.parse);parseInline=this.#t(st.lexInline,ht.parseInline);Parser=ht;Renderer=lt;TextRenderer=ct;Lexer=st;Tokenizer=v;Hooks=ut;constructor(...t){this.use(...t)}walkTokens(t,e){let r=[];for(const n of t)switch(r=r.concat(e.call(this,n)),n.type){case"table":{const t=n;for(const n of t.header)r=r.concat(this.walkTokens(n.tokens,e));for(const n of t.rows)for(const t of n)r=r.concat(this.walkTokens(t.tokens,e));break}case"list":{const t=n;r=r.concat(this.walkTokens(t.items,e));break}default:{const t=n;this.defaults.extensions?.childTokens?.[t.type]?this.defaults.extensions.childTokens[t.type].forEach((n=>{const i=t[n].flat(1/0);r=r.concat(this.walkTokens(i,e))})):t.tokens&&(r=r.concat(this.walkTokens(t.tokens,e)))}}return r}use(...t){const e=this.defaults.extensions||{renderers:{},childTokens:{}};return t.forEach((t=>{const r={...t};if(r.async=this.defaults.async||r.async||!1,t.extensions&&(t.extensions.forEach((t=>{if(!t.name)throw new Error("extension name required");if("renderer"in t){const r=e.renderers[t.name];e.renderers[t.name]=r?function(...e){let n=t.renderer.apply(this,e);return!1===n&&(n=r.apply(this,e)),n}:t.renderer}if("tokenizer"in t){if(!t.level||"block"!==t.level&&"inline"!==t.level)throw new Error("extension level must be 'block' or 'inline'");const r=e[t.level];r?r.unshift(t.tokenizer):e[t.level]=[t.tokenizer],t.start&&("block"===t.level?e.startBlock?e.startBlock.push(t.start):e.startBlock=[t.start]:"inline"===t.level&&(e.startInline?e.startInline.push(t.start):e.startInline=[t.start]))}"childTokens"in t&&t.childTokens&&(e.childTokens[t.name]=t.childTokens)})),r.extensions=e),t.renderer){const e=this.defaults.renderer||new lt(this.defaults);for(const r in t.renderer){if(!(r in e))throw new Error(`renderer '${r}' does not exist`);if(["options","parser"].includes(r))continue;const n=r;let i=t.renderer[n];t.useNewRenderer||(i=this.#e(i,n,e));const a=e[n];e[n]=(...t)=>{let r=i.apply(e,t);return!1===r&&(r=a.apply(e,t)),r||""}}r.renderer=e}if(t.tokenizer){const e=this.defaults.tokenizer||new v(this.defaults);for(const r in t.tokenizer){if(!(r in e))throw new Error(`tokenizer '${r}' does not exist`);if(["options","rules","lexer"].includes(r))continue;const n=r,i=t.tokenizer[n],a=e[n];e[n]=(...t)=>{let r=i.apply(e,t);return!1===r&&(r=a.apply(e,t)),r}}r.tokenizer=e}if(t.hooks){const e=this.defaults.hooks||new ut;for(const r in t.hooks){if(!(r in e))throw new Error(`hook '${r}' does not exist`);if("options"===r)continue;const n=r,i=t.hooks[n],a=e[n];ut.passThroughHooks.has(r)?e[n]=t=>{if(this.defaults.async)return Promise.resolve(i.call(e,t)).then((t=>a.call(e,t)));const r=i.call(e,t);return a.call(e,r)}:e[n]=(...t)=>{let r=i.apply(e,t);return!1===r&&(r=a.apply(e,t)),r}}r.hooks=e}if(t.walkTokens){const e=this.defaults.walkTokens,n=t.walkTokens;r.walkTokens=function(t){let r=[];return r.push(n.call(this,t)),e&&(r=r.concat(e.call(this,t))),r}}this.defaults={...this.defaults,...r}})),this}#e(t,e,r){switch(e){case"heading":return function(n){return n.type&&n.type===e?t.call(this,r.parser.parseInline(n.tokens),n.depth,function(t){return t.replace(m,((t,e)=>"colon"===(e=e.toLowerCase())?":":"#"===e.charAt(0)?"x"===e.charAt(1)?String.fromCharCode(parseInt(e.substring(2),16)):String.fromCharCode(+e.substring(1)):""))}(r.parser.parseInline(n.tokens,r.parser.textRenderer))):t.apply(this,arguments)};case"code":return function(r){return r.type&&r.type===e?t.call(this,r.text,r.lang,!!r.escaped):t.apply(this,arguments)};case"table":return function(r){if(!r.type||r.type!==e)return t.apply(this,arguments);let n="",i="";for(let t=0;t<r.header.length;t++)i+=this.tablecell({text:r.header[t].text,tokens:r.header[t].tokens,header:!0,align:r.align[t]});n+=this.tablerow({text:i});let a="";for(let t=0;t<r.rows.length;t++){const e=r.rows[t];i="";for(let t=0;t<e.length;t++)i+=this.tablecell({text:e[t].text,tokens:e[t].tokens,header:!1,align:r.align[t]});a+=this.tablerow({text:i})}return t.call(this,n,a)};case"blockquote":return function(r){if(!r.type||r.type!==e)return t.apply(this,arguments);const n=this.parser.parse(r.tokens);return t.call(this,n)};case"list":return function(r){if(!r.type||r.type!==e)return t.apply(this,arguments);const n=r.ordered,i=r.start,a=r.loose;let o="";for(let t=0;t<r.items.length;t++){const e=r.items[t],n=e.checked,i=e.task;let s="";if(e.task){const t=this.checkbox({checked:!!n});a?e.tokens.length>0&&"paragraph"===e.tokens[0].type?(e.tokens[0].text=t+" "+e.tokens[0].text,e.tokens[0].tokens&&e.tokens[0].tokens.length>0&&"text"===e.tokens[0].tokens[0].type&&(e.tokens[0].tokens[0].text=t+" "+e.tokens[0].tokens[0].text)):e.tokens.unshift({type:"text",text:t+" "}):s+=t+" "}s+=this.parser.parse(e.tokens,a),o+=this.listitem({type:"list_item",raw:s,text:s,task:i,checked:!!n,loose:a,tokens:e.tokens})}return t.call(this,o,n,i)};case"html":return function(r){return r.type&&r.type===e?t.call(this,r.text,r.block):t.apply(this,arguments)};case"paragraph":case"strong":case"em":case"del":return function(r){return r.type&&r.type===e?t.call(this,this.parser.parseInline(r.tokens)):t.apply(this,arguments)};case"escape":case"codespan":case"text":return function(r){return r.type&&r.type===e?t.call(this,r.text):t.apply(this,arguments)};case"link":return function(r){return r.type&&r.type===e?t.call(this,r.href,r.title,this.parser.parseInline(r.tokens)):t.apply(this,arguments)};case"image":return function(r){return r.type&&r.type===e?t.call(this,r.href,r.title,r.text):t.apply(this,arguments)}}return t}setOptions(t){return this.defaults={...this.defaults,...t},this}lexer(t,e){return st.lex(t,e??this.defaults)}parser(t,e){return ht.parse(t,e??this.defaults)}#t(t,e){return(r,n)=>{const i={...n},a={...this.defaults,...i};!0===this.defaults.async&&!1===i.async&&(a.silent||console.warn("marked(): The async option was set to true by an extension. The async: false option sent to parse will be ignored."),a.async=!0);const o=this.#r(!!a.silent,!!a.async);if(null==r)return o(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof r)return o(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(r)+", string expected"));if(a.hooks&&(a.hooks.options=a),a.async)return Promise.resolve(a.hooks?a.hooks.preprocess(r):r).then((e=>t(e,a))).then((t=>a.hooks?a.hooks.processAllTokens(t):t)).then((t=>a.walkTokens?Promise.all(this.walkTokens(t,a.walkTokens)).then((()=>t)):t)).then((t=>e(t,a))).then((t=>a.hooks?a.hooks.postprocess(t):t)).catch(o);try{a.hooks&&(r=a.hooks.preprocess(r));let n=t(r,a);a.hooks&&(n=a.hooks.processAllTokens(n)),a.walkTokens&&this.walkTokens(n,a.walkTokens);let i=e(n,a);return a.hooks&&(i=a.hooks.postprocess(i)),i}catch(s){return o(s)}}}#r(t,e){return r=>{if(r.message+="\nPlease report this to https://github.com/markedjs/marked.",t){const t="<p>An error occurred:</p><pre>"+g(r.message+"",!0)+"</pre>";return e?Promise.resolve(t):t}if(e)return Promise.reject(r);throw r}}};function pt(t,e){return dt.parse(t,e)}pt.options=pt.setOptions=function(t){return dt.setOptions(t),pt.defaults=dt.defaults,l(pt.defaults),pt},pt.getDefaults=o,pt.defaults=s,pt.use=function(...t){return dt.use(...t),pt.defaults=dt.defaults,l(pt.defaults),pt},pt.walkTokens=function(t,e){return dt.walkTokens(t,e)},pt.parseInline=dt.parseInline,pt.Parser=ht,pt.parser=ht.parse,pt.Renderer=lt,pt.TextRenderer=ct,pt.Lexer=st,pt.lexer=st.lex,pt.Tokenizer=v,pt.Hooks=ut,pt.parse=pt;pt.options,pt.setOptions,pt.use,pt.walkTokens,pt.parseInline,ht.parse,st.lex;var ft=r(60513);function gt(t,{markdownAutoWrap:e}){const r=t.replace(/<br\/>/g,"\n").replace(/\n{2,}/g,"\n"),n=(0,ft.T)(r);return!1===e?n.replace(/ /g," "):n}function mt(t,e={}){const r=gt(t,e),n=pt.lexer(r),a=[[]];let o=0;function s(t,e="normal"){if("text"===t.type){t.text.split("\n").forEach(((t,r)=>{0!==r&&(o++,a.push([])),t.split(" ").forEach((t=>{(t=t.replace(/'/g,"'"))&&a[o].push({content:t,type:e})}))}))}else"strong"===t.type||"em"===t.type?t.tokens.forEach((e=>{s(e,t.type)})):"html"===t.type&&a[o].push({content:t.text,type:"normal"})}return(0,i.K2)(s,"processNode"),n.forEach((t=>{"paragraph"===t.type?t.tokens?.forEach((t=>{s(t)})):"html"===t.type&&a[o].push({content:t.text,type:"normal"})})),a}function yt(t,{markdownAutoWrap:e}={}){const r=pt.lexer(t);function n(t){return"text"===t.type?!1===e?t.text.replace(/\n */g,"<br/>").replace(/ /g," "):t.text.replace(/\n */g,"<br/>"):"strong"===t.type?`<strong>${t.tokens?.map(n).join("")}</strong>`:"em"===t.type?`<em>${t.tokens?.map(n).join("")}</em>`:"paragraph"===t.type?`<p>${t.tokens?.map(n).join("")}</p>`:"space"===t.type?"":"html"===t.type?`${t.text}`:"escape"===t.type?t.text:`Unsupported markdown: ${t.type}`}return(0,i.K2)(n,"output"),r.map(n).join("")}function xt(t){return Intl.Segmenter?[...(new Intl.Segmenter).segment(t)].map((t=>t.segment)):[...t]}function bt(t,e){return kt(t,[],xt(e.content),e.type)}function kt(t,e,r,n){if(0===r.length)return[{content:e.join(""),type:n},{content:"",type:n}];const[i,...a]=r,o=[...e,i];return t([{content:o.join(""),type:n}])?kt(t,o,a,n):(0===e.length&&i&&(e.push(i),r.shift()),[{content:e.join(""),type:n},{content:r.join(""),type:n}])}function Ct(t,e){if(t.some((({content:t})=>t.includes("\n"))))throw new Error("splitLineToFitWidth does not support newlines in the line");return wt(t,e)}function wt(t,e,r=[],n=[]){if(0===t.length)return n.length>0&&r.push(n),r.length>0?r:[];let i="";" "===t[0].content&&(i=" ",t.shift());const a=t.shift()??{content:" ",type:"normal"},o=[...n];if(""!==i&&o.push({content:i,type:"normal"}),o.push(a),e(o))return wt(t,e,r,o);if(n.length>0)r.push(n),t.unshift(a);else if(a.content){const[n,i]=bt(e,a);r.push([n]),i.content&&t.unshift(i)}return wt(t,e,r)}function _t(t,e){e&&t.attr("style",e)}async function vt(t,e,r,n,a=!1){const o=t.append("foreignObject");o.attr("width",10*r+"px"),o.attr("height",10*r+"px");const s=o.append("xhtml:div");let l=e.label;e.label&&(0,i.Wi)(e.label)&&(l=await(0,i.VJ)(e.label.replace(i.Y2.lineBreakRegex,"\n"),(0,i.D7)()));const c=e.isNode?"nodeLabel":"edgeLabel",h=s.append("span");h.html(l),_t(h,e.labelStyle),h.attr("class",`${c} ${n}`),_t(s,e.labelStyle),s.style("display","table-cell"),s.style("white-space","nowrap"),s.style("line-height","1.5"),s.style("max-width",r+"px"),s.style("text-align","center"),s.attr("xmlns","http://www.w3.org/1999/xhtml"),a&&s.attr("class","labelBkg");let u=s.node().getBoundingClientRect();return u.width===r&&(s.style("display","table"),s.style("white-space","break-spaces"),s.style("width",r+"px"),u=s.node().getBoundingClientRect()),o.node()}function St(t,e,r){return t.append("tspan").attr("class","text-outer-tspan").attr("x",0).attr("y",e*r-.1+"em").attr("dy",r+"em")}function At(t,e,r){const n=t.append("text"),i=St(n,1,e);Bt(i,r);const a=i.node().getComputedTextLength();return n.remove(),a}function Tt(t,e,r){const n=t.append("text"),i=St(n,1,e);Bt(i,[{content:r,type:"normal"}]);const a=i.node()?.getBoundingClientRect();return a&&n.remove(),a}function Mt(t,e,r,n=!1){const a=e.append("g"),o=a.insert("rect").attr("class","background").attr("style","stroke: none"),s=a.append("text").attr("y","-10.1");let l=0;for(const c of r){const e=(0,i.K2)((e=>At(a,1.1,e)<=t),"checkWidth"),r=e(c)?[c]:Ct(c,e);for(const t of r){Bt(St(s,l,1.1),t),l++}}if(n){const t=s.node().getBBox(),e=2;return o.attr("x",t.x-e).attr("y",t.y-e).attr("width",t.width+2*e).attr("height",t.height+2*e),a.node()}return s.node()}function Bt(t,e){t.text(""),e.forEach(((e,r)=>{const n=t.append("tspan").attr("font-style","em"===e.type?"italic":"normal").attr("class","text-inner-tspan").attr("font-weight","strong"===e.type?"bold":"normal");0===r?n.text(e.content):n.text(" "+e.content)}))}function Lt(t){return t.replace(/fa[bklrs]?:fa-[\w-]+/g,(t=>`<i class='${t.replace(":"," ")}'></i>`))}(0,i.K2)(gt,"preprocessMarkdown"),(0,i.K2)(mt,"markdownToLines"),(0,i.K2)(yt,"markdownToHTML"),(0,i.K2)(xt,"splitTextToChars"),(0,i.K2)(bt,"splitWordToFitWidth"),(0,i.K2)(kt,"splitWordToFitWidthRecursion"),(0,i.K2)(Ct,"splitLineToFitWidth"),(0,i.K2)(wt,"splitLineToFitWidthRecursion"),(0,i.K2)(_t,"applyStyle"),(0,i.K2)(vt,"addHtmlSpan"),(0,i.K2)(St,"createTspan"),(0,i.K2)(At,"computeWidthOfText"),(0,i.K2)(Tt,"computeDimensionOfText"),(0,i.K2)(Mt,"createFormattedText"),(0,i.K2)(Bt,"updateTextContentAndStyles"),(0,i.K2)(Lt,"replaceIconSubstring");var Ft=(0,i.K2)((async(t,e="",{style:r="",isTitle:o=!1,classes:s="",useHtmlLabels:l=!0,isNode:c=!0,width:h=200,addSvgBackground:u=!1}={},d)=>{if(i.Rm.debug("XYZ createText",e,r,o,s,l,c,"addSvgBackground: ",u),l){const a=yt(e,d),o=Lt((0,n.Sm)(a)),l=e.replace(/\\\\/g,"\\"),p={isNode:c,label:(0,i.Wi)(e)?l:o,labelStyle:r.replace("fill:","color:")};return await vt(t,p,h,s,u)}{const n=Mt(h,t,mt(e.replace(/<br\s*\/?>/g,"<br/>").replace("<br>","<br/>"),d),!!e&&u);if(c){/stroke:/.exec(r)&&(r=r.replace("stroke:","lineColor:"));const t=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");(0,a.Ltv)(n).attr("style",t)}else{const t=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/background:/g,"fill:");(0,a.Ltv)(n).select("rect").attr("style",t.replace(/background:/g,"fill:"));const e=r.replace(/stroke:[^;]+;?/g,"").replace(/stroke-width:[^;]+;?/g,"").replace(/fill:[^;]+;?/g,"").replace(/color:/g,"fill:");(0,a.Ltv)(n).select("text").attr("style",e)}return n}}),"createText")},29196:(t,e,r)=>{"use strict";r.d(e,{r:()=>n});var n="11.4.0"},62392:(t,e,r)=>{"use strict";r.d(e,{O:()=>n});var n=(0,r(45567).K2)((({flowchart:t})=>{const e=t?.subGraphTitleMargin?.top??0,r=t?.subGraphTitleMargin?.bottom??0;return{subGraphTitleTopMargin:e,subGraphTitleBottomMargin:r,subGraphTitleTotalMargin:e+r}}),"getSubGraphTitleMargins")},52294:(t,e,r)=>{"use strict";r.d(e,{R:()=>s});var n=r(45567),i={aggregation:18,extension:18,composition:18,dependency:6,lollipop:13.5,arrow_point:4};function a(t,e){if(void 0===t||void 0===e)return{angle:0,deltaX:0,deltaY:0};t=o(t),e=o(e);const[r,n]=[t.x,t.y],[i,a]=[e.x,e.y],s=i-r,l=a-n;return{angle:Math.atan(l/s),deltaX:s,deltaY:l}}(0,n.K2)(a,"calculateDeltaAndAngle");var o=(0,n.K2)((t=>Array.isArray(t)?{x:t[0],y:t[1]}:t),"pointTransformer"),s=(0,n.K2)((t=>({x:(0,n.K2)((function(e,r,n){let s=0;const l=o(n[0]).x<o(n[n.length-1]).x?"left":"right";if(0===r&&Object.hasOwn(i,t.arrowTypeStart)){const{angle:e,deltaX:r}=a(n[0],n[1]);s=i[t.arrowTypeStart]*Math.cos(e)*(r>=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(i,t.arrowTypeEnd)){const{angle:e,deltaX:r}=a(n[n.length-1],n[n.length-2]);s=i[t.arrowTypeEnd]*Math.cos(e)*(r>=0?1:-1)}const c=Math.abs(o(e).x-o(n[n.length-1]).x),h=Math.abs(o(e).y-o(n[n.length-1]).y),u=Math.abs(o(e).x-o(n[0]).x),d=Math.abs(o(e).y-o(n[0]).y),p=i[t.arrowTypeStart],f=i[t.arrowTypeEnd];if(c<f&&c>0&&h<f){let t=f+1-c;t*="right"===l?-1:1,s-=t}if(u<p&&u>0&&d<p){let t=p+1-u;t*="right"===l?-1:1,s+=t}return o(e).x+s}),"x"),y:(0,n.K2)((function(e,r,n){let s=0;const l=o(n[0]).y<o(n[n.length-1]).y?"down":"up";if(0===r&&Object.hasOwn(i,t.arrowTypeStart)){const{angle:e,deltaY:r}=a(n[0],n[1]);s=i[t.arrowTypeStart]*Math.abs(Math.sin(e))*(r>=0?1:-1)}else if(r===n.length-1&&Object.hasOwn(i,t.arrowTypeEnd)){const{angle:e,deltaY:r}=a(n[n.length-1],n[n.length-2]);s=i[t.arrowTypeEnd]*Math.abs(Math.sin(e))*(r>=0?1:-1)}const c=Math.abs(o(e).y-o(n[n.length-1]).y),h=Math.abs(o(e).x-o(n[n.length-1]).x),u=Math.abs(o(e).y-o(n[0]).y),d=Math.abs(o(e).x-o(n[0]).x),p=i[t.arrowTypeStart],f=i[t.arrowTypeEnd];if(c<f&&c>0&&h<f){let t=f+1-c;t*="up"===l?-1:1,s-=t}if(u<p&&u>0&&d<p){let t=p+1-u;t*="up"===l?-1:1,s+=t}return o(e).y+s}),"y")})),"getLineFunctionsWithOffset")}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6912.4cd2abc1.js.LICENSE.txt b/pr-preview/pr-976/assets/js/6912.4cd2abc1.js.LICENSE.txt new file mode 100644 index 0000000000..04660fdba7 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6912.4cd2abc1.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! @license DOMPurify 3.1.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.1.6/LICENSE */ + +/*! Bundled license information: + +js-yaml/dist/js-yaml.mjs: + (*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT *) +*/ diff --git a/pr-preview/pr-976/assets/js/69ec948c.89847346.js b/pr-preview/pr-976/assets/js/69ec948c.89847346.js new file mode 100644 index 0000000000..b73e892db6 --- /dev/null +++ b/pr-preview/pr-976/assets/js/69ec948c.89847346.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3712],{75778:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-0.5/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/0.5/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/deployment.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto"},"next":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/"}}');var r=n(74848),s=n(28453);const a={},i="Workload deployment",c={},l=[{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,s.R)(),...e.components},{TabItem:n,Tabs:o}=t;return n||p("TabItem",!0),o||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,r.jsx)(t.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,r.jsxs)(t.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,r.jsx)(t.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,r.jsx)(t.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml\n"})}),"\n",(0,r.jsx)(t.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,r.jsx)(t.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,r.jsxs)(o,{groupId:"yaml-source",children:[(0,r.jsx)(n,{value:"kustomize",label:"kustomize",children:(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,r.jsx)(n,{value:"helm",label:"helm",children:(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,r.jsx)(n,{value:"copy",label:"copy",children:(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,r.jsxs)(t.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,r.jsx)(t.code,{children:"runtimeClassName: kata-cc-isolation"})," to the pod spec (pod definition or template).\nIn addition, add the Contrast Initializer as ",(0,r.jsx)(t.code,{children:"initContainers"})," to these workloads and configure the\nworkload to use the certificates written to a ",(0,r.jsx)(t.code,{children:"volumeMount"})," named ",(0,r.jsx)(t.code,{children:"tls-certs"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n runtimeClassName: kata-cc-isolation\n initContainers:\n - name: initializer\n image: "ghcr.io/edgelesssys/contrast/initializer:latest"\n env:\n - name: COORDINATOR_HOST\n value: coordinator\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n volumes:\n - name: tls-certs\n emptyDir: {}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,r.jsxs)(t.p,{children:["Run the ",(0,r.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as annotations to your\ndeployment files. A ",(0,r.jsx)(t.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"contrast generate resources/\n"})}),"\n",(0,r.jsx)(t.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,r.jsx)(t.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,r.jsx)(t.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,r.jsx)(t.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,r.jsxs)(t.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,r.jsx)(t.a,{href:"https://github.com/edgelesssys/contrast/blob/main/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,r.jsx)(t.code,{children:"kubectl port-forward"}),"."]}),(0,r.jsxs)(t.p,{children:["Upstream tracking issue: ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,r.jsx)(t.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,r.jsx)(t.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,r.jsx)(t.p,{children:"After this step, the Coordinator will start issuing TLS certs to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,r.jsx)(t.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,r.jsxs)(t.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,r.jsx)(t.code,{children:"verify"})," command."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsxs)(t.p,{children:["The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh\nroot certificate and the history of manifests into the ",(0,r.jsx)(t.code,{children:"verify/"})," directory. In addition, the policies referenced\nin the manifest are also written to the directory."]}),"\n",(0,r.jsx)(t.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,r.jsxs)(t.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,r.jsx)(t.code,{children:"mesh-root.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\ntimeout 30s bash -c 'until kubectl get service/${MY_SERVICE} --output=jsonpath='{.status.loadBalancer}' | grep \"ingress\"; do sleep 2 ; done'\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,r.jsxs)(t.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,r.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh root certificate with throw the following error:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-root.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,r.jsxs)(t.p,{children:["Using ",(0,r.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,r.jsx)(t.code,{children:"mesh-root.pem"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-root.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var o=n(96540);const r={},s=o.createContext(r);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6a46f748.9218759d.js b/pr-preview/pr-976/assets/js/6a46f748.9218759d.js new file mode 100644 index 0000000000..5e1047f1c3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/6a46f748.9218759d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6240],{42508:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/versioned_docs/version-0.8/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/architecture/observability.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/certificates"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.8/features-limitations"}}');var s=r(74848),i=r(28453);const o={},c="Observability",a={},d=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function h(e){const t={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator exports gRPC metrics under the prefix ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_"}),".\nThese metrics are labeled with the gRPC service name and method name.\nMetrics of interest include ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handled_total"}),", which counts\nthe number of requests by return code, and\n",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handling_seconds_bucket"}),", which produces a histogram of",(0,s.jsx)(t.br,{}),"\n","request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["The gRPC service ",(0,s.jsx)(t.code,{children:"userapi.UserAPI"})," records metrics for the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"meshapi.MeshAPI"})," service records metrics for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"}),", which\ngets called by the ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>c});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/6fc50b39.46b4da2f.js b/pr-preview/pr-976/assets/js/6fc50b39.46b4da2f.js new file mode 100644 index 0000000000..b5d2a4ac5d --- /dev/null +++ b/pr-preview/pr-976/assets/js/6fc50b39.46b4da2f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4213],{3669:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-0.8/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/getting-started/install.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.8/basics/features"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup"}}');var r=s(74848),a=s(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.8.1/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>o,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function o(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7032.dded9666.js b/pr-preview/pr-976/assets/js/7032.dded9666.js new file mode 100644 index 0000000000..3b31b9717d --- /dev/null +++ b/pr-preview/pr-976/assets/js/7032.dded9666.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7032],{39676:(t,e,a)=>{a.d(e,{m:()=>s});var r=a(45567),s=class{constructor(t){this.init=t,this.records=this.init()}static{(0,r.K2)(this,"ImperativeState")}reset(){this.records=this.init()}}},59347:(t,e,a)=>{a.d(e,{CP:()=>l,HT:()=>h,PB:()=>d,aC:()=>c,lC:()=>n,m:()=>o,tk:()=>i});var r=a(45567),s=a(16750),i=(0,r.K2)(((t,e)=>{const a=t.append("rect");if(a.attr("x",e.x),a.attr("y",e.y),a.attr("fill",e.fill),a.attr("stroke",e.stroke),a.attr("width",e.width),a.attr("height",e.height),e.name&&a.attr("name",e.name),e.rx&&a.attr("rx",e.rx),e.ry&&a.attr("ry",e.ry),void 0!==e.attrs)for(const r in e.attrs)a.attr(r,e.attrs[r]);return e.class&&a.attr("class",e.class),a}),"drawRect"),n=(0,r.K2)(((t,e)=>{const a={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};i(t,a).lower()}),"drawBackgroundRect"),o=(0,r.K2)(((t,e)=>{const a=e.text.replace(r.H1," "),s=t.append("text");s.attr("x",e.x),s.attr("y",e.y),s.attr("class","legend"),s.style("text-anchor",e.anchor),e.class&&s.attr("class",e.class);const i=s.append("tspan");return i.attr("x",e.x+2*e.textMargin),i.text(a),s}),"drawText"),c=(0,r.K2)(((t,e,a,r)=>{const i=t.append("image");i.attr("x",e),i.attr("y",a);const n=(0,s.J)(r);i.attr("xlink:href",n)}),"drawImage"),l=(0,r.K2)(((t,e,a,r)=>{const i=t.append("use");i.attr("x",e),i.attr("y",a);const n=(0,s.J)(r);i.attr("xlink:href",`#${n}`)}),"drawEmbeddedImage"),d=(0,r.K2)((()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0})),"getNoteRect"),h=(0,r.K2)((()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})),"getTextObj")},7032:(t,e,a)=>{a.d(e,{diagram:()=>Ut});var r=a(59347),s=a(39676),i=a(85039),n=a(45567),o=a(20007),c=a(16750),l=function(){var t=(0,n.K2)((function(t,e,a,r){for(a=a||{},r=t.length;r--;a[t[r]]=e);return a}),"o"),e=[1,2],a=[1,3],r=[1,4],s=[2,4],i=[1,9],o=[1,11],c=[1,13],l=[1,14],d=[1,16],h=[1,17],p=[1,18],g=[1,24],u=[1,25],x=[1,26],y=[1,27],m=[1,28],b=[1,29],T=[1,30],f=[1,31],E=[1,32],w=[1,33],I=[1,34],L=[1,35],_=[1,36],P=[1,37],k=[1,38],A=[1,39],v=[1,41],N=[1,42],M=[1,43],D=[1,44],O=[1,45],S=[1,46],K=[1,4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,48,49,50,52,53,54,59,60,61,62,70],R=[4,5,16,50,52,53],Y=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],C=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,49,50,52,53,54,59,60,61,62,70],B=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,48,50,52,53,54,59,60,61,62,70],$=[4,5,13,14,16,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,47,50,52,53,54,59,60,61,62,70],V=[68,69,70],F=[1,122],W={trace:(0,n.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,box_section:10,box_line:11,participant_statement:12,create:13,box:14,restOfLine:15,end:16,signal:17,autonumber:18,NUM:19,off:20,activate:21,actor:22,deactivate:23,note_statement:24,links_statement:25,link_statement:26,properties_statement:27,details_statement:28,title:29,legacy_title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,loop:36,rect:37,opt:38,alt:39,else_sections:40,par:41,par_sections:42,par_over:43,critical:44,option_sections:45,break:46,option:47,and:48,else:49,participant:50,AS:51,participant_actor:52,destroy:53,note:54,placement:55,text2:56,over:57,actor_pair:58,links:59,link:60,properties:61,details:62,spaceList:63,",":64,left_of:65,right_of:66,signaltype:67,"+":68,"-":69,ACTOR:70,SOLID_OPEN_ARROW:71,DOTTED_OPEN_ARROW:72,SOLID_ARROW:73,BIDIRECTIONAL_SOLID_ARROW:74,DOTTED_ARROW:75,BIDIRECTIONAL_DOTTED_ARROW:76,SOLID_CROSS:77,DOTTED_CROSS:78,SOLID_POINT:79,DOTTED_POINT:80,TXT:81,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",13:"create",14:"box",15:"restOfLine",16:"end",18:"autonumber",19:"NUM",20:"off",21:"activate",23:"deactivate",29:"title",30:"legacy_title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"loop",37:"rect",38:"opt",39:"alt",41:"par",43:"par_over",44:"critical",46:"break",47:"option",48:"and",49:"else",50:"participant",51:"AS",52:"participant_actor",53:"destroy",54:"note",57:"over",59:"links",60:"link",61:"properties",62:"details",64:",",65:"left_of",66:"right_of",68:"+",69:"-",70:"ACTOR",71:"SOLID_OPEN_ARROW",72:"DOTTED_OPEN_ARROW",73:"SOLID_ARROW",74:"BIDIRECTIONAL_SOLID_ARROW",75:"DOTTED_ARROW",76:"BIDIRECTIONAL_DOTTED_ARROW",77:"SOLID_CROSS",78:"DOTTED_CROSS",79:"SOLID_POINT",80:"DOTTED_POINT",81:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[10,0],[10,2],[11,2],[11,1],[11,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[45,1],[45,4],[42,1],[42,4],[40,1],[40,4],[12,5],[12,3],[12,5],[12,3],[12,3],[24,4],[24,4],[25,3],[26,3],[27,3],[28,3],[63,2],[63,1],[58,3],[58,1],[55,1],[55,1],[17,5],[17,5],[17,4],[22,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[67,1],[56,1]],performAction:(0,n.K2)((function(t,e,a,r,s,i,n){var o=i.length-1;switch(s){case 3:return r.apply(i[o]),i[o];case 4:case 9:case 8:case 13:this.$=[];break;case 5:case 10:i[o-1].push(i[o]),this.$=i[o-1];break;case 6:case 7:case 11:case 12:case 62:this.$=i[o];break;case 15:i[o].type="createParticipant",this.$=i[o];break;case 16:i[o-1].unshift({type:"boxStart",boxData:r.parseBoxData(i[o-2])}),i[o-1].push({type:"boxEnd",boxText:i[o-2]}),this.$=i[o-1];break;case 18:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-2]),sequenceIndexStep:Number(i[o-1]),sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(i[o-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:r.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:r.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1].actor};break;case 23:this.$={type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-1].actor};break;case 29:r.setDiagramTitle(i[o].substring(6)),this.$=i[o].substring(6);break;case 30:r.setDiagramTitle(i[o].substring(7)),this.$=i[o].substring(7);break;case 31:this.$=i[o].trim(),r.setAccTitle(this.$);break;case 32:case 33:this.$=i[o].trim(),r.setAccDescription(this.$);break;case 34:i[o-1].unshift({type:"loopStart",loopText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.LOOP_START}),i[o-1].push({type:"loopEnd",loopText:i[o-2],signalType:r.LINETYPE.LOOP_END}),this.$=i[o-1];break;case 35:i[o-1].unshift({type:"rectStart",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_START}),i[o-1].push({type:"rectEnd",color:r.parseMessage(i[o-2]),signalType:r.LINETYPE.RECT_END}),this.$=i[o-1];break;case 36:i[o-1].unshift({type:"optStart",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_START}),i[o-1].push({type:"optEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.OPT_END}),this.$=i[o-1];break;case 37:i[o-1].unshift({type:"altStart",altText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.ALT_START}),i[o-1].push({type:"altEnd",signalType:r.LINETYPE.ALT_END}),this.$=i[o-1];break;case 38:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 39:i[o-1].unshift({type:"parStart",parText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.PAR_OVER_START}),i[o-1].push({type:"parEnd",signalType:r.LINETYPE.PAR_END}),this.$=i[o-1];break;case 40:i[o-1].unshift({type:"criticalStart",criticalText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.CRITICAL_START}),i[o-1].push({type:"criticalEnd",signalType:r.LINETYPE.CRITICAL_END}),this.$=i[o-1];break;case 41:i[o-1].unshift({type:"breakStart",breakText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_START}),i[o-1].push({type:"breakEnd",optText:r.parseMessage(i[o-2]),signalType:r.LINETYPE.BREAK_END}),this.$=i[o-1];break;case 43:this.$=i[o-3].concat([{type:"option",optionText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.CRITICAL_OPTION},i[o]]);break;case 45:this.$=i[o-3].concat([{type:"and",parText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.PAR_AND},i[o]]);break;case 47:this.$=i[o-3].concat([{type:"else",altText:r.parseMessage(i[o-1]),signalType:r.LINETYPE.ALT_ELSE},i[o]]);break;case 48:i[o-3].draw="participant",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 49:i[o-1].draw="participant",i[o-1].type="addParticipant",this.$=i[o-1];break;case 50:i[o-3].draw="actor",i[o-3].type="addParticipant",i[o-3].description=r.parseMessage(i[o-1]),this.$=i[o-3];break;case 51:i[o-1].draw="actor",i[o-1].type="addParticipant",this.$=i[o-1];break;case 52:i[o-1].type="destroyParticipant",this.$=i[o-1];break;case 53:this.$=[i[o-1],{type:"addNote",placement:i[o-2],actor:i[o-1].actor,text:i[o]}];break;case 54:i[o-2]=[].concat(i[o-1],i[o-1]).slice(0,2),i[o-2][0]=i[o-2][0].actor,i[o-2][1]=i[o-2][1].actor,this.$=[i[o-1],{type:"addNote",placement:r.PLACEMENT.OVER,actor:i[o-2].slice(0,2),text:i[o]}];break;case 55:this.$=[i[o-1],{type:"addLinks",actor:i[o-1].actor,text:i[o]}];break;case 56:this.$=[i[o-1],{type:"addALink",actor:i[o-1].actor,text:i[o]}];break;case 57:this.$=[i[o-1],{type:"addProperties",actor:i[o-1].actor,text:i[o]}];break;case 58:this.$=[i[o-1],{type:"addDetails",actor:i[o-1].actor,text:i[o]}];break;case 61:this.$=[i[o-2],i[o]];break;case 63:this.$=r.PLACEMENT.LEFTOF;break;case 64:this.$=r.PLACEMENT.RIGHTOF;break;case 65:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o],activate:!0},{type:"activeStart",signalType:r.LINETYPE.ACTIVE_START,actor:i[o-1].actor}];break;case 66:this.$=[i[o-4],i[o-1],{type:"addMessage",from:i[o-4].actor,to:i[o-1].actor,signalType:i[o-3],msg:i[o]},{type:"activeEnd",signalType:r.LINETYPE.ACTIVE_END,actor:i[o-4].actor}];break;case 67:this.$=[i[o-3],i[o-1],{type:"addMessage",from:i[o-3].actor,to:i[o-1].actor,signalType:i[o-2],msg:i[o]}];break;case 68:this.$={type:"addParticipant",actor:i[o]};break;case 69:this.$=r.LINETYPE.SOLID_OPEN;break;case 70:this.$=r.LINETYPE.DOTTED_OPEN;break;case 71:this.$=r.LINETYPE.SOLID;break;case 72:this.$=r.LINETYPE.BIDIRECTIONAL_SOLID;break;case 73:this.$=r.LINETYPE.DOTTED;break;case 74:this.$=r.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 75:this.$=r.LINETYPE.SOLID_CROSS;break;case 76:this.$=r.LINETYPE.DOTTED_CROSS;break;case 77:this.$=r.LINETYPE.SOLID_POINT;break;case 78:this.$=r.LINETYPE.DOTTED_POINT;break;case 79:this.$=r.parseMessage(i[o].trim().substring(1))}}),"anonymous"),table:[{3:1,4:e,5:a,6:r},{1:[3]},{3:5,4:e,5:a,6:r},{3:6,4:e,5:a,6:r},t([1,4,5,13,14,18,21,23,29,30,31,33,35,36,37,38,39,41,43,44,46,50,52,53,54,59,60,61,62,70],s,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:i,5:o,8:8,9:10,12:12,13:c,14:l,17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},t(K,[2,5]),{9:47,12:12,13:c,14:l,17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},t(K,[2,7]),t(K,[2,8]),t(K,[2,14]),{12:48,50:P,52:k,53:A},{15:[1,49]},{5:[1,50]},{5:[1,53],19:[1,51],20:[1,52]},{22:54,70:S},{22:55,70:S},{5:[1,56]},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},t(K,[2,29]),t(K,[2,30]),{32:[1,61]},{34:[1,62]},t(K,[2,33]),{15:[1,63]},{15:[1,64]},{15:[1,65]},{15:[1,66]},{15:[1,67]},{15:[1,68]},{15:[1,69]},{15:[1,70]},{22:71,70:S},{22:72,70:S},{22:73,70:S},{67:74,71:[1,75],72:[1,76],73:[1,77],74:[1,78],75:[1,79],76:[1,80],77:[1,81],78:[1,82],79:[1,83],80:[1,84]},{55:85,57:[1,86],65:[1,87],66:[1,88]},{22:89,70:S},{22:90,70:S},{22:91,70:S},{22:92,70:S},t([5,51,64,71,72,73,74,75,76,77,78,79,80,81],[2,68]),t(K,[2,6]),t(K,[2,15]),t(R,[2,9],{10:93}),t(K,[2,17]),{5:[1,95],19:[1,94]},{5:[1,96]},t(K,[2,21]),{5:[1,97]},{5:[1,98]},t(K,[2,24]),t(K,[2,25]),t(K,[2,26]),t(K,[2,27]),t(K,[2,28]),t(K,[2,31]),t(K,[2,32]),t(Y,s,{7:99}),t(Y,s,{7:100}),t(Y,s,{7:101}),t(C,s,{40:102,7:103}),t(B,s,{42:104,7:105}),t(B,s,{7:105,42:106}),t($,s,{45:107,7:108}),t(Y,s,{7:109}),{5:[1,111],51:[1,110]},{5:[1,113],51:[1,112]},{5:[1,114]},{22:117,68:[1,115],69:[1,116],70:S},t(V,[2,69]),t(V,[2,70]),t(V,[2,71]),t(V,[2,72]),t(V,[2,73]),t(V,[2,74]),t(V,[2,75]),t(V,[2,76]),t(V,[2,77]),t(V,[2,78]),{22:118,70:S},{22:120,58:119,70:S},{70:[2,63]},{70:[2,64]},{56:121,81:F},{56:123,81:F},{56:124,81:F},{56:125,81:F},{4:[1,128],5:[1,130],11:127,12:129,16:[1,126],50:P,52:k,53:A},{5:[1,131]},t(K,[2,19]),t(K,[2,20]),t(K,[2,22]),t(K,[2,23]),{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[1,132],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[1,133],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[1,134],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{16:[1,135]},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[2,46],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,49:[1,136],50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{16:[1,137]},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[2,44],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,48:[1,138],50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{16:[1,139]},{16:[1,140]},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[2,42],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,47:[1,141],50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{4:i,5:o,8:8,9:10,12:12,13:c,14:l,16:[1,142],17:15,18:d,21:h,22:40,23:p,24:19,25:20,26:21,27:22,28:23,29:g,30:u,31:x,33:y,35:m,36:b,37:T,38:f,39:E,41:w,43:I,44:L,46:_,50:P,52:k,53:A,54:v,59:N,60:M,61:D,62:O,70:S},{15:[1,143]},t(K,[2,49]),{15:[1,144]},t(K,[2,51]),t(K,[2,52]),{22:145,70:S},{22:146,70:S},{56:147,81:F},{56:148,81:F},{56:149,81:F},{64:[1,150],81:[2,62]},{5:[2,55]},{5:[2,79]},{5:[2,56]},{5:[2,57]},{5:[2,58]},t(K,[2,16]),t(R,[2,10]),{12:151,50:P,52:k,53:A},t(R,[2,12]),t(R,[2,13]),t(K,[2,18]),t(K,[2,34]),t(K,[2,35]),t(K,[2,36]),t(K,[2,37]),{15:[1,152]},t(K,[2,38]),{15:[1,153]},t(K,[2,39]),t(K,[2,40]),{15:[1,154]},t(K,[2,41]),{5:[1,155]},{5:[1,156]},{56:157,81:F},{56:158,81:F},{5:[2,67]},{5:[2,53]},{5:[2,54]},{22:159,70:S},t(R,[2,11]),t(C,s,{7:103,40:160}),t(B,s,{7:105,42:161}),t($,s,{7:108,45:162}),t(K,[2,48]),t(K,[2,50]),{5:[2,65]},{5:[2,66]},{81:[2,61]},{16:[2,47]},{16:[2,45]},{16:[2,43]}],defaultActions:{5:[2,1],6:[2,2],87:[2,63],88:[2,64],121:[2,55],122:[2,79],123:[2,56],124:[2,57],125:[2,58],147:[2,67],148:[2,53],149:[2,54],157:[2,65],158:[2,66],159:[2,61],160:[2,47],161:[2,45],162:[2,43]},parseError:(0,n.K2)((function(t,e){if(!e.recoverable){var a=new Error(t);throw a.hash=e,a}this.trace(t)}),"parseError"),parse:(0,n.K2)((function(t){var e=this,a=[0],r=[],s=[null],i=[],o=this.table,c="",l=0,d=0,h=0,p=i.slice.call(arguments,1),g=Object.create(this.lexer),u={yy:{}};for(var x in this.yy)Object.prototype.hasOwnProperty.call(this.yy,x)&&(u.yy[x]=this.yy[x]);g.setInput(t,u.yy),u.yy.lexer=g,u.yy.parser=this,void 0===g.yylloc&&(g.yylloc={});var y=g.yylloc;i.push(y);var m=g.options&&g.options.ranges;function b(){var t;return"number"!=typeof(t=r.pop()||g.lex()||1)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof u.yy.parseError?this.parseError=u.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,n.K2)((function(t){a.length=a.length-2*t,s.length=s.length-t,i.length=i.length-t}),"popStack"),(0,n.K2)(b,"lex");for(var T,f,E,w,I,L,_,P,k,A={};;){if(E=a[a.length-1],this.defaultActions[E]?w=this.defaultActions[E]:(null==T&&(T=b()),w=o[E]&&o[E][T]),void 0===w||!w.length||!w[0]){var v="";for(L in k=[],o[E])this.terminals_[L]&&L>2&&k.push("'"+this.terminals_[L]+"'");v=g.showPosition?"Parse error on line "+(l+1)+":\n"+g.showPosition()+"\nExpecting "+k.join(", ")+", got '"+(this.terminals_[T]||T)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==T?"end of input":"'"+(this.terminals_[T]||T)+"'"),this.parseError(v,{text:g.match,token:this.terminals_[T]||T,line:g.yylineno,loc:y,expected:k})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+T);switch(w[0]){case 1:a.push(T),s.push(g.yytext),i.push(g.yylloc),a.push(w[1]),T=null,f?(T=f,f=null):(d=g.yyleng,c=g.yytext,l=g.yylineno,y=g.yylloc,h>0&&h--);break;case 2:if(_=this.productions_[w[1]][1],A.$=s[s.length-_],A._$={first_line:i[i.length-(_||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(_||1)].first_column,last_column:i[i.length-1].last_column},m&&(A._$.range=[i[i.length-(_||1)].range[0],i[i.length-1].range[1]]),void 0!==(I=this.performAction.apply(A,[c,d,l,u.yy,w[1],s,i].concat(p))))return I;_&&(a=a.slice(0,-1*_*2),s=s.slice(0,-1*_),i=i.slice(0,-1*_)),a.push(this.productions_[w[1]][0]),s.push(A.$),i.push(A._$),P=o[a[a.length-2]][a[a.length-1]],a.push(P);break;case 3:return!0}}return!0}),"parse")},q=function(){return{EOF:1,parseError:(0,n.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,n.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,n.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,n.K2)((function(t){var e=t.length,a=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),a.length-1&&(this.yylineno-=a.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:a?(a.length===r.length?this.yylloc.first_column:0)+r[r.length-a.length].length-a[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,n.K2)((function(){return this._more=!0,this}),"more"),reject:(0,n.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,n.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,n.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,n.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,n.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,n.K2)((function(t,e){var a,r,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(r=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=r.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:r?r[r.length-1].length-r[r.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],a=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a)return a;if(this._backtrack){for(var i in s)this[i]=s[i];return!1}return!1}),"test_match"),next:(0,n.K2)((function(){if(this.done)return this.EOF;var t,e,a,r;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),i=0;i<s.length;i++)if((a=this._input.match(this.rules[s[i]]))&&(!e||a[0].length>e[0].length)){if(e=a,r=i,this.options.backtrack_lexer){if(!1!==(t=this.test_match(a,s[i])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[r]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,n.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,n.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,n.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,n.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,n.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,n.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,n.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,n.K2)((function(t,e,a,r){switch(a){case 0:case 51:case 66:return 5;case 1:case 2:case 3:case 4:case 5:break;case 6:return 19;case 7:return this.begin("LINE"),14;case 8:return this.begin("ID"),50;case 9:return this.begin("ID"),52;case 10:return 13;case 11:return this.begin("ID"),53;case 12:return e.yytext=e.yytext.trim(),this.begin("ALIAS"),70;case 13:return this.popState(),this.popState(),this.begin("LINE"),51;case 14:return this.popState(),this.popState(),5;case 15:return this.begin("LINE"),36;case 16:return this.begin("LINE"),37;case 17:return this.begin("LINE"),38;case 18:return this.begin("LINE"),39;case 19:return this.begin("LINE"),49;case 20:return this.begin("LINE"),41;case 21:return this.begin("LINE"),43;case 22:return this.begin("LINE"),48;case 23:return this.begin("LINE"),44;case 24:return this.begin("LINE"),47;case 25:return this.begin("LINE"),46;case 26:return this.popState(),15;case 27:return 16;case 28:return 65;case 29:return 66;case 30:return 59;case 31:return 60;case 32:return 61;case 33:return 62;case 34:return 57;case 35:return 54;case 36:return this.begin("ID"),21;case 37:return this.begin("ID"),23;case 38:return 29;case 39:return 30;case 40:return this.begin("acc_title"),31;case 41:return this.popState(),"acc_title_value";case 42:return this.begin("acc_descr"),33;case 43:return this.popState(),"acc_descr_value";case 44:this.begin("acc_descr_multiline");break;case 45:this.popState();break;case 46:return"acc_descr_multiline_value";case 47:return 6;case 48:return 18;case 49:return 20;case 50:return 64;case 52:return e.yytext=e.yytext.trim(),70;case 53:return 73;case 54:return 74;case 55:return 75;case 56:return 76;case 57:return 71;case 58:return 72;case 59:return 77;case 60:return 78;case 61:return 79;case 62:return 80;case 63:return 81;case 64:return 68;case 65:return 69;case 67:return"INVALID"}}),"anonymous"),rules:[/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[0-9]+(?=[ \n]+))/i,/^(?:box\b)/i,/^(?:participant\b)/i,/^(?:actor\b)/i,/^(?:create\b)/i,/^(?:destroy\b)/i,/^(?:[^\<->\->:\n,;]+?([\-]*[^\<->\->:\n,;]+?)*?(?=((?!\n)\s)+as(?!\n)\s|[#\n;]|$))/i,/^(?:as\b)/i,/^(?:(?:))/i,/^(?:loop\b)/i,/^(?:rect\b)/i,/^(?:opt\b)/i,/^(?:alt\b)/i,/^(?:else\b)/i,/^(?:par\b)/i,/^(?:par_over\b)/i,/^(?:and\b)/i,/^(?:critical\b)/i,/^(?:option\b)/i,/^(?:break\b)/i,/^(?:(?:[:]?(?:no)?wrap)?[^#\n;]*)/i,/^(?:end\b)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:links\b)/i,/^(?:link\b)/i,/^(?:properties\b)/i,/^(?:details\b)/i,/^(?:over\b)/i,/^(?:note\b)/i,/^(?:activate\b)/i,/^(?:deactivate\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:title:\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:sequenceDiagram\b)/i,/^(?:autonumber\b)/i,/^(?:off\b)/i,/^(?:,)/i,/^(?:;)/i,/^(?:[^\+\<->\->:\n,;]+((?!(-x|--x|-\)|--\)))[\-]*[^\+\<->\->:\n,;]+)*)/i,/^(?:->>)/i,/^(?:<<->>)/i,/^(?:-->>)/i,/^(?:<<-->>)/i,/^(?:->)/i,/^(?:-->)/i,/^(?:-[x])/i,/^(?:--[x])/i,/^(?:-[\)])/i,/^(?:--[\)])/i,/^(?::(?:(?:no)?wrap)?[^#\n;]+)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[45,46],inclusive:!1},acc_descr:{rules:[43],inclusive:!1},acc_title:{rules:[41],inclusive:!1},ID:{rules:[2,3,12],inclusive:!1},ALIAS:{rules:[2,3,13,14],inclusive:!1},LINE:{rules:[2,3,26],inclusive:!1},INITIAL:{rules:[0,1,3,4,5,6,7,8,9,10,11,15,16,17,18,19,20,21,22,23,24,25,27,28,29,30,31,32,33,34,35,36,37,38,39,40,42,44,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67],inclusive:!0}}}}();function z(){this.yy={}}return W.lexer=q,(0,n.K2)(z,"Parser"),z.prototype=W,W.Parser=z,new z}();l.parser=l;var d=l,h=new s.m((()=>({prevActor:void 0,actors:new Map,createdActors:new Map,destroyedActors:new Map,boxes:[],messages:[],notes:[],sequenceNumbersEnabled:!1,wrapEnabled:void 0,currentBox:void 0,lastCreated:void 0,lastDestroyed:void 0}))),p=(0,n.K2)((function(t){h.records.boxes.push({name:t.text,wrap:t.wrap??M(),fill:t.color,actorKeys:[]}),h.records.currentBox=h.records.boxes.slice(-1)[0]}),"addBox"),g=(0,n.K2)((function(t,e,a,r){let s=h.records.currentBox;const i=h.records.actors.get(t);if(i){if(h.records.currentBox&&i.box&&h.records.currentBox!==i.box)throw new Error(`A same participant should only be defined in one Box: ${i.name} can't be in '${i.box.name}' and in '${h.records.currentBox.name}' at the same time.`);if(s=i.box?i.box:h.records.currentBox,i.box=s,i&&e===i.name&&null==a)return}if(null==a?.text&&(a={text:e,type:r}),null!=r&&null!=a.text||(a={text:e,type:r}),h.records.actors.set(t,{box:s,name:e,description:a.text,wrap:a.wrap??M(),prevActor:h.records.prevActor,links:{},properties:{},actorCnt:null,rectData:null,type:r??"participant"}),h.records.prevActor){const e=h.records.actors.get(h.records.prevActor);e&&(e.nextActor=t)}h.records.currentBox&&h.records.currentBox.actorKeys.push(t),h.records.prevActor=t}),"addActor"),u=(0,n.K2)((t=>{let e,a=0;if(!t)return 0;for(e=0;e<h.records.messages.length;e++)h.records.messages[e].type===K.ACTIVE_START&&h.records.messages[e].from===t&&a++,h.records.messages[e].type===K.ACTIVE_END&&h.records.messages[e].from===t&&a--;return a}),"activationCount"),x=(0,n.K2)((function(t,e,a,r){h.records.messages.push({from:t,to:e,message:a.text,wrap:a.wrap??M(),answer:r})}),"addMessage"),y=(0,n.K2)((function(t,e,a,r,s=!1){if(r===K.ACTIVE_END){if(u(t??"")<1){const e=new Error("Trying to inactivate an inactive participant ("+t+")");throw e.hash={text:"->>-",token:"->>-",line:"1",loc:{first_line:1,last_line:1,first_column:1,last_column:1},expected:["'ACTIVE_PARTICIPANT'"]},e}}return h.records.messages.push({from:t,to:e,message:a?.text??"",wrap:a?.wrap??M(),type:r,activate:s}),!0}),"addSignal"),m=(0,n.K2)((function(){return h.records.boxes.length>0}),"hasAtLeastOneBox"),b=(0,n.K2)((function(){return h.records.boxes.some((t=>t.name))}),"hasAtLeastOneBoxWithTitle"),T=(0,n.K2)((function(){return h.records.messages}),"getMessages"),f=(0,n.K2)((function(){return h.records.boxes}),"getBoxes"),E=(0,n.K2)((function(){return h.records.actors}),"getActors"),w=(0,n.K2)((function(){return h.records.createdActors}),"getCreatedActors"),I=(0,n.K2)((function(){return h.records.destroyedActors}),"getDestroyedActors"),L=(0,n.K2)((function(t){return h.records.actors.get(t)}),"getActor"),_=(0,n.K2)((function(){return[...h.records.actors.keys()]}),"getActorKeys"),P=(0,n.K2)((function(){h.records.sequenceNumbersEnabled=!0}),"enableSequenceNumbers"),k=(0,n.K2)((function(){h.records.sequenceNumbersEnabled=!1}),"disableSequenceNumbers"),A=(0,n.K2)((()=>h.records.sequenceNumbersEnabled),"showSequenceNumbers"),v=(0,n.K2)((function(t){h.records.wrapEnabled=t}),"setWrap"),N=(0,n.K2)((t=>{if(void 0===t)return{};t=t.trim();const e=null!==/^:?wrap:/.exec(t)||null===/^:?nowrap:/.exec(t)&&void 0;return{cleanedText:(void 0===e?t:t.replace(/^:?(?:no)?wrap:/,"")).trim(),wrap:e}}),"extractWrap"),M=(0,n.K2)((()=>void 0!==h.records.wrapEnabled?h.records.wrapEnabled:(0,n.D7)().sequence?.wrap??!1),"autoWrap"),D=(0,n.K2)((function(){h.reset(),(0,n.IU)()}),"clear"),O=(0,n.K2)((function(t){const e=t.trim(),{wrap:a,cleanedText:r}=N(e),s={text:r,wrap:a};return n.Rm.debug(`parseMessage: ${JSON.stringify(s)}`),s}),"parseMessage"),S=(0,n.K2)((function(t){const e=/^((?:rgba?|hsla?)\s*\(.*\)|\w*)(.*)$/.exec(t);let a=e?.[1]?e[1].trim():"transparent",r=e?.[2]?e[2].trim():void 0;if(window?.CSS)window.CSS.supports("color",a)||(a="transparent",r=t.trim());else{const e=(new Option).style;e.color=a,e.color!==a&&(a="transparent",r=t.trim())}const{wrap:s,cleanedText:i}=N(r);return{text:i?(0,n.jZ)(i,(0,n.D7)()):void 0,color:a,wrap:s}}),"parseBoxData"),K={SOLID:0,DOTTED:1,NOTE:2,SOLID_CROSS:3,DOTTED_CROSS:4,SOLID_OPEN:5,DOTTED_OPEN:6,LOOP_START:10,LOOP_END:11,ALT_START:12,ALT_ELSE:13,ALT_END:14,OPT_START:15,OPT_END:16,ACTIVE_START:17,ACTIVE_END:18,PAR_START:19,PAR_AND:20,PAR_END:21,RECT_START:22,RECT_END:23,SOLID_POINT:24,DOTTED_POINT:25,AUTONUMBER:26,CRITICAL_START:27,CRITICAL_OPTION:28,CRITICAL_END:29,BREAK_START:30,BREAK_END:31,PAR_OVER_START:32,BIDIRECTIONAL_SOLID:33,BIDIRECTIONAL_DOTTED:34},R=(0,n.K2)((function(t,e,a){const r={actor:t,placement:e,message:a.text,wrap:a.wrap??M()},s=[].concat(t,t);h.records.notes.push(r),h.records.messages.push({from:s[0],to:s[1],message:a.text,wrap:a.wrap??M(),type:K.NOTE,placement:e})}),"addNote"),Y=(0,n.K2)((function(t,e){const a=L(t);try{let t=(0,n.jZ)(e.text,(0,n.D7)());t=t.replace(/&/g,"&"),t=t.replace(/=/g,"=");B(a,JSON.parse(t))}catch(r){n.Rm.error("error while parsing actor link text",r)}}),"addLinks"),C=(0,n.K2)((function(t,e){const a=L(t);try{const t={};let r=(0,n.jZ)(e.text,(0,n.D7)());const s=r.indexOf("@");r=r.replace(/&/g,"&"),r=r.replace(/=/g,"=");const i=r.slice(0,s-1).trim(),o=r.slice(s+1).trim();t[i]=o,B(a,t)}catch(r){n.Rm.error("error while parsing actor link text",r)}}),"addALink");function B(t,e){if(null==t.links)t.links=e;else for(const a in e)t.links[a]=e[a]}(0,n.K2)(B,"insertLinks");var $=(0,n.K2)((function(t,e){const a=L(t);try{const t=(0,n.jZ)(e.text,(0,n.D7)());V(a,JSON.parse(t))}catch(r){n.Rm.error("error while parsing actor properties text",r)}}),"addProperties");function V(t,e){if(null==t.properties)t.properties=e;else for(const a in e)t.properties[a]=e[a]}function F(){h.records.currentBox=void 0}(0,n.K2)(V,"insertProperties"),(0,n.K2)(F,"boxEnd");var W=(0,n.K2)((function(t,e){const a=L(t),r=document.getElementById(e.text);try{const t=r.innerHTML,e=JSON.parse(t);e.properties&&V(a,e.properties),e.links&&B(a,e.links)}catch(s){n.Rm.error("error while parsing actor details text",s)}}),"addDetails"),q=(0,n.K2)((function(t,e){if(void 0!==t?.properties)return t.properties[e]}),"getActorProperty"),z=(0,n.K2)((function(t){if(Array.isArray(t))t.forEach((function(t){z(t)}));else switch(t.type){case"sequenceIndex":h.records.messages.push({from:void 0,to:void 0,message:{start:t.sequenceIndex,step:t.sequenceIndexStep,visible:t.sequenceVisible},wrap:!1,type:t.signalType});break;case"addParticipant":g(t.actor,t.actor,t.description,t.draw);break;case"createParticipant":if(h.records.actors.has(t.actor))throw new Error("It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior");h.records.lastCreated=t.actor,g(t.actor,t.actor,t.description,t.draw),h.records.createdActors.set(t.actor,h.records.messages.length);break;case"destroyParticipant":h.records.lastDestroyed=t.actor,h.records.destroyedActors.set(t.actor,h.records.messages.length);break;case"activeStart":case"activeEnd":y(t.actor,void 0,void 0,t.signalType);break;case"addNote":R(t.actor,t.placement,t.text);break;case"addLinks":Y(t.actor,t.text);break;case"addALink":C(t.actor,t.text);break;case"addProperties":$(t.actor,t.text);break;case"addDetails":W(t.actor,t.text);break;case"addMessage":if(h.records.lastCreated){if(t.to!==h.records.lastCreated)throw new Error("The created participant "+h.records.lastCreated.name+" does not have an associated creating message after its declaration. Please check the sequence diagram.");h.records.lastCreated=void 0}else if(h.records.lastDestroyed){if(t.to!==h.records.lastDestroyed&&t.from!==h.records.lastDestroyed)throw new Error("The destroyed participant "+h.records.lastDestroyed.name+" does not have an associated destroying message after its declaration. Please check the sequence diagram.");h.records.lastDestroyed=void 0}y(t.from,t.to,t.msg,t.signalType,t.activate);break;case"boxStart":p(t.boxData);break;case"boxEnd":F();break;case"loopStart":y(void 0,void 0,t.loopText,t.signalType);break;case"loopEnd":case"rectEnd":case"optEnd":case"altEnd":case"parEnd":case"criticalEnd":case"breakEnd":y(void 0,void 0,void 0,t.signalType);break;case"rectStart":y(void 0,void 0,t.color,t.signalType);break;case"optStart":y(void 0,void 0,t.optText,t.signalType);break;case"altStart":case"else":y(void 0,void 0,t.altText,t.signalType);break;case"setAccTitle":(0,n.SV)(t.text);break;case"parStart":case"and":y(void 0,void 0,t.parText,t.signalType);break;case"criticalStart":y(void 0,void 0,t.criticalText,t.signalType);break;case"option":y(void 0,void 0,t.optionText,t.signalType);break;case"breakStart":y(void 0,void 0,t.breakText,t.signalType)}}),"apply"),H={addActor:g,addMessage:x,addSignal:y,addLinks:Y,addDetails:W,addProperties:$,autoWrap:M,setWrap:v,enableSequenceNumbers:P,disableSequenceNumbers:k,showSequenceNumbers:A,getMessages:T,getActors:E,getCreatedActors:w,getDestroyedActors:I,getActor:L,getActorKeys:_,getActorProperty:q,getAccTitle:n.iN,getBoxes:f,getDiagramTitle:n.ab,setDiagramTitle:n.ke,getConfig:(0,n.K2)((()=>(0,n.D7)().sequence),"getConfig"),clear:D,parseMessage:O,parseBoxData:S,LINETYPE:K,ARROWTYPE:{FILLED:0,OPEN:1},PLACEMENT:{LEFTOF:0,RIGHTOF:1,OVER:2},addNote:R,setAccTitle:n.SV,apply:z,setAccDescription:n.EI,getAccDescription:n.m7,hasAtLeastOneBox:m,hasAtLeastOneBoxWithTitle:b},j=(0,n.K2)((t=>`.actor {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${t.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${t.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${t.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${t.signalColor};\n }\n\n #arrowhead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .sequenceNumber {\n fill: ${t.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${t.signalColor};\n }\n\n #crosshead path {\n fill: ${t.signalColor};\n stroke: ${t.signalColor};\n }\n\n .messageText {\n fill: ${t.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${t.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${t.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${t.labelBoxBorderColor};\n fill: ${t.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${t.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation1 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .activation2 {\n fill: ${t.activationBkgColor};\n stroke: ${t.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${t.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${t.actorBorder};\n fill: ${t.actorBkg};\n stroke-width: 2px;\n }\n`),"getStyles"),U="actor-top",J="actor-bottom",X="actor-man",G=(0,n.K2)((function(t,e){return(0,r.tk)(t,e)}),"drawRect"),Z=(0,n.K2)((function(t,e,a,r,s){if(void 0===e.links||null===e.links||0===Object.keys(e.links).length)return{height:0,width:0};const i=e.links,n=e.actorCnt,o=e.rectData;var l="none";s&&(l="block !important");const d=t.append("g");d.attr("id","actor"+n+"_popup"),d.attr("class","actorPopupMenu"),d.attr("display",l);var h="";void 0!==o.class&&(h=" "+o.class);let p=o.width>a?o.width:a;const g=d.append("rect");if(g.attr("class","actorPopupMenuPanel"+h),g.attr("x",o.x),g.attr("y",o.height),g.attr("fill",o.fill),g.attr("stroke",o.stroke),g.attr("width",p),g.attr("height",o.height),g.attr("rx",o.rx),g.attr("ry",o.ry),null!=i){var u=20;for(let t in i){var x=d.append("a"),y=(0,c.J)(i[t]);x.attr("xlink:href",y),x.attr("target","_blank"),It(r)(t,x,o.x+10,o.height+u,p,20,{class:"actor"},r),u+=30}}return g.attr("height",u),{height:o.height+u,width:p}}),"drawPopup"),Q=(0,n.K2)((function(t){return"var pu = document.getElementById('"+t+"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }"}),"popupMenuToggle"),tt=(0,n.K2)((async function(t,e,a=null){let r=t.append("foreignObject");const s=await(0,n.VJ)(e.text,(0,n.zj)()),i=r.append("xhtml:div").attr("style","width: fit-content;").attr("xmlns","http://www.w3.org/1999/xhtml").html(s).node().getBoundingClientRect();if(r.attr("height",Math.round(i.height)).attr("width",Math.round(i.width)),"noteText"===e.class){const a=t.node().firstChild;a.setAttribute("height",i.height+2*e.textMargin);const s=a.getBBox();r.attr("x",Math.round(s.x+s.width/2-i.width/2)).attr("y",Math.round(s.y+s.height/2-i.height/2))}else if(a){let{startx:t,stopx:s,starty:n}=a;if(t>s){const e=t;t=s,s=e}r.attr("x",Math.round(t+Math.abs(t-s)/2-i.width/2)),"loopText"===e.class?r.attr("y",Math.round(n)):r.attr("y",Math.round(n-i.height))}return[r]}),"drawKatex"),et=(0,n.K2)((function(t,e){let a=0,r=0;const s=e.text.split(n.Y2.lineBreakRegex),[o,c]=(0,i.I5)(e.fontSize);let l=[],d=0,h=(0,n.K2)((()=>e.y),"yfunc");if(void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0)switch(e.valign){case"top":case"start":h=(0,n.K2)((()=>Math.round(e.y+e.textMargin)),"yfunc");break;case"middle":case"center":h=(0,n.K2)((()=>Math.round(e.y+(a+r+e.textMargin)/2)),"yfunc");break;case"bottom":case"end":h=(0,n.K2)((()=>Math.round(e.y+(a+r+2*e.textMargin)-e.textMargin)),"yfunc")}if(void 0!==e.anchor&&void 0!==e.textMargin&&void 0!==e.width)switch(e.anchor){case"left":case"start":e.x=Math.round(e.x+e.textMargin),e.anchor="start",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"middle":case"center":e.x=Math.round(e.x+e.width/2),e.anchor="middle",e.dominantBaseline="middle",e.alignmentBaseline="middle";break;case"right":case"end":e.x=Math.round(e.x+e.width-e.textMargin),e.anchor="end",e.dominantBaseline="middle",e.alignmentBaseline="middle"}for(let[n,p]of s.entries()){void 0!==e.textMargin&&0===e.textMargin&&void 0!==o&&(d=n*o);const s=t.append("text");s.attr("x",e.x),s.attr("y",h()),void 0!==e.anchor&&s.attr("text-anchor",e.anchor).attr("dominant-baseline",e.dominantBaseline).attr("alignment-baseline",e.alignmentBaseline),void 0!==e.fontFamily&&s.style("font-family",e.fontFamily),void 0!==c&&s.style("font-size",c),void 0!==e.fontWeight&&s.style("font-weight",e.fontWeight),void 0!==e.fill&&s.attr("fill",e.fill),void 0!==e.class&&s.attr("class",e.class),void 0!==e.dy?s.attr("dy",e.dy):0!==d&&s.attr("dy",d);const g=p||i.pe;if(e.tspan){const t=s.append("tspan");t.attr("x",e.x),void 0!==e.fill&&t.attr("fill",e.fill),t.text(g)}else s.text(g);void 0!==e.valign&&void 0!==e.textMargin&&e.textMargin>0&&(r+=(s._groups||s)[0][0].getBBox().height,a=r),l.push(s)}return l}),"drawText"),at=(0,n.K2)((function(t,e){function a(t,e,a,r,s){return t+","+e+" "+(t+a)+","+e+" "+(t+a)+","+(e+r-s)+" "+(t+a-1.2*s)+","+(e+r)+" "+t+","+(e+r)}(0,n.K2)(a,"genPoints");const r=t.append("polygon");return r.attr("points",a(e.x,e.y,e.width,e.height,7)),r.attr("class","labelBox"),e.y=e.y+e.height/2,et(t,e),r}),"drawLabel"),rt=-1,st=(0,n.K2)(((t,e,a,r)=>{t.select&&a.forEach((a=>{const s=e.get(a),i=t.select("#actor"+s.actorCnt);!r.mirrorActors&&s.stopy?i.attr("y2",s.stopy+s.height/2):r.mirrorActors&&i.attr("y2",s.stopy)}))}),"fixLifeLineHeights"),it=(0,n.K2)((function(t,e,a,s){const i=s?e.stopy:e.starty,o=e.x+e.width/2,c=i+e.height,l=t.append("g").lower();var d=l;s||(rt++,Object.keys(e.links||{}).length&&!a.forceMenus&&d.attr("onclick",Q(`actor${rt}_popup`)).attr("cursor","pointer"),d.append("line").attr("id","actor"+rt).attr("x1",o).attr("y1",c).attr("x2",o).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),d=l.append("g"),e.actorCnt=rt,null!=e.links&&d.attr("id","root-"+rt));const h=(0,r.PB)();var p="actor";e.properties?.class?p=e.properties.class:h.fill="#eaeaea",p+=s?` ${J}`:` ${U}`,h.x=e.x,h.y=i,h.width=e.width,h.height=e.height,h.class=p,h.rx=3,h.ry=3,h.name=e.name;const g=G(d,h);if(e.rectData=h,e.properties?.icon){const t=e.properties.icon.trim();"@"===t.charAt(0)?(0,r.CP)(d,h.x+h.width-20,h.y+10,t.substr(1)):(0,r.aC)(d,h.x+h.width-20,h.y+10,t)}wt(a,(0,n.Wi)(e.description))(e.description,d,h.x,h.y,h.width,h.height,{class:"actor actor-box"},a);let u=e.height;if(g.node){const t=g.node().getBBox();e.height=t.height,u=t.height}return u}),"drawActorTypeParticipant"),nt=(0,n.K2)((function(t,e,a,s){const i=s?e.stopy:e.starty,o=e.x+e.width/2,c=i+80,l=t.append("g").lower();s||(rt++,l.append("line").attr("id","actor"+rt).attr("x1",o).attr("y1",c).attr("x2",o).attr("y2",2e3).attr("class","actor-line 200").attr("stroke-width","0.5px").attr("stroke","#999").attr("name",e.name),e.actorCnt=rt);const d=t.append("g");let h=X;h+=s?` ${J}`:` ${U}`,d.attr("class",h),d.attr("name",e.name);const p=(0,r.PB)();p.x=e.x,p.y=i,p.fill="#eaeaea",p.width=e.width,p.height=e.height,p.class="actor",p.rx=3,p.ry=3,d.append("line").attr("id","actor-man-torso"+rt).attr("x1",o).attr("y1",i+25).attr("x2",o).attr("y2",i+45),d.append("line").attr("id","actor-man-arms"+rt).attr("x1",o-18).attr("y1",i+33).attr("x2",o+18).attr("y2",i+33),d.append("line").attr("x1",o-18).attr("y1",i+60).attr("x2",o).attr("y2",i+45),d.append("line").attr("x1",o).attr("y1",i+45).attr("x2",o+18-2).attr("y2",i+60);const g=d.append("circle");g.attr("cx",e.x+e.width/2),g.attr("cy",i+10),g.attr("r",15),g.attr("width",e.width),g.attr("height",e.height);const u=d.node().getBBox();return e.height=u.height,wt(a,(0,n.Wi)(e.description))(e.description,d,p.x,p.y+35,p.width,p.height,{class:`actor ${X}`},a),e.height}),"drawActorTypeActor"),ot=(0,n.K2)((async function(t,e,a,r){switch(e.type){case"actor":return await nt(t,e,a,r);case"participant":return await it(t,e,a,r)}}),"drawActor"),ct=(0,n.K2)((function(t,e,a){const r=t.append("g");pt(r,e),e.name&&wt(a)(e.name,r,e.x,e.y+(e.textMaxHeight||0)/2,e.width,0,{class:"text"},a),r.lower()}),"drawBox"),lt=(0,n.K2)((function(t){return t.append("g")}),"anchorElement"),dt=(0,n.K2)((function(t,e,a,s,i){const n=(0,r.PB)(),o=e.anchored;n.x=e.startx,n.y=e.starty,n.class="activation"+i%3,n.width=e.stopx-e.startx,n.height=a-e.starty,G(o,n)}),"drawActivation"),ht=(0,n.K2)((async function(t,e,a,s){const{boxMargin:i,boxTextMargin:o,labelBoxHeight:c,labelBoxWidth:l,messageFontFamily:d,messageFontSize:h,messageFontWeight:p}=s,g=t.append("g"),u=(0,n.K2)((function(t,e,a,r){return g.append("line").attr("x1",t).attr("y1",e).attr("x2",a).attr("y2",r).attr("class","loopLine")}),"drawLoopLine");u(e.startx,e.starty,e.stopx,e.starty),u(e.stopx,e.starty,e.stopx,e.stopy),u(e.startx,e.stopy,e.stopx,e.stopy),u(e.startx,e.starty,e.startx,e.stopy),void 0!==e.sections&&e.sections.forEach((function(t){u(e.startx,t.y,e.stopx,t.y).style("stroke-dasharray","3, 3")}));let x=(0,r.HT)();x.text=a,x.x=e.startx,x.y=e.starty,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.anchor="middle",x.valign="middle",x.tspan=!1,x.width=l||50,x.height=c||20,x.textMargin=o,x.class="labelText",at(g,x),x=ft(),x.text=e.title,x.x=e.startx+l/2+(e.stopx-e.startx)/2,x.y=e.starty+i+o,x.anchor="middle",x.valign="middle",x.textMargin=o,x.class="loopText",x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=!0;let y=(0,n.Wi)(x.text)?await tt(g,x,e):et(g,x);if(void 0!==e.sectionTitles)for(const[r,m]of Object.entries(e.sectionTitles))if(m.message){x.text=m.message,x.x=e.startx+(e.stopx-e.startx)/2,x.y=e.sections[r].y+i+o,x.class="loopText",x.anchor="middle",x.valign="middle",x.tspan=!1,x.fontFamily=d,x.fontSize=h,x.fontWeight=p,x.wrap=e.wrap,(0,n.Wi)(x.text)?(e.starty=e.sections[r].y,await tt(g,x,e)):et(g,x);let t=Math.round(y.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));e.sections[r].height+=t-(i+o)}return e.height=Math.round(e.stopy-e.starty),g}),"drawLoop"),pt=(0,n.K2)((function(t,e){(0,r.lC)(t,e)}),"drawBackgroundRect"),gt=(0,n.K2)((function(t){t.append("defs").append("symbol").attr("id","database").attr("fill-rule","evenodd").attr("clip-rule","evenodd").append("path").attr("transform","scale(.5)").attr("d","M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z")}),"insertDatabaseIcon"),ut=(0,n.K2)((function(t){t.append("defs").append("symbol").attr("id","computer").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z")}),"insertComputerIcon"),xt=(0,n.K2)((function(t){t.append("defs").append("symbol").attr("id","clock").attr("width","24").attr("height","24").append("path").attr("transform","scale(.5)").attr("d","M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z")}),"insertClockIcon"),yt=(0,n.K2)((function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",7.9).attr("refY",5).attr("markerUnits","userSpaceOnUse").attr("markerWidth",12).attr("markerHeight",12).attr("orient","auto-start-reverse").append("path").attr("d","M -1 0 L 10 5 L 0 10 z")}),"insertArrowHead"),mt=(0,n.K2)((function(t){t.append("defs").append("marker").attr("id","filled-head").attr("refX",15.5).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L14,7 L9,1 Z")}),"insertArrowFilledHead"),bt=(0,n.K2)((function(t){t.append("defs").append("marker").attr("id","sequencenumber").attr("refX",15).attr("refY",15).attr("markerWidth",60).attr("markerHeight",40).attr("orient","auto").append("circle").attr("cx",15).attr("cy",15).attr("r",6)}),"insertSequenceNumber"),Tt=(0,n.K2)((function(t){t.append("defs").append("marker").attr("id","crosshead").attr("markerWidth",15).attr("markerHeight",8).attr("orient","auto").attr("refX",4).attr("refY",4.5).append("path").attr("fill","none").attr("stroke","#000000").style("stroke-dasharray","0, 0").attr("stroke-width","1pt").attr("d","M 1,2 L 6,7 M 6,2 L 1,7")}),"insertArrowCrossHead"),ft=(0,n.K2)((function(){return{x:0,y:0,fill:void 0,anchor:void 0,style:"#666",width:void 0,height:void 0,textMargin:0,rx:0,ry:0,tspan:!0,valign:void 0}}),"getTextObj"),Et=(0,n.K2)((function(){return{x:0,y:0,fill:"#EDF2AE",stroke:"#666",width:100,anchor:"start",height:100,rx:0,ry:0}}),"getNoteRect"),wt=function(){function t(t,e,a,r,i,n,o){s(e.append("text").attr("x",a+i/2).attr("y",r+n/2+5).style("text-anchor","middle").text(t),o)}function e(t,e,a,r,o,c,l,d){const{actorFontSize:h,actorFontFamily:p,actorFontWeight:g}=d,[u,x]=(0,i.I5)(h),y=t.split(n.Y2.lineBreakRegex);for(let i=0;i<y.length;i++){const t=i*u-u*(y.length-1)/2,n=e.append("text").attr("x",a+o/2).attr("y",r).style("text-anchor","middle").style("font-size",x).style("font-weight",g).style("font-family",p);n.append("tspan").attr("x",a+o/2).attr("dy",t).text(y[i]),n.attr("y",r+c/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),s(n,l)}}function a(t,a,r,i,n,o,c,l){const d=a.append("switch"),h=d.append("foreignObject").attr("x",r).attr("y",i).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");h.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,d,r,i,n,o,c,l),s(h,c)}async function r(t,a,r,i,o,c,l,d){const h=await(0,n.Dl)(t,(0,n.zj)()),p=a.append("switch"),g=p.append("foreignObject").attr("x",r+o/2-h.width/2).attr("y",i+c/2-h.height/2).attr("width",h.width).attr("height",h.height).append("xhtml:div").style("height","100%").style("width","100%");g.append("div").style("text-align","center").style("vertical-align","middle").html(await(0,n.VJ)(t,(0,n.zj)())),e(t,p,r,i,o,c,l,d),s(g,l)}function s(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return(0,n.K2)(t,"byText"),(0,n.K2)(e,"byTspan"),(0,n.K2)(a,"byFo"),(0,n.K2)(r,"byKatex"),(0,n.K2)(s,"_setTextAttrs"),function(s,i=!1){return i?r:"fo"===s.textPlacement?a:"old"===s.textPlacement?t:e}}(),It=function(){function t(t,e,a,s,i,n,o){r(e.append("text").attr("x",a).attr("y",s).style("text-anchor","start").text(t),o)}function e(t,e,a,s,i,o,c,l){const{actorFontSize:d,actorFontFamily:h,actorFontWeight:p}=l,g=t.split(n.Y2.lineBreakRegex);for(let n=0;n<g.length;n++){const t=n*d-d*(g.length-1)/2,i=e.append("text").attr("x",a).attr("y",s).style("text-anchor","start").style("font-size",d).style("font-weight",p).style("font-family",h);i.append("tspan").attr("x",a).attr("dy",t).text(g[n]),i.attr("y",s+o/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),r(i,c)}}function a(t,a,s,i,n,o,c,l){const d=a.append("switch"),h=d.append("foreignObject").attr("x",s).attr("y",i).attr("width",n).attr("height",o).append("xhtml:div").style("display","table").style("height","100%").style("width","100%");h.append("div").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,d,s,i,0,o,c,l),r(h,c)}function r(t,e){for(const a in e)e.hasOwnProperty(a)&&t.attr(a,e[a])}return(0,n.K2)(t,"byText"),(0,n.K2)(e,"byTspan"),(0,n.K2)(a,"byFo"),(0,n.K2)(r,"_setTextAttrs"),function(r){return"fo"===r.textPlacement?a:"old"===r.textPlacement?t:e}}(),Lt={drawRect:G,drawText:et,drawLabel:at,drawActor:ot,drawBox:ct,drawPopup:Z,anchorElement:lt,drawActivation:dt,drawLoop:ht,drawBackgroundRect:pt,insertArrowHead:yt,insertArrowFilledHead:mt,insertSequenceNumber:bt,insertArrowCrossHead:Tt,insertDatabaseIcon:gt,insertComputerIcon:ut,insertClockIcon:xt,getTextObj:ft,getNoteRect:Et,fixLifeLineHeights:st,sanitizeUrl:c.J},_t={},Pt={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],activations:[],models:{getHeight:(0,n.K2)((function(){return Math.max.apply(null,0===this.actors.length?[0]:this.actors.map((t=>t.height||0)))+(0===this.loops.length?0:this.loops.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.messages.length?0:this.messages.map((t=>t.height||0)).reduce(((t,e)=>t+e)))+(0===this.notes.length?0:this.notes.map((t=>t.height||0)).reduce(((t,e)=>t+e)))}),"getHeight"),clear:(0,n.K2)((function(){this.actors=[],this.boxes=[],this.loops=[],this.messages=[],this.notes=[]}),"clear"),addBox:(0,n.K2)((function(t){this.boxes.push(t)}),"addBox"),addActor:(0,n.K2)((function(t){this.actors.push(t)}),"addActor"),addLoop:(0,n.K2)((function(t){this.loops.push(t)}),"addLoop"),addMessage:(0,n.K2)((function(t){this.messages.push(t)}),"addMessage"),addNote:(0,n.K2)((function(t){this.notes.push(t)}),"addNote"),lastActor:(0,n.K2)((function(){return this.actors[this.actors.length-1]}),"lastActor"),lastLoop:(0,n.K2)((function(){return this.loops[this.loops.length-1]}),"lastLoop"),lastMessage:(0,n.K2)((function(){return this.messages[this.messages.length-1]}),"lastMessage"),lastNote:(0,n.K2)((function(){return this.notes[this.notes.length-1]}),"lastNote"),actors:[],boxes:[],loops:[],messages:[],notes:[]},init:(0,n.K2)((function(){this.sequenceItems=[],this.activations=[],this.models.clear(),this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0,Rt((0,n.D7)())}),"init"),updateVal:(0,n.K2)((function(t,e,a,r){void 0===t[e]?t[e]=a:t[e]=r(a,t[e])}),"updateVal"),updateBounds:(0,n.K2)((function(t,e,a,r){const s=this;let i=0;function o(o){return(0,n.K2)((function(n){i++;const c=s.sequenceItems.length-i+1;s.updateVal(n,"starty",e-c*_t.boxMargin,Math.min),s.updateVal(n,"stopy",r+c*_t.boxMargin,Math.max),s.updateVal(Pt.data,"startx",t-c*_t.boxMargin,Math.min),s.updateVal(Pt.data,"stopx",a+c*_t.boxMargin,Math.max),"activation"!==o&&(s.updateVal(n,"startx",t-c*_t.boxMargin,Math.min),s.updateVal(n,"stopx",a+c*_t.boxMargin,Math.max),s.updateVal(Pt.data,"starty",e-c*_t.boxMargin,Math.min),s.updateVal(Pt.data,"stopy",r+c*_t.boxMargin,Math.max))}),"updateItemBounds")}(0,n.K2)(o,"updateFn"),this.sequenceItems.forEach(o()),this.activations.forEach(o("activation"))}),"updateBounds"),insert:(0,n.K2)((function(t,e,a,r){const s=n.Y2.getMin(t,a),i=n.Y2.getMax(t,a),o=n.Y2.getMin(e,r),c=n.Y2.getMax(e,r);this.updateVal(Pt.data,"startx",s,Math.min),this.updateVal(Pt.data,"starty",o,Math.min),this.updateVal(Pt.data,"stopx",i,Math.max),this.updateVal(Pt.data,"stopy",c,Math.max),this.updateBounds(s,o,i,c)}),"insert"),newActivation:(0,n.K2)((function(t,e,a){const r=a.get(t.from),s=Yt(t.from).length||0,i=r.x+r.width/2+(s-1)*_t.activationWidth/2;this.activations.push({startx:i,starty:this.verticalPos+2,stopx:i+_t.activationWidth,stopy:void 0,actor:t.from,anchored:Lt.anchorElement(e)})}),"newActivation"),endActivation:(0,n.K2)((function(t){const e=this.activations.map((function(t){return t.actor})).lastIndexOf(t.from);return this.activations.splice(e,1)[0]}),"endActivation"),createLoop:(0,n.K2)((function(t={message:void 0,wrap:!1,width:void 0},e){return{startx:void 0,starty:this.verticalPos,stopx:void 0,stopy:void 0,title:t.message,wrap:t.wrap,width:t.width,height:0,fill:e}}),"createLoop"),newLoop:(0,n.K2)((function(t={message:void 0,wrap:!1,width:void 0},e){this.sequenceItems.push(this.createLoop(t,e))}),"newLoop"),endLoop:(0,n.K2)((function(){return this.sequenceItems.pop()}),"endLoop"),isLoopOverlap:(0,n.K2)((function(){return!!this.sequenceItems.length&&this.sequenceItems[this.sequenceItems.length-1].overlap}),"isLoopOverlap"),addSectionToLoop:(0,n.K2)((function(t){const e=this.sequenceItems.pop();e.sections=e.sections||[],e.sectionTitles=e.sectionTitles||[],e.sections.push({y:Pt.getVerticalPos(),height:0}),e.sectionTitles.push(t),this.sequenceItems.push(e)}),"addSectionToLoop"),saveVerticalPos:(0,n.K2)((function(){this.isLoopOverlap()&&(this.savedVerticalPos=this.verticalPos)}),"saveVerticalPos"),resetVerticalPos:(0,n.K2)((function(){this.isLoopOverlap()&&(this.verticalPos=this.savedVerticalPos)}),"resetVerticalPos"),bumpVerticalPos:(0,n.K2)((function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=n.Y2.getMax(this.data.stopy,this.verticalPos)}),"bumpVerticalPos"),getVerticalPos:(0,n.K2)((function(){return this.verticalPos}),"getVerticalPos"),getBounds:(0,n.K2)((function(){return{bounds:this.data,models:this.models}}),"getBounds")},kt=(0,n.K2)((async function(t,e){Pt.bumpVerticalPos(_t.boxMargin),e.height=_t.boxMargin,e.starty=Pt.getVerticalPos();const a=(0,r.PB)();a.x=e.startx,a.y=e.starty,a.width=e.width||_t.width,a.class="note";const s=t.append("g"),i=Lt.drawRect(s,a),o=(0,r.HT)();o.x=e.startx,o.y=e.starty,o.width=a.width,o.dy="1em",o.text=e.message,o.class="noteText",o.fontFamily=_t.noteFontFamily,o.fontSize=_t.noteFontSize,o.fontWeight=_t.noteFontWeight,o.anchor=_t.noteAlign,o.textMargin=_t.noteMargin,o.valign="center";const c=(0,n.Wi)(o.text)?await tt(s,o):et(s,o),l=Math.round(c.map((t=>(t._groups||t)[0][0].getBBox().height)).reduce(((t,e)=>t+e)));i.attr("height",l+2*_t.noteMargin),e.height+=l+2*_t.noteMargin,Pt.bumpVerticalPos(l+2*_t.noteMargin),e.stopy=e.starty+l+2*_t.noteMargin,e.stopx=e.startx+a.width,Pt.insert(e.startx,e.starty,e.stopx,e.stopy),Pt.models.addNote(e)}),"drawNote"),At=(0,n.K2)((t=>({fontFamily:t.messageFontFamily,fontSize:t.messageFontSize,fontWeight:t.messageFontWeight})),"messageFont"),vt=(0,n.K2)((t=>({fontFamily:t.noteFontFamily,fontSize:t.noteFontSize,fontWeight:t.noteFontWeight})),"noteFont"),Nt=(0,n.K2)((t=>({fontFamily:t.actorFontFamily,fontSize:t.actorFontSize,fontWeight:t.actorFontWeight})),"actorFont");async function Mt(t,e){Pt.bumpVerticalPos(10);const{startx:a,stopx:r,message:s}=e,o=n.Y2.splitBreaks(s).length,c=(0,n.Wi)(s),l=c?await(0,n.Dl)(s,(0,n.D7)()):i._K.calculateTextDimensions(s,At(_t));if(!c){const t=l.height/o;e.height+=t,Pt.bumpVerticalPos(t)}let d,h=l.height-10;const p=l.width;if(a===r){d=Pt.getVerticalPos()+h,_t.rightAngles||(h+=_t.boxMargin,d=Pt.getVerticalPos()+h),h+=30;const t=n.Y2.getMax(p/2,_t.width/2);Pt.insert(a-t,Pt.getVerticalPos()-10+h,r+t,Pt.getVerticalPos()+30+h)}else h+=_t.boxMargin,d=Pt.getVerticalPos()+h,Pt.insert(a,d-10,r,d);return Pt.bumpVerticalPos(h),e.height+=h,e.stopy=e.starty+e.height,Pt.insert(e.fromBounds,e.starty,e.toBounds,e.stopy),d}(0,n.K2)(Mt,"boundMessage");var Dt=(0,n.K2)((async function(t,e,a,s){const{startx:o,stopx:c,starty:l,message:d,type:h,sequenceIndex:p,sequenceVisible:g}=e,u=i._K.calculateTextDimensions(d,At(_t)),x=(0,r.HT)();x.x=o,x.y=l+10,x.width=c-o,x.class="messageText",x.dy="1em",x.text=d,x.fontFamily=_t.messageFontFamily,x.fontSize=_t.messageFontSize,x.fontWeight=_t.messageFontWeight,x.anchor=_t.messageAlign,x.valign="center",x.textMargin=_t.wrapPadding,x.tspan=!1,(0,n.Wi)(x.text)?await tt(t,x,{startx:o,stopx:c,starty:a}):et(t,x);const y=u.width;let m;o===c?m=_t.rightAngles?t.append("path").attr("d",`M ${o},${a} H ${o+n.Y2.getMax(_t.width/2,y/2)} V ${a+25} H ${o}`):t.append("path").attr("d","M "+o+","+a+" C "+(o+60)+","+(a-10)+" "+(o+60)+","+(a+30)+" "+o+","+(a+20)):(m=t.append("line"),m.attr("x1",o),m.attr("y1",a),m.attr("x2",c),m.attr("y2",a)),h===s.db.LINETYPE.DOTTED||h===s.db.LINETYPE.DOTTED_CROSS||h===s.db.LINETYPE.DOTTED_POINT||h===s.db.LINETYPE.DOTTED_OPEN||h===s.db.LINETYPE.BIDIRECTIONAL_DOTTED?(m.style("stroke-dasharray","3, 3"),m.attr("class","messageLine1")):m.attr("class","messageLine0");let b="";_t.arrowMarkerAbsolute&&(b=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,b=b.replace(/\(/g,"\\("),b=b.replace(/\)/g,"\\)")),m.attr("stroke-width",2),m.attr("stroke","none"),m.style("fill","none"),h!==s.db.LINETYPE.SOLID&&h!==s.db.LINETYPE.DOTTED||m.attr("marker-end","url("+b+"#arrowhead)"),h!==s.db.LINETYPE.BIDIRECTIONAL_SOLID&&h!==s.db.LINETYPE.BIDIRECTIONAL_DOTTED||(m.attr("marker-start","url("+b+"#arrowhead)"),m.attr("marker-end","url("+b+"#arrowhead)")),h!==s.db.LINETYPE.SOLID_POINT&&h!==s.db.LINETYPE.DOTTED_POINT||m.attr("marker-end","url("+b+"#filled-head)"),h!==s.db.LINETYPE.SOLID_CROSS&&h!==s.db.LINETYPE.DOTTED_CROSS||m.attr("marker-end","url("+b+"#crosshead)"),(g||_t.showSequenceNumbers)&&(m.attr("marker-start","url("+b+"#sequencenumber)"),t.append("text").attr("x",o).attr("y",a+4).attr("font-family","sans-serif").attr("font-size","12px").attr("text-anchor","middle").attr("class","sequenceNumber").text(p))}),"drawMessage"),Ot=(0,n.K2)((function(t,e,a,r,s,i,o){let c,l=0,d=0,h=0;for(const p of r){const t=e.get(p),r=t.box;c&&c!=r&&(o||Pt.models.addBox(c),d+=_t.boxMargin+c.margin),r&&r!=c&&(o||(r.x=l+d,r.y=s),d+=r.margin),t.width=t.width||_t.width,t.height=n.Y2.getMax(t.height||_t.height,_t.height),t.margin=t.margin||_t.actorMargin,h=n.Y2.getMax(h,t.height),a.get(t.name)&&(d+=t.width/2),t.x=l+d,t.starty=Pt.getVerticalPos(),Pt.insert(t.x,s,t.x+t.width,t.height),l+=t.width+d,t.box&&(t.box.width=l+r.margin-t.box.x),d=t.margin,c=t.box,Pt.models.addActor(t)}c&&!o&&Pt.models.addBox(c),Pt.bumpVerticalPos(h)}),"addActorRenderingData"),St=(0,n.K2)((async function(t,e,a,r){if(r){let r=0;Pt.bumpVerticalPos(2*_t.boxMargin);for(const s of a){const a=e.get(s);a.stopy||(a.stopy=Pt.getVerticalPos());const i=await Lt.drawActor(t,a,_t,!0);r=n.Y2.getMax(r,i)}Pt.bumpVerticalPos(r+_t.boxMargin)}else for(const s of a){const a=e.get(s);await Lt.drawActor(t,a,_t,!1)}}),"drawActors"),Kt=(0,n.K2)((function(t,e,a,r){let s=0,i=0;for(const n of a){const a=e.get(n),o=Wt(a),c=Lt.drawPopup(t,a,o,_t,_t.forceMenus,r);c.height>s&&(s=c.height),c.width+a.x>i&&(i=c.width+a.x)}return{maxHeight:s,maxWidth:i}}),"drawActorsPopup"),Rt=(0,n.K2)((function(t){(0,n.hH)(_t,t),t.fontFamily&&(_t.actorFontFamily=_t.noteFontFamily=_t.messageFontFamily=t.fontFamily),t.fontSize&&(_t.actorFontSize=_t.noteFontSize=_t.messageFontSize=t.fontSize),t.fontWeight&&(_t.actorFontWeight=_t.noteFontWeight=_t.messageFontWeight=t.fontWeight)}),"setConf"),Yt=(0,n.K2)((function(t){return Pt.activations.filter((function(e){return e.actor===t}))}),"actorActivations"),Ct=(0,n.K2)((function(t,e){const a=e.get(t),r=Yt(t);return[r.reduce((function(t,e){return n.Y2.getMin(t,e.startx)}),a.x+a.width/2-1),r.reduce((function(t,e){return n.Y2.getMax(t,e.stopx)}),a.x+a.width/2+1)]}),"activationBounds");function Bt(t,e,a,r,s){Pt.bumpVerticalPos(a);let o=r;if(e.id&&e.message&&t[e.id]){const a=t[e.id].width,s=At(_t);e.message=i._K.wrapLabel(`[${e.message}]`,a-2*_t.wrapPadding,s),e.width=a,e.wrap=!0;const c=i._K.calculateTextDimensions(e.message,s),l=n.Y2.getMax(c.height,_t.labelBoxHeight);o=r+l,n.Rm.debug(`${l} - ${e.message}`)}s(e),Pt.bumpVerticalPos(o)}function $t(t,e,a,r,s,i,o){function c(a,r){a.x<s.get(t.from).x?(Pt.insert(e.stopx-r,e.starty,e.startx,e.stopy+a.height/2+_t.noteMargin),e.stopx=e.stopx+r):(Pt.insert(e.startx,e.starty,e.stopx+r,e.stopy+a.height/2+_t.noteMargin),e.stopx=e.stopx-r)}function l(a,r){a.x<s.get(t.to).x?(Pt.insert(e.startx-r,e.starty,e.stopx,e.stopy+a.height/2+_t.noteMargin),e.startx=e.startx+r):(Pt.insert(e.stopx,e.starty,e.startx+r,e.stopy+a.height/2+_t.noteMargin),e.startx=e.startx-r)}if((0,n.K2)(c,"receiverAdjustment"),(0,n.K2)(l,"senderAdjustment"),i.get(t.to)==r){const e=s.get(t.to);c(e,"actor"==e.type?21:e.width/2+3),e.starty=a-e.height/2,Pt.bumpVerticalPos(e.height/2)}else if(o.get(t.from)==r){const e=s.get(t.from);if(_t.mirrorActors){l(e,"actor"==e.type?18:e.width/2)}e.stopy=a-e.height/2,Pt.bumpVerticalPos(e.height/2)}else if(o.get(t.to)==r){const e=s.get(t.to);if(_t.mirrorActors){c(e,"actor"==e.type?21:e.width/2+3)}e.stopy=a-e.height/2,Pt.bumpVerticalPos(e.height/2)}}(0,n.K2)(Bt,"adjustLoopHeightForWrap"),(0,n.K2)($t,"adjustCreatedDestroyedData");var Vt=(0,n.K2)((async function(t,e,a,r){const{securityLevel:s,sequence:i}=(0,n.D7)();let c;_t=i,"sandbox"===s&&(c=(0,o.Ltv)("#i"+e));const l="sandbox"===s?(0,o.Ltv)(c.nodes()[0].contentDocument.body):(0,o.Ltv)("body"),d="sandbox"===s?c.nodes()[0].contentDocument:document;Pt.init(),n.Rm.debug(r.db);const h="sandbox"===s?l.select(`[id="${e}"]`):(0,o.Ltv)(`[id="${e}"]`),p=r.db.getActors(),g=r.db.getCreatedActors(),u=r.db.getDestroyedActors(),x=r.db.getBoxes();let y=r.db.getActorKeys();const m=r.db.getMessages(),b=r.db.getDiagramTitle(),T=r.db.hasAtLeastOneBox(),f=r.db.hasAtLeastOneBoxWithTitle(),E=await Ft(p,m,r);if(_t.height=await qt(p,E,x),Lt.insertComputerIcon(h),Lt.insertDatabaseIcon(h),Lt.insertClockIcon(h),T&&(Pt.bumpVerticalPos(_t.boxMargin),f&&Pt.bumpVerticalPos(x[0].textMaxHeight)),!0===_t.hideUnusedParticipants){const t=new Set;m.forEach((e=>{t.add(e.from),t.add(e.to)})),y=y.filter((e=>t.has(e)))}Ot(h,p,g,y,0,m,!1);const w=await jt(m,p,E,r);function I(t,e){const a=Pt.endActivation(t);a.starty+18>e&&(a.starty=e-6,e+=12),Lt.drawActivation(h,a,e,_t,Yt(t.from).length),Pt.insert(a.startx,e-10,a.stopx,e)}Lt.insertArrowHead(h),Lt.insertArrowCrossHead(h),Lt.insertArrowFilledHead(h),Lt.insertSequenceNumber(h),(0,n.K2)(I,"activeEnd");let L=1,_=1;const P=[],k=[];let A=0;for(const o of m){let t,e,a;switch(o.type){case r.db.LINETYPE.NOTE:Pt.resetVerticalPos(),e=o.noteModel,await kt(h,e);break;case r.db.LINETYPE.ACTIVE_START:Pt.newActivation(o,h,p);break;case r.db.LINETYPE.ACTIVE_END:I(o,Pt.getVerticalPos());break;case r.db.LINETYPE.LOOP_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t)));break;case r.db.LINETYPE.LOOP_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"loop",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;case r.db.LINETYPE.RECT_START:Bt(w,o,_t.boxMargin,_t.boxMargin,(t=>Pt.newLoop(void 0,t.message)));break;case r.db.LINETYPE.RECT_END:t=Pt.endLoop(),k.push(t),Pt.models.addLoop(t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos());break;case r.db.LINETYPE.OPT_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t)));break;case r.db.LINETYPE.OPT_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"opt",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;case r.db.LINETYPE.ALT_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t)));break;case r.db.LINETYPE.ALT_ELSE:Bt(w,o,_t.boxMargin+_t.boxTextMargin,_t.boxMargin,(t=>Pt.addSectionToLoop(t)));break;case r.db.LINETYPE.ALT_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"alt",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t))),Pt.saveVerticalPos();break;case r.db.LINETYPE.PAR_AND:Bt(w,o,_t.boxMargin+_t.boxTextMargin,_t.boxMargin,(t=>Pt.addSectionToLoop(t)));break;case r.db.LINETYPE.PAR_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"par",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;case r.db.LINETYPE.AUTONUMBER:L=o.message.start||L,_=o.message.step||_,o.message.visible?r.db.enableSequenceNumbers():r.db.disableSequenceNumbers();break;case r.db.LINETYPE.CRITICAL_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t)));break;case r.db.LINETYPE.CRITICAL_OPTION:Bt(w,o,_t.boxMargin+_t.boxTextMargin,_t.boxMargin,(t=>Pt.addSectionToLoop(t)));break;case r.db.LINETYPE.CRITICAL_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"critical",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;case r.db.LINETYPE.BREAK_START:Bt(w,o,_t.boxMargin,_t.boxMargin+_t.boxTextMargin,(t=>Pt.newLoop(t)));break;case r.db.LINETYPE.BREAK_END:t=Pt.endLoop(),await Lt.drawLoop(h,t,"break",_t),Pt.bumpVerticalPos(t.stopy-Pt.getVerticalPos()),Pt.models.addLoop(t);break;default:try{a=o.msgModel,a.starty=Pt.getVerticalPos(),a.sequenceIndex=L,a.sequenceVisible=r.db.showSequenceNumbers();const t=await Mt(0,a);$t(o,a,t,A,p,g,u),P.push({messageModel:a,lineStartY:t}),Pt.models.addMessage(a)}catch(R){n.Rm.error("error while drawing message",R)}}[r.db.LINETYPE.SOLID_OPEN,r.db.LINETYPE.DOTTED_OPEN,r.db.LINETYPE.SOLID,r.db.LINETYPE.DOTTED,r.db.LINETYPE.SOLID_CROSS,r.db.LINETYPE.DOTTED_CROSS,r.db.LINETYPE.SOLID_POINT,r.db.LINETYPE.DOTTED_POINT,r.db.LINETYPE.BIDIRECTIONAL_SOLID,r.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(o.type)&&(L+=_),A++}n.Rm.debug("createdActors",g),n.Rm.debug("destroyedActors",u),await St(h,p,y,!1);for(const n of P)await Dt(h,n.messageModel,n.lineStartY,r);_t.mirrorActors&&await St(h,p,y,!0),k.forEach((t=>Lt.drawBackgroundRect(h,t))),st(h,p,y,_t);for(const n of Pt.models.boxes)n.height=Pt.getVerticalPos()-n.y,Pt.insert(n.x,n.y,n.x+n.width,n.height),n.startx=n.x,n.starty=n.y,n.stopx=n.startx+n.width,n.stopy=n.starty+n.height,n.stroke="rgb(0,0,0, 0.5)",Lt.drawBox(h,n,_t);T&&Pt.bumpVerticalPos(_t.boxMargin);const v=Kt(h,p,y,d),{bounds:N}=Pt.getBounds();void 0===N.startx&&(N.startx=0),void 0===N.starty&&(N.starty=0),void 0===N.stopx&&(N.stopx=0),void 0===N.stopy&&(N.stopy=0);let M=N.stopy-N.starty;M<v.maxHeight&&(M=v.maxHeight);let D=M+2*_t.diagramMarginY;_t.mirrorActors&&(D=D-_t.boxMargin+_t.bottomMarginAdj);let O=N.stopx-N.startx;O<v.maxWidth&&(O=v.maxWidth);const S=O+2*_t.diagramMarginX;b&&h.append("text").text(b).attr("x",(N.stopx-N.startx)/2-2*_t.diagramMarginX).attr("y",-25),(0,n.a$)(h,D,S,_t.useMaxWidth);const K=b?40:0;h.attr("viewBox",N.startx-_t.diagramMarginX+" -"+(_t.diagramMarginY+K)+" "+S+" "+(D+K)),n.Rm.debug("models:",Pt.models)}),"draw");async function Ft(t,e,a){const r={};for(const s of e)if(t.get(s.to)&&t.get(s.from)){const e=t.get(s.to);if(s.placement===a.db.PLACEMENT.LEFTOF&&!e.prevActor)continue;if(s.placement===a.db.PLACEMENT.RIGHTOF&&!e.nextActor)continue;const o=void 0!==s.placement,c=!o,l=o?vt(_t):At(_t),d=s.wrap?i._K.wrapLabel(s.message,_t.width-2*_t.wrapPadding,l):s.message,h=((0,n.Wi)(d)?await(0,n.Dl)(s.message,(0,n.D7)()):i._K.calculateTextDimensions(d,l)).width+2*_t.wrapPadding;c&&s.from===e.nextActor?r[s.to]=n.Y2.getMax(r[s.to]||0,h):c&&s.from===e.prevActor?r[s.from]=n.Y2.getMax(r[s.from]||0,h):c&&s.from===s.to?(r[s.from]=n.Y2.getMax(r[s.from]||0,h/2),r[s.to]=n.Y2.getMax(r[s.to]||0,h/2)):s.placement===a.db.PLACEMENT.RIGHTOF?r[s.from]=n.Y2.getMax(r[s.from]||0,h):s.placement===a.db.PLACEMENT.LEFTOF?r[e.prevActor]=n.Y2.getMax(r[e.prevActor]||0,h):s.placement===a.db.PLACEMENT.OVER&&(e.prevActor&&(r[e.prevActor]=n.Y2.getMax(r[e.prevActor]||0,h/2)),e.nextActor&&(r[s.from]=n.Y2.getMax(r[s.from]||0,h/2)))}return n.Rm.debug("maxMessageWidthPerActor:",r),r}(0,n.K2)(Ft,"getMaxMessageWidthPerActor");var Wt=(0,n.K2)((function(t){let e=0;const a=Nt(_t);for(const r in t.links){const t=i._K.calculateTextDimensions(r,a).width+2*_t.wrapPadding+2*_t.boxMargin;e<t&&(e=t)}return e}),"getRequiredPopupWidth");async function qt(t,e,a){let r=0;for(const o of t.keys()){const e=t.get(o);e.wrap&&(e.description=i._K.wrapLabel(e.description,_t.width-2*_t.wrapPadding,Nt(_t)));const a=(0,n.Wi)(e.description)?await(0,n.Dl)(e.description,(0,n.D7)()):i._K.calculateTextDimensions(e.description,Nt(_t));e.width=e.wrap?_t.width:n.Y2.getMax(_t.width,a.width+2*_t.wrapPadding),e.height=e.wrap?n.Y2.getMax(a.height,_t.height):_t.height,r=n.Y2.getMax(r,e.height)}for(const i in e){const a=t.get(i);if(!a)continue;const r=t.get(a.nextActor);if(!r){const t=e[i]+_t.actorMargin-a.width/2;a.margin=n.Y2.getMax(t,_t.actorMargin);continue}const s=e[i]+_t.actorMargin-a.width/2-r.width/2;a.margin=n.Y2.getMax(s,_t.actorMargin)}let s=0;return a.forEach((e=>{const a=At(_t);let r=e.actorKeys.reduce(((e,a)=>e+(t.get(a).width+(t.get(a).margin||0))),0);r-=2*_t.boxTextMargin,e.wrap&&(e.name=i._K.wrapLabel(e.name,r-2*_t.wrapPadding,a));const o=i._K.calculateTextDimensions(e.name,a);s=n.Y2.getMax(o.height,s);const c=n.Y2.getMax(r,o.width+2*_t.wrapPadding);if(e.margin=_t.boxTextMargin,r<c){const t=(c-r)/2;e.margin+=t}})),a.forEach((t=>t.textMaxHeight=s)),n.Y2.getMax(r,_t.height)}(0,n.K2)(qt,"calculateActorMargins");var zt=(0,n.K2)((async function(t,e,a){const r=e.get(t.from),s=e.get(t.to),o=r.x,c=s.x,l=t.wrap&&t.message;let d=(0,n.Wi)(t.message)?await(0,n.Dl)(t.message,(0,n.D7)()):i._K.calculateTextDimensions(l?i._K.wrapLabel(t.message,_t.width,vt(_t)):t.message,vt(_t));const h={width:l?_t.width:n.Y2.getMax(_t.width,d.width+2*_t.noteMargin),height:0,startx:r.x,stopx:0,starty:0,stopy:0,message:t.message};return t.placement===a.db.PLACEMENT.RIGHTOF?(h.width=l?n.Y2.getMax(_t.width,d.width):n.Y2.getMax(r.width/2+s.width/2,d.width+2*_t.noteMargin),h.startx=o+(r.width+_t.actorMargin)/2):t.placement===a.db.PLACEMENT.LEFTOF?(h.width=l?n.Y2.getMax(_t.width,d.width+2*_t.noteMargin):n.Y2.getMax(r.width/2+s.width/2,d.width+2*_t.noteMargin),h.startx=o-h.width+(r.width-_t.actorMargin)/2):t.to===t.from?(d=i._K.calculateTextDimensions(l?i._K.wrapLabel(t.message,n.Y2.getMax(_t.width,r.width),vt(_t)):t.message,vt(_t)),h.width=l?n.Y2.getMax(_t.width,r.width):n.Y2.getMax(r.width,_t.width,d.width+2*_t.noteMargin),h.startx=o+(r.width-h.width)/2):(h.width=Math.abs(o+r.width/2-(c+s.width/2))+_t.actorMargin,h.startx=o<c?o+r.width/2-_t.actorMargin/2:c+s.width/2-_t.actorMargin/2),l&&(h.message=i._K.wrapLabel(t.message,h.width-2*_t.wrapPadding,vt(_t))),n.Rm.debug(`NM:[${h.startx},${h.stopx},${h.starty},${h.stopy}:${h.width},${h.height}=${t.message}]`),h}),"buildNoteModel"),Ht=(0,n.K2)((function(t,e,a){if(![a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN,a.db.LINETYPE.SOLID,a.db.LINETYPE.DOTTED,a.db.LINETYPE.SOLID_CROSS,a.db.LINETYPE.DOTTED_CROSS,a.db.LINETYPE.SOLID_POINT,a.db.LINETYPE.DOTTED_POINT,a.db.LINETYPE.BIDIRECTIONAL_SOLID,a.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type))return{};const[r,s]=Ct(t.from,e),[o,c]=Ct(t.to,e),l=r<=o;let d=l?s:r,h=l?o:c;const p=Math.abs(o-c)>2,g=(0,n.K2)((t=>l?-t:t),"adjustValue");t.from===t.to?h=d:(t.activate&&!p&&(h+=g(_t.activationWidth/2-1)),[a.db.LINETYPE.SOLID_OPEN,a.db.LINETYPE.DOTTED_OPEN].includes(t.type)||(h+=g(3)),[a.db.LINETYPE.BIDIRECTIONAL_SOLID,a.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(t.type)&&(d-=g(3)));const u=[r,s,o,c],x=Math.abs(d-h);t.wrap&&t.message&&(t.message=i._K.wrapLabel(t.message,n.Y2.getMax(x+2*_t.wrapPadding,_t.width),At(_t)));const y=i._K.calculateTextDimensions(t.message,At(_t));return{width:n.Y2.getMax(t.wrap?0:y.width+2*_t.wrapPadding,x+2*_t.wrapPadding,_t.width),height:0,startx:d,stopx:h,starty:0,stopy:0,message:t.message,type:t.type,wrap:t.wrap,fromBounds:Math.min.apply(null,u),toBounds:Math.max.apply(null,u)}}),"buildMessageModel"),jt=(0,n.K2)((async function(t,e,a,r){const s={},o=[];let c,l,d;for(const h of t){switch(h.id=i._K.random({length:10}),h.type){case r.db.LINETYPE.LOOP_START:case r.db.LINETYPE.ALT_START:case r.db.LINETYPE.OPT_START:case r.db.LINETYPE.PAR_START:case r.db.LINETYPE.PAR_OVER_START:case r.db.LINETYPE.CRITICAL_START:case r.db.LINETYPE.BREAK_START:o.push({id:h.id,msg:h.message,from:Number.MAX_SAFE_INTEGER,to:Number.MIN_SAFE_INTEGER,width:0});break;case r.db.LINETYPE.ALT_ELSE:case r.db.LINETYPE.PAR_AND:case r.db.LINETYPE.CRITICAL_OPTION:h.message&&(c=o.pop(),s[c.id]=c,s[h.id]=c,o.push(c));break;case r.db.LINETYPE.LOOP_END:case r.db.LINETYPE.ALT_END:case r.db.LINETYPE.OPT_END:case r.db.LINETYPE.PAR_END:case r.db.LINETYPE.CRITICAL_END:case r.db.LINETYPE.BREAK_END:c=o.pop(),s[c.id]=c;break;case r.db.LINETYPE.ACTIVE_START:{const t=e.get(h.from?h.from:h.to.actor),a=Yt(h.from?h.from:h.to.actor).length,r=t.x+t.width/2+(a-1)*_t.activationWidth/2,s={startx:r,stopx:r+_t.activationWidth,actor:h.from,enabled:!0};Pt.activations.push(s)}break;case r.db.LINETYPE.ACTIVE_END:{const t=Pt.activations.map((t=>t.actor)).lastIndexOf(h.from);Pt.activations.splice(t,1).splice(0,1)}}void 0!==h.placement?(l=await zt(h,e,r),h.noteModel=l,o.forEach((t=>{c=t,c.from=n.Y2.getMin(c.from,l.startx),c.to=n.Y2.getMax(c.to,l.startx+l.width),c.width=n.Y2.getMax(c.width,Math.abs(c.from-c.to))-_t.labelBoxWidth}))):(d=Ht(h,e,r),h.msgModel=d,d.startx&&d.stopx&&o.length>0&&o.forEach((t=>{if(c=t,d.startx===d.stopx){const t=e.get(h.from),a=e.get(h.to);c.from=n.Y2.getMin(t.x-d.width/2,t.x-t.width/2,c.from),c.to=n.Y2.getMax(a.x+d.width/2,a.x+t.width/2,c.to),c.width=n.Y2.getMax(c.width,Math.abs(c.to-c.from))-_t.labelBoxWidth}else c.from=n.Y2.getMin(d.startx,c.from),c.to=n.Y2.getMax(d.stopx,c.to),c.width=n.Y2.getMax(c.width,d.width)-_t.labelBoxWidth})))}return Pt.activations=[],n.Rm.debug("Loop type widths:",s),s}),"calculateLoopBounds"),Ut={parser:d,db:H,renderer:{bounds:Pt,drawActors:St,drawActorsPopup:Kt,setConf:Rt,draw:Vt},styles:j,init:(0,n.K2)((({wrap:t})=>{H.setWrap(t)}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7060.28ce0df1.js b/pr-preview/pr-976/assets/js/7060.28ce0df1.js new file mode 100644 index 0000000000..940f28edf4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/7060.28ce0df1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7060],{27060:(t,n,e)=>{e.d(n,{diagram:()=>rt});var i=e(45567),s=e(20007);function r(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e>i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e>s||void 0===e&&s>=s)&&(e=s)}return e}function o(t){return t.target.depth}function c(t,n){return t.sourceLinks.length?t.depth:n-1}function a(t,n){let e=0;if(void 0===n)for(let i of t)(i=+i)&&(e+=i);else{let i=-1;for(let s of t)(s=+n(s,++i,t))&&(e+=s)}return e}function l(t,n){let e;if(void 0===n)for(const i of t)null!=i&&(e<i||void 0===e&&i>=i)&&(e=i);else{let i=-1;for(let s of t)null!=(s=n(s,++i,t))&&(e<s||void 0===e&&s>=s)&&(e=s)}return e}function h(t){return function(){return t}}function u(t,n){return y(t.source,n.source)||t.index-n.index}function f(t,n){return y(t.target,n.target)||t.index-n.index}function y(t,n){return t.y0-n.y0}function d(t){return t.value}function p(t){return t.index}function g(t){return t.nodes}function _(t){return t.links}function k(t,n){const e=t.get(n);if(!e)throw new Error("missing: "+n);return e}function x({nodes:t}){for(const n of t){let t=n.y0,e=t;for(const i of n.sourceLinks)i.y0=t+i.width/2,t+=i.width;for(const i of n.targetLinks)i.y1=e+i.width/2,e+=i.width}}function m(){let t,n,e,i=0,s=0,o=1,m=1,v=24,b=8,w=p,L=c,S=g,E=_,A=6;function K(){const c={nodes:S.apply(null,arguments),links:E.apply(null,arguments)};return function({nodes:t,links:n}){for(const[e,s]of t.entries())s.index=e,s.sourceLinks=[],s.targetLinks=[];const i=new Map(t.map(((n,e)=>[w(n,e,t),n])));for(const[e,s]of n.entries()){s.index=e;let{source:t,target:n}=s;"object"!=typeof t&&(t=s.source=k(i,t)),"object"!=typeof n&&(n=s.target=k(i,n)),t.sourceLinks.push(s),n.targetLinks.push(s)}if(null!=e)for(const{sourceLinks:s,targetLinks:r}of t)s.sort(e),r.sort(e)}(c),function({nodes:t}){for(const n of t)n.value=void 0===n.fixedValue?Math.max(a(n.sourceLinks,d),a(n.targetLinks,d)):n.fixedValue}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.depth=s;for(const{target:n}of t.sourceLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function({nodes:t}){const n=t.length;let e=new Set(t),i=new Set,s=0;for(;e.size;){for(const t of e){t.height=s;for(const{source:n}of t.targetLinks)i.add(n)}if(++s>n)throw new Error("circular link");e=i,i=new Set}}(c),function(e){const c=function({nodes:t}){const e=l(t,(t=>t.depth))+1,s=(o-i-v)/(e-1),r=new Array(e);for(const n of t){const t=Math.max(0,Math.min(e-1,Math.floor(L.call(null,n,e))));n.layer=t,n.x0=i+t*s,n.x1=n.x0+v,r[t]?r[t].push(n):r[t]=[n]}if(n)for(const i of r)i.sort(n);return r}(e);t=Math.min(b,(m-s)/(l(c,(t=>t.length))-1)),function(n){const e=r(n,(n=>(m-s-(n.length-1)*t)/a(n,d)));for(const i of n){let n=s;for(const s of i){s.y0=n,s.y1=n+s.value*e,n=s.y1+t;for(const t of s.sourceLinks)t.width=t.value*e}n=(m-n+t)/(i.length+1);for(let t=0;t<i.length;++t){const e=i[t];e.y0+=n*(t+1),e.y1+=n*(t+1)}C(i)}}(c);for(let t=0;t<A;++t){const n=Math.pow(.99,t),e=Math.max(1-n,(t+1)/A);I(c,n,e),M(c,n,e)}}(c),x(c),c}function M(t,e,i){for(let s=1,r=t.length;s<r;++s){const r=t[s];for(const t of r){let n=0,i=0;for(const{source:e,value:r}of t.targetLinks){let s=r*(t.layer-e.layer);n+=O(e,t)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),T(r,i)}}function I(t,e,i){for(let s=t.length-2;s>=0;--s){const r=t[s];for(const t of r){let n=0,i=0;for(const{target:e,value:r}of t.sourceLinks){let s=r*(e.layer-t.layer);n+=$(t,e)*s,i+=s}if(!(i>0))continue;let s=(n/i-t.y0)*e;t.y0+=s,t.y1+=s,P(t)}void 0===n&&r.sort(y),T(r,i)}}function T(n,e){const i=n.length>>1,r=n[i];N(n,r.y0-t,i-1,e),D(n,r.y1+t,i+1,e),N(n,m,n.length-1,e),D(n,s,0,e)}function D(n,e,i,s){for(;i<n.length;++i){const r=n[i],o=(e-r.y0)*s;o>1e-6&&(r.y0+=o,r.y1+=o),e=r.y1+t}}function N(n,e,i,s){for(;i>=0;--i){const r=n[i],o=(r.y1-e)*s;o>1e-6&&(r.y0-=o,r.y1-=o),e=r.y0-t}}function P({sourceLinks:t,targetLinks:n}){if(void 0===e){for(const{source:{sourceLinks:t}}of n)t.sort(f);for(const{target:{targetLinks:n}}of t)n.sort(u)}}function C(t){if(void 0===e)for(const{sourceLinks:n,targetLinks:e}of t)n.sort(f),e.sort(u)}function O(n,e){let i=n.y0-(n.sourceLinks.length-1)*t/2;for(const{target:s,width:r}of n.sourceLinks){if(s===e)break;i+=r+t}for(const{source:t,width:s}of e.targetLinks){if(t===n)break;i-=s}return i}function $(n,e){let i=e.y0-(e.targetLinks.length-1)*t/2;for(const{source:s,width:r}of e.targetLinks){if(s===n)break;i+=r+t}for(const{target:t,width:s}of n.sourceLinks){if(t===e)break;i-=s}return i}return K.update=function(t){return x(t),t},K.nodeId=function(t){return arguments.length?(w="function"==typeof t?t:h(t),K):w},K.nodeAlign=function(t){return arguments.length?(L="function"==typeof t?t:h(t),K):L},K.nodeSort=function(t){return arguments.length?(n=t,K):n},K.nodeWidth=function(t){return arguments.length?(v=+t,K):v},K.nodePadding=function(n){return arguments.length?(b=t=+n,K):b},K.nodes=function(t){return arguments.length?(S="function"==typeof t?t:h(t),K):S},K.links=function(t){return arguments.length?(E="function"==typeof t?t:h(t),K):E},K.linkSort=function(t){return arguments.length?(e=t,K):e},K.size=function(t){return arguments.length?(i=s=0,o=+t[0],m=+t[1],K):[o-i,m-s]},K.extent=function(t){return arguments.length?(i=+t[0][0],o=+t[1][0],s=+t[0][1],m=+t[1][1],K):[[i,s],[o,m]]},K.iterations=function(t){return arguments.length?(A=+t,K):A},K}var v=Math.PI,b=2*v,w=1e-6,L=b-w;function S(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function E(){return new S}S.prototype=E.prototype={constructor:S,moveTo:function(t,n){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,n){this._+="L"+(this._x1=+t)+","+(this._y1=+n)},quadraticCurveTo:function(t,n,e,i){this._+="Q"+ +t+","+ +n+","+(this._x1=+e)+","+(this._y1=+i)},bezierCurveTo:function(t,n,e,i,s,r){this._+="C"+ +t+","+ +n+","+ +e+","+ +i+","+(this._x1=+s)+","+(this._y1=+r)},arcTo:function(t,n,e,i,s){t=+t,n=+n,e=+e,i=+i,s=+s;var r=this._x1,o=this._y1,c=e-t,a=i-n,l=r-t,h=o-n,u=l*l+h*h;if(s<0)throw new Error("negative radius: "+s);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=n);else if(u>w)if(Math.abs(h*c-a*l)>w&&s){var f=e-r,y=i-o,d=c*c+a*a,p=f*f+y*y,g=Math.sqrt(d),_=Math.sqrt(u),k=s*Math.tan((v-Math.acos((d+u-p)/(2*g*_)))/2),x=k/_,m=k/g;Math.abs(x-1)>w&&(this._+="L"+(t+x*l)+","+(n+x*h)),this._+="A"+s+","+s+",0,0,"+ +(h*f>l*y)+","+(this._x1=t+m*c)+","+(this._y1=n+m*a)}else this._+="L"+(this._x1=t)+","+(this._y1=n);else;},arc:function(t,n,e,i,s,r){t=+t,n=+n,r=!!r;var o=(e=+e)*Math.cos(i),c=e*Math.sin(i),a=t+o,l=n+c,h=1^r,u=r?i-s:s-i;if(e<0)throw new Error("negative radius: "+e);null===this._x1?this._+="M"+a+","+l:(Math.abs(this._x1-a)>w||Math.abs(this._y1-l)>w)&&(this._+="L"+a+","+l),e&&(u<0&&(u=u%b+b),u>L?this._+="A"+e+","+e+",0,1,"+h+","+(t-o)+","+(n-c)+"A"+e+","+e+",0,1,"+h+","+(this._x1=a)+","+(this._y1=l):u>w&&(this._+="A"+e+","+e+",0,"+ +(u>=v)+","+h+","+(this._x1=t+e*Math.cos(s))+","+(this._y1=n+e*Math.sin(s))))},rect:function(t,n,e,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+n)+"h"+ +e+"v"+ +i+"h"+-e+"Z"},toString:function(){return this._}};const A=E;var K=Array.prototype.slice;function M(t){return function(){return t}}function I(t){return t[0]}function T(t){return t[1]}function D(t){return t.source}function N(t){return t.target}function P(t){var n=D,e=N,i=I,s=T,r=null;function o(){var o,c=K.call(arguments),a=n.apply(this,c),l=e.apply(this,c);if(r||(r=o=A()),t(r,+i.apply(this,(c[0]=a,c)),+s.apply(this,c),+i.apply(this,(c[0]=l,c)),+s.apply(this,c)),o)return r=null,o+""||null}return o.source=function(t){return arguments.length?(n=t,o):n},o.target=function(t){return arguments.length?(e=t,o):e},o.x=function(t){return arguments.length?(i="function"==typeof t?t:M(+t),o):i},o.y=function(t){return arguments.length?(s="function"==typeof t?t:M(+t),o):s},o.context=function(t){return arguments.length?(r=null==t?null:t,o):r},o}function C(t,n,e,i,s){t.moveTo(n,e),t.bezierCurveTo(n=(n+i)/2,e,n,s,i,s)}function O(t){return[t.source.x1,t.y0]}function $(t){return[t.target.x0,t.y1]}function j(){return P(C).source(O).target($)}var z=function(){var t=(0,i.K2)((function(t,n,e,i){for(e=e||{},i=t.length;i--;e[t[i]]=n);return e}),"o"),n=[1,9],e=[1,10],s=[1,5,10,12],r={trace:(0,i.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:(0,i.K2)((function(t,n,e,i,s,r,o){var c=r.length-1;switch(s){case 7:const t=i.findOrCreateNode(r[c-4].trim().replaceAll('""','"')),n=i.findOrCreateNode(r[c-2].trim().replaceAll('""','"')),e=parseFloat(r[c].trim());i.addLink(t,n,e);break;case 8:case 9:case 11:this.$=r[c];break;case 10:this.$=r[c-1]}}),"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:n,20:e},{1:[2,6],7:11,10:[1,12]},t(e,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(s,[2,8]),t(s,[2,9]),{19:[1,16]},t(s,[2,11]),{1:[2,1]},{1:[2,5]},t(e,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:n,20:e},{15:18,16:7,17:8,18:n,20:e},{18:[1,19]},t(e,[2,3]),{12:[1,20]},t(s,[2,10]),{15:21,16:7,17:8,18:n,20:e},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:(0,i.K2)((function(t,n){if(!n.recoverable){var e=new Error(t);throw e.hash=n,e}this.trace(t)}),"parseError"),parse:(0,i.K2)((function(t){var n=this,e=[0],s=[],r=[null],o=[],c=this.table,a="",l=0,h=0,u=0,f=o.slice.call(arguments,1),y=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);y.setInput(t,d.yy),d.yy.lexer=y,d.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var g=y.yylloc;o.push(g);var _=y.options&&y.options.ranges;function k(){var t;return"number"!=typeof(t=s.pop()||y.lex()||1)&&(t instanceof Array&&(t=(s=t).pop()),t=n.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,i.K2)((function(t){e.length=e.length-2*t,r.length=r.length-t,o.length=o.length-t}),"popStack"),(0,i.K2)(k,"lex");for(var x,m,v,b,w,L,S,E,A,K={};;){if(v=e[e.length-1],this.defaultActions[v]?b=this.defaultActions[v]:(null==x&&(x=k()),b=c[v]&&c[v][x]),void 0===b||!b.length||!b[0]){var M="";for(L in A=[],c[v])this.terminals_[L]&&L>2&&A.push("'"+this.terminals_[L]+"'");M=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[x]||x)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==x?"end of input":"'"+(this.terminals_[x]||x)+"'"),this.parseError(M,{text:y.match,token:this.terminals_[x]||x,line:y.yylineno,loc:g,expected:A})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+x);switch(b[0]){case 1:e.push(x),r.push(y.yytext),o.push(y.yylloc),e.push(b[1]),x=null,m?(x=m,m=null):(h=y.yyleng,a=y.yytext,l=y.yylineno,g=y.yylloc,u>0&&u--);break;case 2:if(S=this.productions_[b[1]][1],K.$=r[r.length-S],K._$={first_line:o[o.length-(S||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(S||1)].first_column,last_column:o[o.length-1].last_column},_&&(K._$.range=[o[o.length-(S||1)].range[0],o[o.length-1].range[1]]),void 0!==(w=this.performAction.apply(K,[a,h,l,d.yy,b[1],r,o].concat(f))))return w;S&&(e=e.slice(0,-1*S*2),r=r.slice(0,-1*S),o=o.slice(0,-1*S)),e.push(this.productions_[b[1]][0]),r.push(K.$),o.push(K._$),E=c[e[e.length-2]][e[e.length-1]],e.push(E);break;case 3:return!0}}return!0}),"parse")},o=function(){return{EOF:1,parseError:(0,i.K2)((function(t,n){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,n)}),"parseError"),setInput:(0,i.K2)((function(t,n){return this.yy=n||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,i.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,i.K2)((function(t){var n=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===i.length?this.yylloc.first_column:0)+i[i.length-e.length].length-e[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,i.K2)((function(){return this._more=!0,this}),"more"),reject:(0,i.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,i.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,i.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,i.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,i.K2)((function(){var t=this.pastInput(),n=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+n+"^"}),"showPosition"),test_match:(0,i.K2)((function(t,n){var e,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,n,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1}),"test_match"),next:(0,i.K2)((function(){if(this.done)return this.EOF;var t,n,e,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((e=this._input.match(this.rules[s[r]]))&&(!n||e[0].length>n[0].length)){if(n=e,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,s[r])))return t;if(this._backtrack){n=!1;continue}return!1}if(!this.options.flex)break}return n?!1!==(t=this.test_match(n,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,i.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,i.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,i.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,i.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,i.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,i.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,i.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,i.K2)((function(t,n,e,i){switch(e){case 0:return this.pushState("csv"),4;case 1:return 10;case 2:return 5;case 3:return 12;case 4:return this.pushState("escaped_text"),18;case 5:return 20;case 6:return this.popState("escaped_text"),18;case 7:return 19}}),"anonymous"),rules:[/^(?:sankey-beta\b)/i,/^(?:$)/i,/^(?:((\u000D\u000A)|(\u000A)))/i,/^(?:(\u002C))/i,/^(?:(\u0022))/i,/^(?:([\u0020-\u0021\u0023-\u002B\u002D-\u007E])*)/i,/^(?:(\u0022)(?!(\u0022)))/i,/^(?:(([\u0020-\u0021\u0023-\u002B\u002D-\u007E])|(\u002C)|(\u000D)|(\u000A)|(\u0022)(\u0022))*)/i],conditions:{csv:{rules:[1,2,3,4,5,6,7],inclusive:!1},escaped_text:{rules:[6,7],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7],inclusive:!0}}}}();function c(){this.yy={}}return r.lexer=o,(0,i.K2)(c,"Parser"),c.prototype=r,r.Parser=c,new c}();z.parser=z;var U=z,F=[],W=[],G=new Map,V=(0,i.K2)((()=>{F=[],W=[],G=new Map,(0,i.IU)()}),"clear"),X=class{constructor(t,n,e=0){this.source=t,this.target=n,this.value=e}static{(0,i.K2)(this,"SankeyLink")}},Y=(0,i.K2)(((t,n,e)=>{F.push(new X(t,n,e))}),"addLink"),q=class{constructor(t){this.ID=t}static{(0,i.K2)(this,"SankeyNode")}},Q=(0,i.K2)((t=>{t=i.Y2.sanitizeText(t,(0,i.D7)());let n=G.get(t);return void 0===n&&(n=new q(t),G.set(t,n),W.push(n)),n}),"findOrCreateNode"),R=(0,i.K2)((()=>W),"getNodes"),B=(0,i.K2)((()=>F),"getLinks"),Z=(0,i.K2)((()=>({nodes:W.map((t=>({id:t.ID}))),links:F.map((t=>({source:t.source.ID,target:t.target.ID,value:t.value})))})),"getGraph"),H={nodesMap:G,getConfig:(0,i.K2)((()=>(0,i.D7)().sankey),"getConfig"),getNodes:R,getLinks:B,getGraph:Z,addLink:Y,findOrCreateNode:Q,getAccTitle:i.iN,setAccTitle:i.SV,getAccDescription:i.m7,setAccDescription:i.EI,getDiagramTitle:i.ab,setDiagramTitle:i.ke,clear:V},J=class t{static{(0,i.K2)(this,"Uid")}static{this.count=0}static next(n){return new t(n+ ++t.count)}constructor(t){this.id=t,this.href=`#${t}`}toString(){return"url("+this.href+")"}},tt={left:function(t){return t.depth},right:function(t,n){return n-1-t.height},center:function(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?r(t.sourceLinks,o)-1:0},justify:c},nt=(0,i.K2)((function(t,n,e,r){const{securityLevel:o,sankey:c}=(0,i.D7)(),a=i.ME.sankey;let l;"sandbox"===o&&(l=(0,s.Ltv)("#i"+n));const h="sandbox"===o?(0,s.Ltv)(l.nodes()[0].contentDocument.body):(0,s.Ltv)("body"),u="sandbox"===o?h.select(`[id="${n}"]`):(0,s.Ltv)(`[id="${n}"]`),f=c?.width??a.width,y=c?.height??a.width,d=c?.useMaxWidth??a.useMaxWidth,p=c?.nodeAlignment??a.nodeAlignment,g=c?.prefix??a.prefix,_=c?.suffix??a.suffix,k=c?.showValues??a.showValues,x=r.db.getGraph(),v=tt[p];m().nodeId((t=>t.id)).nodeWidth(10).nodePadding(10+(k?15:0)).nodeAlign(v).extent([[0,0],[f,y]])(x);const b=(0,s.UMr)(s.zt);u.append("g").attr("class","nodes").selectAll(".node").data(x.nodes).join("g").attr("class","node").attr("id",(t=>(t.uid=J.next("node-")).id)).attr("transform",(function(t){return"translate("+t.x0+","+t.y0+")"})).attr("x",(t=>t.x0)).attr("y",(t=>t.y0)).append("rect").attr("height",(t=>t.y1-t.y0)).attr("width",(t=>t.x1-t.x0)).attr("fill",(t=>b(t.id)));const w=(0,i.K2)((({id:t,value:n})=>k?`${t}\n${g}${Math.round(100*n)/100}${_}`:t),"getText");u.append("g").attr("class","node-labels").attr("font-family","sans-serif").attr("font-size",14).selectAll("text").data(x.nodes).join("text").attr("x",(t=>t.x0<f/2?t.x1+6:t.x0-6)).attr("y",(t=>(t.y1+t.y0)/2)).attr("dy",(k?"0":"0.35")+"em").attr("text-anchor",(t=>t.x0<f/2?"start":"end")).text(w);const L=u.append("g").attr("class","links").attr("fill","none").attr("stroke-opacity",.5).selectAll(".link").data(x.links).join("g").attr("class","link").style("mix-blend-mode","multiply"),S=c?.linkColor??"gradient";if("gradient"===S){const t=L.append("linearGradient").attr("id",(t=>(t.uid=J.next("linearGradient-")).id)).attr("gradientUnits","userSpaceOnUse").attr("x1",(t=>t.source.x1)).attr("x2",(t=>t.target.x0));t.append("stop").attr("offset","0%").attr("stop-color",(t=>b(t.source.id))),t.append("stop").attr("offset","100%").attr("stop-color",(t=>b(t.target.id)))}let E;switch(S){case"gradient":E=(0,i.K2)((t=>t.uid),"coloring");break;case"source":E=(0,i.K2)((t=>b(t.source.id)),"coloring");break;case"target":E=(0,i.K2)((t=>b(t.target.id)),"coloring");break;default:E=S}L.append("path").attr("d",j()).attr("stroke",E).attr("stroke-width",(t=>Math.max(1,t.width))),(0,i.ot)(void 0,u,0,d)}),"draw"),et={draw:nt},it=(0,i.K2)((t=>t.replaceAll(/^[^\S\n\r]+|[^\S\n\r]+$/g,"").replaceAll(/([\n\r])+/g,"\n").trim()),"prepareTextForParsing"),st=U.parse.bind(U);U.parse=t=>st(it(t));var rt={parser:U,db:H,renderer:et}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7357.6aa95f42.js b/pr-preview/pr-976/assets/js/7357.6aa95f42.js new file mode 100644 index 0000000000..10b856ebdd --- /dev/null +++ b/pr-preview/pr-976/assets/js/7357.6aa95f42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7357],{77357:(t,e,n)=>{n.d(e,{diagram:()=>J});var i=n(45567),s=n(20007),r=n(3219),a=n(78041),o=n(75263),c=function(){var t=(0,i.K2)((function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n}),"o"),e=[6,8,10,11,12,14,16,17,20,21],n=[1,9],s=[1,10],r=[1,11],a=[1,12],o=[1,13],c=[1,16],l=[1,17],h={trace:(0,i.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,timeline:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,period_statement:18,event_statement:19,period:20,event:21,$accept:0,$end:1},terminals_:{2:"error",4:"timeline",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",20:"period",21:"event"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[18,1],[19,1]],performAction:(0,i.K2)((function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.getCommonDb().setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.getCommonDb().setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.getCommonDb().setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 15:i.addTask(r[o],0,""),this.$=r[o];break;case 16:i.addEvent(r[o].substr(2)),this.$=r[o]}}),"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:s,14:r,16:a,17:o,18:14,19:15,20:c,21:l},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:18,11:n,12:s,14:r,16:a,17:o,18:14,19:15,20:c,21:l},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,19]},{15:[1,20]},t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),t(e,[2,4]),t(e,[2,9]),t(e,[2,10])],defaultActions:{},parseError:(0,i.K2)((function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)}),"parseError"),parse:(0,i.K2)((function(t){var e=this,n=[0],s=[],r=[null],a=[],o=this.table,c="",l=0,h=0,d=0,u=a.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;a.push(f);var m=p.options&&p.options.ranges;function x(){var t;return"number"!=typeof(t=s.pop()||p.lex()||1)&&(t instanceof Array&&(t=(s=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,i.K2)((function(t){n.length=n.length-2*t,r.length=r.length-t,a.length=a.length-t}),"popStack"),(0,i.K2)(x,"lex");for(var b,k,_,w,v,K,S,$,E,T={};;){if(_=n[n.length-1],this.defaultActions[_]?w=this.defaultActions[_]:(null==b&&(b=x()),w=o[_]&&o[_][b]),void 0===w||!w.length||!w[0]){var I="";for(K in E=[],o[_])this.terminals_[K]&&K>2&&E.push("'"+this.terminals_[K]+"'");I=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+E.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(I,{text:p.match,token:this.terminals_[b]||b,line:p.yylineno,loc:f,expected:E})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+_+", token: "+b);switch(w[0]){case 1:n.push(b),r.push(p.yytext),a.push(p.yylloc),n.push(w[1]),b=null,k?(b=k,k=null):(h=p.yyleng,c=p.yytext,l=p.yylineno,f=p.yylloc,d>0&&d--);break;case 2:if(S=this.productions_[w[1]][1],T.$=r[r.length-S],T._$={first_line:a[a.length-(S||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(S||1)].first_column,last_column:a[a.length-1].last_column},m&&(T._$.range=[a[a.length-(S||1)].range[0],a[a.length-1].range[1]]),void 0!==(v=this.performAction.apply(T,[c,h,l,y.yy,w[1],r,a].concat(u))))return v;S&&(n=n.slice(0,-1*S*2),r=r.slice(0,-1*S),a=a.slice(0,-1*S)),n.push(this.productions_[w[1]][0]),r.push(T.$),a.push(T._$),$=o[n[n.length-2]][n[n.length-1]],n.push($);break;case 3:return!0}}return!0}),"parse")},d=function(){return{EOF:1,parseError:(0,i.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,i.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,i.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,i.K2)((function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,i.K2)((function(){return this._more=!0,this}),"more"),reject:(0,i.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,i.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,i.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,i.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,i.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,i.K2)((function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1}),"test_match"),next:(0,i.K2)((function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,i.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,i.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,i.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,i.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,i.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,i.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,i.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,i.K2)((function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 21;case 16:return 20;case 17:return 6;case 18:return"INVALID"}}),"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:timeline\b)/i,/^(?:title\s[^\n]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^:\n]+)/i,/^(?::\s[^:\n]+)/i,/^(?:[^#:\n]+)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18],inclusive:!0}}}}();function u(){this.yy={}}return h.lexer=d,(0,i.K2)(u,"Parser"),u.prototype=h,h.Parser=u,new u}();c.parser=c;var l=c,h={};(0,i.VA)(h,{addEvent:()=>w,addSection:()=>x,addTask:()=>_,addTaskOrg:()=>v,clear:()=>m,default:()=>S,getCommonDb:()=>f,getSections:()=>b,getTasks:()=>k});var d="",u=0,p=[],y=[],g=[],f=(0,i.K2)((()=>i.Wt),"getCommonDb"),m=(0,i.K2)((function(){p.length=0,y.length=0,d="",g.length=0,(0,i.IU)()}),"clear"),x=(0,i.K2)((function(t){d=t,p.push(t)}),"addSection"),b=(0,i.K2)((function(){return p}),"getSections"),k=(0,i.K2)((function(){let t=K();let e=0;for(;!t&&e<100;)t=K(),e++;return y.push(...g),y}),"getTasks"),_=(0,i.K2)((function(t,e,n){const i={id:u++,section:d,type:d,task:t,score:e||0,events:n?[n]:[]};g.push(i)}),"addTask"),w=(0,i.K2)((function(t){g.find((t=>t.id===u-1)).events.push(t)}),"addEvent"),v=(0,i.K2)((function(t){const e={section:d,type:d,description:t,task:t,classes:[]};y.push(e)}),"addTaskOrg"),K=(0,i.K2)((function(){const t=(0,i.K2)((function(t){return g[t].processed}),"compileTask");let e=!0;for(const[n,i]of g.entries())t(n),e=e&&i.processed;return e}),"compileTasks"),S={clear:m,getCommonDb:f,addSection:x,getSections:b,getTasks:k,addTask:_,addTaskOrg:v,addEvent:w},$=(0,i.K2)((function(t,e){const n=t.append("rect");return n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),n.attr("rx",e.rx),n.attr("ry",e.ry),void 0!==e.class&&n.attr("class",e.class),n}),"drawRect"),E=(0,i.K2)((function(t,e){const n=15,r=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),a=t.append("g");function o(t){const i=(0,s.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}function c(t){const i=(0,s.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}function l(t){t.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return a.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),a.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),(0,i.K2)(o,"smile"),(0,i.K2)(c,"sad"),(0,i.K2)(l,"ambivalent"),e.score>3?o(a):e.score<3?c(a):l(a),r}),"drawFace"),T=(0,i.K2)((function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n}),"drawCircle"),I=(0,i.K2)((function(t,e){const n=e.text.replace(/<br\s*\/?>/gi," "),i=t.append("text");i.attr("x",e.x),i.attr("y",e.y),i.attr("class","legend"),i.style("text-anchor",e.anchor),void 0!==e.class&&i.attr("class",e.class);const s=i.append("tspan");return s.attr("x",e.x+2*e.textMargin),s.text(n),i}),"drawText"),R=(0,i.K2)((function(t,e){function n(t,e,n,i,s){return t+","+e+" "+(t+n)+","+e+" "+(t+n)+","+(e+i-s)+" "+(t+n-1.2*s)+","+(e+i)+" "+t+","+(e+i)}(0,i.K2)(n,"genPoints");const s=t.append("polygon");s.attr("points",n(e.x,e.y,50,20,7)),s.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,I(t,e)}),"drawLabel"),A=(0,i.K2)((function(t,e,n){const i=t.append("g"),s=P();s.x=e.x,s.y=e.y,s.fill=e.fill,s.width=n.width,s.height=n.height,s.class="journey-section section-type-"+e.num,s.rx=3,s.ry=3,$(i,s),H(n)(e.text,i,s.x,s.y,s.width,s.height,{class:"journey-section section-type-"+e.num},n,e.colour)}),"drawSection"),L=-1,M=(0,i.K2)((function(t,e,n){const i=e.x+n.width/2,s=t.append("g");L++;s.append("line").attr("id","task"+L).attr("x1",i).attr("y1",e.y).attr("x2",i).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),E(s,{cx:i,cy:300+30*(5-e.score),score:e.score});const r=P();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width,r.height=n.height,r.class="task task-type-"+e.num,r.rx=3,r.ry=3,$(s,r),H(n)(e.task,s,r.x,r.y,r.width,r.height,{class:"task"},n,e.colour)}),"drawTask"),C=(0,i.K2)((function(t,e){$(t,{x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,class:"rect"}).lower()}),"drawBackgroundRect"),N=(0,i.K2)((function(){return{x:0,y:0,fill:void 0,"text-anchor":"start",width:100,height:100,textMargin:0,rx:0,ry:0}}),"getTextObj"),P=(0,i.K2)((function(){return{x:0,y:0,width:100,anchor:"start",height:100,rx:0,ry:0}}),"getNoteRect"),H=function(){function t(t,e,n,i,r,a,o,c){s(e.append("text").attr("x",n+r/2).attr("y",i+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,i,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:d}=c,u=t.split(/<br\s*\/?>/gi);for(let p=0;p<u.length;p++){const t=p*h-h*(u.length-1)/2,c=e.append("text").attr("x",n+r/2).attr("y",i).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",d);c.append("tspan").attr("x",n+r/2).attr("dy",t).text(u[p]),c.attr("y",i+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),s(c,o)}}function n(t,n,i,r,a,o,c,l){const h=n.append("switch"),d=h.append("foreignObject").attr("x",i).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");d.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,i,r,a,o,c,l),s(d,c)}function s(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return(0,i.K2)(t,"byText"),(0,i.K2)(e,"byTspan"),(0,i.K2)(n,"byFo"),(0,i.K2)(s,"_setTextAttrs"),function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),O=(0,i.K2)((function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")}),"initGraphics");function j(t,e){t.each((function(){var t,n=(0,s.Ltv)(this),i=n.text().split(/(\s+|<br>)/).reverse(),r=[],a=n.attr("y"),o=parseFloat(n.attr("dy")),c=n.text(null).append("tspan").attr("x",0).attr("y",a).attr("dy",o+"em");for(let s=0;s<i.length;s++)t=i[i.length-1-s],r.push(t),c.text(r.join(" ").trim()),(c.node().getComputedTextLength()>e||"<br>"===t)&&(r.pop(),c.text(r.join(" ").trim()),r="<br>"===t?[""]:[t],c=n.append("tspan").attr("x",0).attr("y",a).attr("dy","1.1em").text(t))}))}(0,i.K2)(j,"wrap");var D=(0,i.K2)((function(t,e,n,i){const s=n%12-1,r=t.append("g");e.section=s,r.attr("class",(e.class?e.class+" ":"")+"timeline-node section-"+s);const a=r.append("g"),o=r.append("g"),c=o.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(j,e.width).node().getBBox(),l=i.fontSize?.replace?i.fontSize.replace("px",""):i.fontSize;return e.height=c.height+1.1*l*.5+e.padding,e.height=Math.max(e.height,e.maxHeight),e.width=e.width+2*e.padding,o.attr("transform","translate("+e.width/2+", "+e.padding/2+")"),W(a,e,s,i),e}),"drawNode"),z=(0,i.K2)((function(t,e,n){const i=t.append("g"),s=i.append("text").text(e.descr).attr("dy","1em").attr("alignment-baseline","middle").attr("dominant-baseline","middle").attr("text-anchor","middle").call(j,e.width).node().getBBox(),r=n.fontSize?.replace?n.fontSize.replace("px",""):n.fontSize;return i.remove(),s.height+1.1*r*.5+e.padding}),"getVirtualNodeHeight"),W=(0,i.K2)((function(t,e,n){t.append("path").attr("id","node-"+e.id).attr("class","node-bkg node-"+e.type).attr("d",`M0 ${e.height-5} v${10-e.height} q0,-5 5,-5 h${e.width-10} q5,0 5,5 v${e.height-5} H0 Z`),t.append("line").attr("class","node-line-"+n).attr("x1",0).attr("y1",e.height).attr("x2",e.width).attr("y2",e.height)}),"defaultBkg"),B={drawRect:$,drawCircle:T,drawSection:A,drawText:I,drawLabel:R,drawTask:M,drawBackgroundRect:C,getTextObj:N,getNoteRect:P,initGraphics:O,drawNode:D,getVirtualNodeHeight:z},F=(0,i.K2)((function(t,e,n,r){const a=(0,i.D7)(),o=a.leftMargin??50;i.Rm.debug("timeline",r.db);const c=a.securityLevel;let l;"sandbox"===c&&(l=(0,s.Ltv)("#i"+e));const h=("sandbox"===c?(0,s.Ltv)(l.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select("#"+e);h.append("g");const d=r.db.getTasks(),u=r.db.getCommonDb().getDiagramTitle();i.Rm.debug("task",d),B.initGraphics(h);const p=r.db.getSections();i.Rm.debug("sections",p);let y=0,g=0,f=0,m=0,x=50+o,b=50;m=50;let k=0,_=!0;p.forEach((function(t){const e={number:k,descr:t,section:k,width:150,padding:20,maxHeight:y},n=B.getVirtualNodeHeight(h,e,a);i.Rm.debug("sectionHeight before draw",n),y=Math.max(y,n+20)}));let w=0,v=0;i.Rm.debug("tasks.length",d.length);for(const[s,S]of d.entries()){const t={number:s,descr:S,section:S.section,width:150,padding:20,maxHeight:g},e=B.getVirtualNodeHeight(h,t,a);i.Rm.debug("taskHeight before draw",e),g=Math.max(g,e+20),w=Math.max(w,S.events.length);let n=0;for(const i of S.events){const t={descr:i,section:S.section,number:S.section,width:150,padding:20,maxHeight:50};n+=B.getVirtualNodeHeight(h,t,a)}v=Math.max(v,n)}i.Rm.debug("maxSectionHeight before draw",y),i.Rm.debug("maxTaskHeight before draw",g),p&&p.length>0?p.forEach((t=>{const e=d.filter((e=>e.section===t)),n={number:k,descr:t,section:k,width:200*Math.max(e.length,1)-50,padding:20,maxHeight:y};i.Rm.debug("sectionNode",n);const s=h.append("g"),r=B.drawNode(s,n,k,a);i.Rm.debug("sectionNode output",r),s.attr("transform",`translate(${x}, 50)`),b+=y+50,e.length>0&&V(h,e,k,x,b,g,a,w,v,y,!1),x+=200*Math.max(e.length,1),b=50,k++})):(_=!1,V(h,d,k,x,b,g,a,w,v,y,!0));const K=h.node().getBBox();i.Rm.debug("bounds",K),u&&h.append("text").text(u).attr("x",K.width/2-o).attr("font-size","4ex").attr("font-weight","bold").attr("y",20),f=_?y+g+150:g+100;h.append("g").attr("class","lineWrapper").append("line").attr("x1",o).attr("y1",f).attr("x2",K.width+3*o).attr("y2",f).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)"),(0,i.ot)(void 0,h,a.timeline?.padding??50,a.timeline?.useMaxWidth??!1)}),"draw"),V=(0,i.K2)((function(t,e,n,s,r,a,o,c,l,h,d){for(const u of e){const e={descr:u.task,section:n,number:n,width:150,padding:20,maxHeight:a};i.Rm.debug("taskNode",e);const c=t.append("g").attr("class","taskWrapper"),p=B.drawNode(c,e,n,o).height;if(i.Rm.debug("taskHeight after draw",p),c.attr("transform",`translate(${s}, ${r})`),a=Math.max(a,p),u.events){const e=t.append("g").attr("class","lineWrapper");let i=a;r+=100,i+=G(t,u.events,n,s,r,o),r-=100,e.append("line").attr("x1",s+95).attr("y1",r+a).attr("x2",s+95).attr("y2",r+a+(d?a:h)+l+120).attr("stroke-width",2).attr("stroke","black").attr("marker-end","url(#arrowhead)").attr("stroke-dasharray","5,5")}s+=200,d&&!o.timeline?.disableMulticolor&&n++}r-=10}),"drawTasks"),G=(0,i.K2)((function(t,e,n,s,r,a){let o=0;const c=r;r+=100;for(const l of e){const e={descr:l,section:n,number:n,width:150,padding:20,maxHeight:50};i.Rm.debug("eventNode",e);const c=t.append("g").attr("class","eventWrapper"),h=B.drawNode(c,e,n,a).height;o+=h,c.attr("transform",`translate(${s}, ${r})`),r=r+10+h}return r=c,o}),"drawEvents"),U={setConf:(0,i.K2)((()=>{}),"setConf"),draw:F},q=(0,i.K2)((t=>{let e="";for(let n=0;n<t.THEME_COLOR_LIMIT;n++)t["lineColor"+n]=t["lineColor"+n]||t["cScaleInv"+n],(0,r.A)(t["lineColor"+n])?t["lineColor"+n]=(0,a.A)(t["lineColor"+n],20):t["lineColor"+n]=(0,o.A)(t["lineColor"+n],20);for(let n=0;n<t.THEME_COLOR_LIMIT;n++){const i=""+(17-3*n);e+=`\n .section-${n-1} rect, .section-${n-1} path, .section-${n-1} circle, .section-${n-1} path {\n fill: ${t["cScale"+n]};\n }\n .section-${n-1} text {\n fill: ${t["cScaleLabel"+n]};\n }\n .node-icon-${n-1} {\n font-size: 40px;\n color: ${t["cScaleLabel"+n]};\n }\n .section-edge-${n-1}{\n stroke: ${t["cScale"+n]};\n }\n .edge-depth-${n-1}{\n stroke-width: ${i};\n }\n .section-${n-1} line {\n stroke: ${t["cScaleInv"+n]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${t["cScaleLabel"+n]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `}return e}),"genSections"),J={db:h,renderer:U,parser:l,styles:(0,i.K2)((t=>`\n .edge {\n stroke-width: 3;\n }\n ${q(t)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${t.git0};\n }\n .section-root text {\n fill: ${t.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/75100f0d.9f8f9b89.js b/pr-preview/pr-976/assets/js/75100f0d.9f8f9b89.js new file mode 100644 index 0000000000..cfda6552ce --- /dev/null +++ b/pr-preview/pr-976/assets/js/75100f0d.9f8f9b89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7882],{67766:(e,t,r)=>{r.d(t,{A:()=>b});var n=r(96540),c=r(34164),s=r(85246),o=r(57880),i=r(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function h(){const e=d();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const c=r.select(t),s=r.pluralForms.indexOf(c);return n[Math.min(s,n.length-1)]}(r,t,e)}}var m=r(77056),p=r(32032),f=r(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=r(74848);function j(e){let{href:t,children:r}=e;return(0,g.jsx)(o.A,{href:t,className:(0,c.A)("card padding--lg",x.cardContainer),children:r})}function v(e){let{href:t,icon:r,title:n,description:s}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,c.A)("text--truncate",x.cardTitle),title:n,children:[r," ",n]}),s&&(0,g.jsx)("p",{className:(0,c.A)("text--truncate",x.cardDescription),title:s,children:s})]})}function w(e){let{item:t}=e;const r=(0,s.Nr)(t),n=function(){const{selectMessage:e}=h();return t=>e(t,(0,p.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return r?(0,g.jsx)(v,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??n(t.items.length)}):null}function A(e){let{item:t}=e;const r=(0,m.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,s.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:r,title:t.label,description:t.description??n?.description})}function y(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(A,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const r=(0,s.$S)();return(0,g.jsx)(b,{items:r.items,className:t})}function b(e){const{items:t,className:r}=e;if(!t)return(0,g.jsx)(N,{...e});const n=(0,s.d1)(t);return(0,g.jsx)("section",{className:(0,c.A)("row",r),children:n.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(y,{item:e})},t)))})}},82094:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"architecture/index","title":"Architecture","description":"","source":"@site/versioned_docs/version-0.6/architecture/index.md","sourceDirName":"architecture","slug":"/architecture/","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/architecture/index.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.6/components/service-mesh"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/attestation"}}');var c=r(74848),s=r(28453),o=r(67766);const i={},a="Architecture",l={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"architecture",children:"Architecture"})}),"\n","\n",(0,c.jsx)(o.A,{})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const c={},s=n.createContext(c);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/75d659e1.2d71da15.js b/pr-preview/pr-976/assets/js/75d659e1.2d71da15.js new file mode 100644 index 0000000000..3562b6c879 --- /dev/null +++ b/pr-preview/pr-976/assets/js/75d659e1.2d71da15.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8597],{5004:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-0.6/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/0.6/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/deployment.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto"},"next":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.6/components/"}}');var s=t(74848),i=t(28453);const o={},a="Workload deployment",c={},l=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"RuntimeClass and Initializer",id:"runtimeclass-and-initializer",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:r}=n;return t||p("TabItem",!0),r||p("Tabs",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,s.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,s.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,s.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,s.jsxs)(n.p,{children:["Contrast depends on a ",(0,s.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:["custom Kubernetes ",(0,s.jsx)(n.code,{children:"RuntimeClass"})," (",(0,s.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,s.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,s.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime.yml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,s.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml\n"})}),"\n",(0,s.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,s.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,s.jsx)(n.h3,{id:"runtimeclass-and-initializer",children:"RuntimeClass and Initializer"}),"\n",(0,s.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,s.jsxs)(r,{groupId:"yaml-source",children:[(0,s.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,s.jsx)(t,{value:"helm",label:"helm",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,s.jsx)(t,{value:"copy",label:"copy",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,s.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,s.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,s.jsx)(n.code,{children:"runtimeClassName"})," when generating policies.\nIn addition, add the Contrast Initializer as ",(0,s.jsx)(n.code,{children:"initContainers"})," to these workloads and configure the\nworkload to use the certificates written to a ",(0,s.jsx)(n.code,{children:"volumeMount"})," named ",(0,s.jsx)(n.code,{children:"tls-certs"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n initContainers:\n - name: initializer\n image: "ghcr.io/edgelesssys/contrast/initializer:latest"\n env:\n - name: COORDINATOR_HOST\n value: coordinator\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n volumes:\n - name: tls-certs\n emptyDir: {}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,s.jsxs)(n.p,{children:["The initializer populates the shared volume with X.509 certificates for your workload.\nThese certificates are used by the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,s.jsxs)(r,{groupId:"tls",children:[(0,s.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,s.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,s.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The app has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,s.jsx)(n.li,{children:"The app has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,s.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,s.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,s.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,s.jsx)(n.p,{children:"Add the following sidecar definition to your workload:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n initContainers:\n - name: tls-sidecar\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:latest"\n restartPolicy: Always\n env:\n - name: EDG_INGRESS_PROXY_CONFIG\n value: "main#8001#false##metrics#8080#true"\n - name: EDG_EGRESS_PROXY_CONFIG\n value: "backend#127.0.0.2:4001#backend.default:4001"\n volumeMounts:\n - name: tls-certs\n mountPath: /tls-config\n'})}),(0,s.jsxs)(n.p,{children:["The only change required to the app itself is to let it connect to ",(0,s.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,s.jsxs)(t,{value:"go",label:"Go integration",children:[(0,s.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,s.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,s.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,s.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,s.jsxs)(r,{groupId:"golang-tls-setup",children:[(0,s.jsx)(t,{value:"client",label:"Client",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,s.jsx)(t,{value:"server",label:"Server",children:(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,s.jsxs)(n.p,{children:["Run the ",(0,s.jsx)(n.code,{children:"generate"})," command to generate the execution policies and add them as annotations to your\ndeployment files. A ",(0,s.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"contrast generate resources/\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/known-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,s.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,s.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,s.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,s.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,s.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,s.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,s.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,s.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,s.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,s.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,s.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,s.jsx)(n.p,{children:"After this step, the Coordinator will start issuing TLS certs to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,s.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,s.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,s.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh\nroot certificate and the history of manifests into the ",(0,s.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies referenced\nin the manifest are also written to the directory."]}),"\n",(0,s.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,s.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,s.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,s.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,s.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,s.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}function p(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var r=t(96540);const s={},i=r.createContext(s);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7680d80e.2894bfc5.js b/pr-preview/pr-976/assets/js/7680d80e.2894bfc5.js new file mode 100644 index 0000000000..e40fa7bf3c --- /dev/null +++ b/pr-preview/pr-976/assets/js/7680d80e.2894bfc5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9025],{88205:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-0.7/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/0.7/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/examples/emojivoto.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.7/examples/"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.7/deployment"}}');var i=n(74848),s=n(28453);const a={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Downloading the deployment",id:"downloading-the-deployment",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(45741).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"downloading-the-deployment",children:"Downloading the deployment"}),"\n",(0,i.jsx)(t.p,{children:"The emojivoto deployment files are part of a zip file in the Contrast release. You can download the\nlatest deployment by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.7.3/emojivoto-demo.zip\n"})}),"\n",(0,i.jsxs)(t.p,{children:["After that, unzip the ",(0,i.jsx)(t.code,{children:"emojivoto-demo.zip"})," file to extract the ",(0,i.jsx)(t.code,{children:"deployment/"})," directory."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"unzip emojivoto-demo.zip\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,i.jsxs)(t.p,{children:["Contrast depends on a ",(0,i.jsxs)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:["custom Kubernetes ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," (",(0,i.jsx)(t.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,i.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/runtime.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate deployment/\n"})}),"\n",(0,i.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,i.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,i.jsx)(t.code,{children:"contrast-cc-<VERSIONHASH>"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,i.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the embedded reference values to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using embedded reference values. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},45741:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7723.83dacf97.js b/pr-preview/pr-976/assets/js/7723.83dacf97.js new file mode 100644 index 0000000000..62aace32ae --- /dev/null +++ b/pr-preview/pr-976/assets/js/7723.83dacf97.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7723],{57723:(e,s,c)=>{c.d(s,{createPieServices:()=>t.f});var t=c(88685);c(19369)}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/790f17e8.a5baddba.js b/pr-preview/pr-976/assets/js/790f17e8.a5baddba.js new file mode 100644 index 0000000000..824f7412da --- /dev/null +++ b/pr-preview/pr-976/assets/js/790f17e8.a5baddba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5242],{27808:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-0.8/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/0.8/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/components/service-mesh.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.8/components/policies"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/attestation"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"CONTRAST_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"CONTRAST_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"<name>#<port>#false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:"<name>"})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"<name>#<port>#true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: CONTRAST_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.8.1@sha256:de65f2921d617fd2cee3734c4d325b9464e655d3c29e95844163a0738937748a"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-tls-certs\n mountPath: /tls-config\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"<name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port>"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:"<name>"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7bd8db71.3f1b000d.js b/pr-preview/pr-976/assets/js/7bd8db71.3f1b000d.js new file mode 100644 index 0000000000..c6a5b2e7ae --- /dev/null +++ b/pr-preview/pr-976/assets/js/7bd8db71.3f1b000d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1606],{57378:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-1.0/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/1.0/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/intro.md","tags":[],"version":"1.0","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/getting-started/install",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7d1602ac.42782481.js b/pr-preview/pr-976/assets/js/7d1602ac.42782481.js new file mode 100644 index 0000000000..369ef2ef83 --- /dev/null +++ b/pr-preview/pr-976/assets/js/7d1602ac.42782481.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6069],{55238:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-0.8/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/0.8/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/basics/features.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.8/basics/security-benefits"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/install"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7edb0f0d.85693ccb.js b/pr-preview/pr-976/assets/js/7edb0f0d.85693ccb.js new file mode 100644 index 0000000000..f3a4ca67bc --- /dev/null +++ b/pr-preview/pr-976/assets/js/7edb0f0d.85693ccb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5231],{32716:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>h});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/versioned_docs/version-0.7/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/architecture/observability.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/certificates"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.7/features-limitations"}}');var s=r(74848),i=r(28453);const o={},a="Observability",c={},h=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator starts two gRPC servers, one for the user API on port ",(0,s.jsx)(t.code,{children:"1313"})," and\none for the mesh API on port ",(0,s.jsx)(t.code,{children:"7777"}),". Metrics for both servers can be accessed\nusing different prefixes."]}),"\n",(0,s.jsxs)(t.p,{children:["All metric names for the user API are prefixed with ",(0,s.jsx)(t.code,{children:"contrast_userapi_grpc_server_"}),".\nExposed metrics include the number of handled requests of the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively. For each method\nyou can see the gRPC status code indicating whether the request succeeded or\nnot and the request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["For the mesh API, the metric names are prefixed with ",(0,s.jsx)(t.code,{children:"contrast_meshapi_grpc_server_"}),". The\nmetrics include similar data to the user API for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"})," which\ngets called by the ",(0,s.jsx)(t.a,{href:"../components#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/7f3f1ff7.009aeec6.js b/pr-preview/pr-976/assets/js/7f3f1ff7.009aeec6.js new file mode 100644 index 0000000000..9d1b28dbbf --- /dev/null +++ b/pr-preview/pr-976/assets/js/7f3f1ff7.009aeec6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6623],{86696:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-0.9/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/0.9/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/about/telemetry.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.9/features-limitations"}}');var r=n(74848),o=n(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8132774f.2680af68.js b/pr-preview/pr-976/assets/js/8132774f.2680af68.js new file mode 100644 index 0000000000..b47a03df11 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8132774f.2680af68.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1841],{58879:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-0.7/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/getting-started/cluster-setup.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/install"},"next":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.7/examples/"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which needs\nto have the permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a\nnon-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool."}),"\n",(0,t.jsx)(n.p,{children:"We'll first start by creating the non-CoCo cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "${azResourceGroup:?}" \\\n --name nodepool2 \\\n --cluster-name "${azClusterName:?}" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Optionally, we can now remove the non-CoCo node pool:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool delete \\\n --resource-group "${azResourceGroup:?}" \\\n --cluster-name "${azClusterName:?}" \\\n --name nodepool1\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8159.4e759f62.js b/pr-preview/pr-976/assets/js/8159.4e759f62.js new file mode 100644 index 0000000000..83fee0ce43 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8159.4e759f62.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8159],{79825:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var o=n(34164),s=n(32032),i=n(98445),r=n(74848);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,o.A)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,r.jsx)(s.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(s.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(s.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},18159:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});n(96540);var o=n(32032),s=n(63523),i=n(83502),r=n(79825),a=n(74848);function c(){const e=(0,o.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.be,{title:e}),(0,a.jsx)(i.A,{children:(0,a.jsx)(r.A,{})})]})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8174.61ff22d1.js b/pr-preview/pr-976/assets/js/8174.61ff22d1.js new file mode 100644 index 0000000000..62225c4127 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8174.61ff22d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8174],{86022:(t,r,e)=>{function n(t,r){t.accDescr&&r.setAccDescription?.(t.accDescr),t.accTitle&&r.setAccTitle?.(t.accTitle),t.title&&r.setDiagramTitle?.(t.title)}e.d(r,{S:()=>n}),(0,e(45567).K2)(n,"populateCommonDb")},39676:(t,r,e)=>{e.d(r,{m:()=>o});var n=e(45567),o=class{constructor(t){this.init=t,this.records=this.init()}static{(0,n.K2)(this,"ImperativeState")}reset(){this.records=this.init()}}},78174:(t,r,e)=>{e.d(r,{diagram:()=>ft});var n=e(86022),o=e(39676),a=e(85039),c=e(45567),s=e(78731),i=e(20007),h={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},d=c.UI.gitGraph,m=(0,c.K2)((()=>(0,a.$t)({...d,...(0,c.zj)().gitGraph})),"getConfig"),$=new o.m((()=>{const t=m(),r=t.mainBranchName,e=t.mainBranchOrder;return{mainBranchName:r,commits:new Map,head:null,branchConfig:new Map([[r,{name:r,order:e}]]),branches:new Map([[r,null]]),currBranch:r,direction:"LR",seq:0,options:{}}}));function l(){return(0,a.yT)({length:7})}function y(t,r){const e=Object.create(null);return t.reduce(((t,n)=>{const o=r(n);return e[o]||(e[o]=!0,t.push(n)),t}),[])}(0,c.K2)(l,"getID"),(0,c.K2)(y,"uniqBy");var g=(0,c.K2)((function(t){$.records.direction=t}),"setDirection"),p=(0,c.K2)((function(t){c.Rm.debug("options str",t),t=t?.trim(),t=t||"{}";try{$.records.options=JSON.parse(t)}catch(r){c.Rm.error("error while parsing gitGraph options",r.message)}}),"setOptions"),x=(0,c.K2)((function(){return $.records.options}),"getOptions"),f=(0,c.K2)((function(t){let r=t.msg,e=t.id;const n=t.type;let o=t.tags;c.Rm.info("commit",r,e,n,o),c.Rm.debug("Entering commit:",r,e,n,o);const a=m();e=c.Y2.sanitizeText(e,a),r=c.Y2.sanitizeText(r,a),o=o?.map((t=>c.Y2.sanitizeText(t,a)));const s={id:e||$.records.seq+"-"+l(),message:r,seq:$.records.seq++,type:n??h.NORMAL,tags:o??[],parents:null==$.records.head?[]:[$.records.head.id],branch:$.records.currBranch};$.records.head=s,c.Rm.info("main branch",a.mainBranchName),$.records.commits.set(s.id,s),$.records.branches.set($.records.currBranch,s.id),c.Rm.debug("in pushCommit "+s.id)}),"commit"),u=(0,c.K2)((function(t){let r=t.name;const e=t.order;if(r=c.Y2.sanitizeText(r,m()),$.records.branches.has(r))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${r}")`);$.records.branches.set(r,null!=$.records.head?$.records.head.id:null),$.records.branchConfig.set(r,{name:r,order:e}),B(r),c.Rm.debug("in createBranch")}),"branch"),b=(0,c.K2)((t=>{let r=t.branch,e=t.id;const n=t.type,o=t.tags,a=m();r=c.Y2.sanitizeText(r,a),e&&(e=c.Y2.sanitizeText(e,a));const s=$.records.branches.get($.records.currBranch),i=$.records.branches.get(r),d=s?$.records.commits.get(s):void 0,y=i?$.records.commits.get(i):void 0;if(d&&y&&d.branch===r)throw new Error(`Cannot merge branch '${r}' into itself.`);if($.records.currBranch===r){const t=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},t}if(void 0===d||!d){const t=new Error(`Incorrect usage of "merge". Current branch (${$.records.currBranch})has no commits`);throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["commit"]},t}if(!$.records.branches.has(r)){const t=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") does not exist");throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:[`branch ${r}`]},t}if(void 0===y||!y){const t=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") has no commits");throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:['"commit"']},t}if(d===y){const t=new Error('Incorrect usage of "merge". Both branches have same head');throw t.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},t}if(e&&$.records.commits.has(e)){const t=new Error('Incorrect usage of "merge". Commit with id:'+e+" already exists, use different custom Id");throw t.hash={text:`merge ${r} ${e} ${n} ${o?.join(" ")}`,token:`merge ${r} ${e} ${n} ${o?.join(" ")}`,expected:[`merge ${r} ${e}_UNIQUE ${n} ${o?.join(" ")}`]},t}const g=i||"",p={id:e||`${$.records.seq}-${l()}`,message:`merged branch ${r} into ${$.records.currBranch}`,seq:$.records.seq++,parents:null==$.records.head?[]:[$.records.head.id,g],branch:$.records.currBranch,type:h.MERGE,customType:n,customId:!!e,tags:o??[]};$.records.head=p,$.records.commits.set(p.id,p),$.records.branches.set($.records.currBranch,p.id),c.Rm.debug($.records.branches),c.Rm.debug("in mergeBranch")}),"merge"),w=(0,c.K2)((function(t){let r=t.id,e=t.targetId,n=t.tags,o=t.parent;c.Rm.debug("Entering cherryPick:",r,e,n);const a=m();if(r=c.Y2.sanitizeText(r,a),e=c.Y2.sanitizeText(e,a),n=n?.map((t=>c.Y2.sanitizeText(t,a))),o=c.Y2.sanitizeText(o,a),!r||!$.records.commits.has(r)){const t=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const s=$.records.commits.get(r);if(void 0===s||!s)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(o&&(!Array.isArray(s.parents)||!s.parents.includes(o))){throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.")}const i=s.branch;if(s.type===h.MERGE&&!o){throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.")}if(!e||!$.records.commits.has(e)){if(i===$.records.currBranch){const t=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const t=$.records.branches.get($.records.currBranch);if(void 0===t||!t){const t=new Error(`Incorrect usage of "cherry-pick". Current branch (${$.records.currBranch})has no commits`);throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const a=$.records.commits.get(t);if(void 0===a||!a){const t=new Error(`Incorrect usage of "cherry-pick". Current branch (${$.records.currBranch})has no commits`);throw t.hash={text:`cherryPick ${r} ${e}`,token:`cherryPick ${r} ${e}`,expected:["cherry-pick abc"]},t}const d={id:$.records.seq+"-"+l(),message:`cherry-picked ${s?.message} into ${$.records.currBranch}`,seq:$.records.seq++,parents:null==$.records.head?[]:[$.records.head.id,s.id],branch:$.records.currBranch,type:h.CHERRY_PICK,tags:n?n.filter(Boolean):[`cherry-pick:${s.id}${s.type===h.MERGE?`|parent:${o}`:""}`]};$.records.head=d,$.records.commits.set(d.id,d),$.records.branches.set($.records.currBranch,d.id),c.Rm.debug($.records.branches),c.Rm.debug("in cherryPick")}}),"cherryPick"),B=(0,c.K2)((function(t){if(t=c.Y2.sanitizeText(t,m()),!$.records.branches.has(t)){const r=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${t}")`);throw r.hash={text:`checkout ${t}`,token:`checkout ${t}`,expected:[`branch ${t}`]},r}{$.records.currBranch=t;const r=$.records.branches.get($.records.currBranch);$.records.head=void 0!==r&&r?$.records.commits.get(r)??null:null}}),"checkout");function E(t,r,e){const n=t.indexOf(r);-1===n?t.push(e):t.splice(n,1,e)}function k(t){const r=t.reduce(((t,r)=>t.seq>r.seq?t:r),t[0]);let e="";t.forEach((function(t){e+=t===r?"\t*":"\t|"}));const n=[e,r.id,r.seq];for(const o in $.records.branches)$.records.branches.get(o)===r.id&&n.push(o);if(c.Rm.debug(n.join(" ")),r.parents&&2==r.parents.length&&r.parents[0]&&r.parents[1]){const e=$.records.commits.get(r.parents[0]);E(t,r,e),r.parents[1]&&t.push($.records.commits.get(r.parents[1]))}else{if(0==r.parents.length)return;if(r.parents[0]){const e=$.records.commits.get(r.parents[0]);E(t,r,e)}}k(t=y(t,(t=>t.id)))}(0,c.K2)(E,"upsert"),(0,c.K2)(k,"prettyPrintCommitHistory");var C=(0,c.K2)((function(){c.Rm.debug($.records.commits);k([R()[0]])}),"prettyPrint"),T=(0,c.K2)((function(){$.reset(),(0,c.IU)()}),"clear"),L=(0,c.K2)((function(){return[...$.records.branchConfig.values()].map(((t,r)=>null!==t.order&&void 0!==t.order?t:{...t,order:parseFloat(`0.${r}`)})).sort(((t,r)=>(t.order??0)-(r.order??0))).map((({name:t})=>({name:t})))}),"getBranchesAsObjArray"),K=(0,c.K2)((function(){return $.records.branches}),"getBranches"),M=(0,c.K2)((function(){return $.records.commits}),"getCommits"),R=(0,c.K2)((function(){const t=[...$.records.commits.values()];return t.forEach((function(t){c.Rm.debug(t.id)})),t.sort(((t,r)=>t.seq-r.seq)),t}),"getCommitsArray"),v={commitType:h,getConfig:m,setDirection:g,setOptions:p,getOptions:x,commit:f,branch:u,merge:b,cherryPick:w,checkout:B,prettyPrint:C,clear:T,getBranchesAsObjArray:L,getBranches:K,getCommits:M,getCommitsArray:R,getCurrentBranch:(0,c.K2)((function(){return $.records.currBranch}),"getCurrentBranch"),getDirection:(0,c.K2)((function(){return $.records.direction}),"getDirection"),getHead:(0,c.K2)((function(){return $.records.head}),"getHead"),setAccTitle:c.SV,getAccTitle:c.iN,getAccDescription:c.m7,setAccDescription:c.EI,setDiagramTitle:c.ke,getDiagramTitle:c.ab},P=(0,c.K2)(((t,r)=>{(0,n.S)(t,r),t.dir&&r.setDirection(t.dir);for(const e of t.statements)I(e,r)}),"populate"),I=(0,c.K2)(((t,r)=>{const e={Commit:(0,c.K2)((t=>r.commit(A(t))),"Commit"),Branch:(0,c.K2)((t=>r.branch(G(t))),"Branch"),Merge:(0,c.K2)((t=>r.merge(O(t))),"Merge"),Checkout:(0,c.K2)((t=>r.checkout(q(t))),"Checkout"),CherryPicking:(0,c.K2)((t=>r.cherryPick(z(t))),"CherryPicking")}[t.$type];e?e(t):c.Rm.error(`Unknown statement type: ${t.$type}`)}),"parseStatement"),A=(0,c.K2)((t=>({id:t.id,msg:t.message??"",type:void 0!==t.type?h[t.type]:h.NORMAL,tags:t.tags??void 0})),"parseCommit"),G=(0,c.K2)((t=>({name:t.name,order:t.order??0})),"parseBranch"),O=(0,c.K2)((t=>({branch:t.branch,id:t.id??"",type:void 0!==t.type?h[t.type]:void 0,tags:t.tags??void 0})),"parseMerge"),q=(0,c.K2)((t=>t.branch),"parseCheckout"),z=(0,c.K2)((t=>({id:t.id,targetId:"",tags:0===t.tags?.length?void 0:t.tags,parent:t.parent})),"parseCherryPicking"),H={parse:(0,c.K2)((async t=>{const r=await(0,s.qg)("gitGraph",t);c.Rm.debug(r),P(r,v)}),"parse")};var S=(0,c.D7)(),D=S?.gitGraph,Y=10,N=40,j=new Map,W=new Map,_=new Map,F=[],U=0,V="LR",J=(0,c.K2)((()=>{j.clear(),W.clear(),_.clear(),U=0,F=[],V="LR"}),"clear"),Q=(0,c.K2)((t=>{const r=document.createElementNS("http://www.w3.org/2000/svg","text");return("string"==typeof t?t.split(/\\n|\n|<br\s*\/?>/gi):t).forEach((t=>{const e=document.createElementNS("http://www.w3.org/2000/svg","tspan");e.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),e.setAttribute("dy","1em"),e.setAttribute("x","0"),e.setAttribute("class","row"),e.textContent=t.trim(),r.appendChild(e)})),r}),"drawText"),X=(0,c.K2)((t=>{let r,e,n;return"BT"===V?(e=(0,c.K2)(((t,r)=>t<=r),"comparisonFunc"),n=1/0):(e=(0,c.K2)(((t,r)=>t>=r),"comparisonFunc"),n=0),t.forEach((t=>{const o="TB"===V||"BT"==V?W.get(t)?.y:W.get(t)?.x;void 0!==o&&e(o,n)&&(r=t,n=o)})),r}),"findClosestParent"),Z=(0,c.K2)((t=>{let r="",e=1/0;return t.forEach((t=>{const n=W.get(t).y;n<=e&&(r=t,e=n)})),r||void 0}),"findClosestParentBT"),tt=(0,c.K2)(((t,r,e)=>{let n=e,o=e;const a=[];t.forEach((t=>{const e=r.get(t);if(!e)throw new Error(`Commit not found for key ${t}`);e.parents.length?(n=et(e),o=Math.max(n,o)):a.push(e),nt(e,n)})),n=o,a.forEach((t=>{ot(t,n,e)})),t.forEach((t=>{const e=r.get(t);if(e?.parents.length){const t=Z(e.parents);n=W.get(t).y-N,n<=o&&(o=n);const r=j.get(e.branch).pos,a=n-Y;W.set(e.id,{x:r,y:a})}}))}),"setParallelBTPos"),rt=(0,c.K2)((t=>{const r=X(t.parents.filter((t=>null!==t)));if(!r)throw new Error(`Closest parent not found for commit ${t.id}`);const e=W.get(r)?.y;if(void 0===e)throw new Error(`Closest parent position not found for commit ${t.id}`);return e}),"findClosestParentPos"),et=(0,c.K2)((t=>rt(t)+N),"calculateCommitPosition"),nt=(0,c.K2)(((t,r)=>{const e=j.get(t.branch);if(!e)throw new Error(`Branch not found for commit ${t.id}`);const n=e.pos,o=r+Y;return W.set(t.id,{x:n,y:o}),{x:n,y:o}}),"setCommitPosition"),ot=(0,c.K2)(((t,r,e)=>{const n=j.get(t.branch);if(!n)throw new Error(`Branch not found for commit ${t.id}`);const o=r+e,a=n.pos;W.set(t.id,{x:a,y:o})}),"setRootPosition"),at=(0,c.K2)(((t,r,e,n,o,a)=>{if(a===h.HIGHLIGHT)t.append("rect").attr("x",e.x-10).attr("y",e.y-10).attr("width",20).attr("height",20).attr("class",`commit ${r.id} commit-highlight${o%8} ${n}-outer`),t.append("rect").attr("x",e.x-6).attr("y",e.y-6).attr("width",12).attr("height",12).attr("class",`commit ${r.id} commit${o%8} ${n}-inner`);else if(a===h.CHERRY_PICK)t.append("circle").attr("cx",e.x).attr("cy",e.y).attr("r",10).attr("class",`commit ${r.id} ${n}`),t.append("circle").attr("cx",e.x-3).attr("cy",e.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${r.id} ${n}`),t.append("circle").attr("cx",e.x+3).attr("cy",e.y+2).attr("r",2.75).attr("fill","#fff").attr("class",`commit ${r.id} ${n}`),t.append("line").attr("x1",e.x+3).attr("y1",e.y+1).attr("x2",e.x).attr("y2",e.y-5).attr("stroke","#fff").attr("class",`commit ${r.id} ${n}`),t.append("line").attr("x1",e.x-3).attr("y1",e.y+1).attr("x2",e.x).attr("y2",e.y-5).attr("stroke","#fff").attr("class",`commit ${r.id} ${n}`);else{const c=t.append("circle");if(c.attr("cx",e.x),c.attr("cy",e.y),c.attr("r",r.type===h.MERGE?9:10),c.attr("class",`commit ${r.id} commit${o%8}`),a===h.MERGE){const a=t.append("circle");a.attr("cx",e.x),a.attr("cy",e.y),a.attr("r",6),a.attr("class",`commit ${n} ${r.id} commit${o%8}`)}if(a===h.REVERSE){t.append("path").attr("d",`M ${e.x-5},${e.y-5}L${e.x+5},${e.y+5}M${e.x-5},${e.y+5}L${e.x+5},${e.y-5}`).attr("class",`commit ${n} ${r.id} commit${o%8}`)}}}),"drawCommitBullet"),ct=(0,c.K2)(((t,r,e,n)=>{if(r.type!==h.CHERRY_PICK&&(r.customId&&r.type===h.MERGE||r.type!==h.MERGE)&&D?.showCommitLabel){const o=t.append("g"),a=o.insert("rect").attr("class","commit-label-bkg"),c=o.append("text").attr("x",n).attr("y",e.y+25).attr("class","commit-label").text(r.id),s=c.node()?.getBBox();if(s&&(a.attr("x",e.posWithOffset-s.width/2-2).attr("y",e.y+13.5).attr("width",s.width+4).attr("height",s.height+4),"TB"===V||"BT"===V?(a.attr("x",e.x-(s.width+16+5)).attr("y",e.y-12),c.attr("x",e.x-(s.width+16)).attr("y",e.y+s.height-12)):c.attr("x",e.posWithOffset-s.width/2),D.rotateCommitLabel))if("TB"===V||"BT"===V)c.attr("transform","rotate(-45, "+e.x+", "+e.y+")"),a.attr("transform","rotate(-45, "+e.x+", "+e.y+")");else{const t=-7.5-(s.width+10)/25*9.5,r=10+s.width/25*8.5;o.attr("transform","translate("+t+", "+r+") rotate(-45, "+n+", "+e.y+")")}}}),"drawCommitLabel"),st=(0,c.K2)(((t,r,e,n)=>{if(r.tags.length>0){let o=0,a=0,c=0;const s=[];for(const n of r.tags.reverse()){const r=t.insert("polygon"),i=t.append("circle"),h=t.append("text").attr("y",e.y-16-o).attr("class","tag-label").text(n),d=h.node()?.getBBox();if(!d)throw new Error("Tag bbox not found");a=Math.max(a,d.width),c=Math.max(c,d.height),h.attr("x",e.posWithOffset-d.width/2),s.push({tag:h,hole:i,rect:r,yOffset:o}),o+=20}for(const{tag:t,hole:r,rect:i,yOffset:h}of s){const o=c/2,s=e.y-19.2-h;if(i.attr("class","tag-label-bkg").attr("points",`\n ${n-a/2-2},${s+2} \n ${n-a/2-2},${s-2}\n ${e.posWithOffset-a/2-4},${s-o-2}\n ${e.posWithOffset+a/2+4},${s-o-2}\n ${e.posWithOffset+a/2+4},${s+o+2}\n ${e.posWithOffset-a/2-4},${s+o+2}`),r.attr("cy",s).attr("cx",n-a/2+2).attr("r",1.5).attr("class","tag-hole"),"TB"===V||"BT"===V){const c=n+h;i.attr("class","tag-label-bkg").attr("points",`\n ${e.x},${c+2}\n ${e.x},${c-2}\n ${e.x+Y},${c-o-2}\n ${e.x+Y+a+4},${c-o-2}\n ${e.x+Y+a+4},${c+o+2}\n ${e.x+Y},${c+o+2}`).attr("transform","translate(12,12) rotate(45, "+e.x+","+n+")"),r.attr("cx",e.x+2).attr("cy",c).attr("transform","translate(12,12) rotate(45, "+e.x+","+n+")"),t.attr("x",e.x+5).attr("y",c+3).attr("transform","translate(14,14) rotate(45, "+e.x+","+n+")")}}}}),"drawCommitTags"),it=(0,c.K2)((t=>{switch(t.customType??t.type){case h.NORMAL:return"commit-normal";case h.REVERSE:return"commit-reverse";case h.HIGHLIGHT:return"commit-highlight";case h.MERGE:return"commit-merge";case h.CHERRY_PICK:return"commit-cherry-pick";default:return"commit-normal"}}),"getCommitClassType"),ht=(0,c.K2)(((t,r,e,n)=>{const o={x:0,y:0};if(!(t.parents.length>0)){if("TB"===r)return 30;if("BT"===r){return(n.get(t.id)??o).y-N}return 0}{const e=X(t.parents);if(e){const a=n.get(e)??o;if("TB"===r)return a.y+N;if("BT"===r){return(n.get(t.id)??o).y-N}return a.x+N}}return 0}),"calculatePosition"),dt=(0,c.K2)(((t,r,e)=>{const n="BT"===V&&e?r:r+Y,o="TB"===V||"BT"===V?n:j.get(t.branch)?.pos,a="TB"===V||"BT"===V?j.get(t.branch)?.pos:n;if(void 0===a||void 0===o)throw new Error(`Position were undefined for commit ${t.id}`);return{x:a,y:o,posWithOffset:n}}),"getCommitPosition"),mt=(0,c.K2)(((t,r,e)=>{if(!D)throw new Error("GitGraph config not found");const n=t.append("g").attr("class","commit-bullets"),o=t.append("g").attr("class","commit-labels");let a="TB"===V||"BT"===V?30:0;const s=[...r.keys()],i=D?.parallelCommits??!1,h=(0,c.K2)(((t,e)=>{const n=r.get(t)?.seq,o=r.get(e)?.seq;return void 0!==n&&void 0!==o?n-o:0}),"sortKeys");let d=s.sort(h);"BT"===V&&(i&&tt(d,r,a),d=d.reverse()),d.forEach((t=>{const c=r.get(t);if(!c)throw new Error(`Commit not found for key ${t}`);i&&(a=ht(c,V,a,W));const s=dt(c,a,i);if(e){const t=it(c),r=c.customType??c.type,e=j.get(c.branch)?.index??0;at(n,c,s,t,e,r),ct(o,c,s,a),st(o,c,s,a)}"TB"===V||"BT"===V?W.set(c.id,{x:s.x,y:s.posWithOffset}):W.set(c.id,{x:s.posWithOffset,y:s.y}),a="BT"===V&&i?a+N:a+N+Y,a>U&&(U=a)}))}),"drawCommits"),$t=(0,c.K2)(((t,r,e,n,o)=>{const a=("TB"===V||"BT"===V?e.x<n.x:e.y<n.y)?r.branch:t.branch,s=(0,c.K2)((t=>t.branch===a),"isOnBranchToGetCurve"),i=(0,c.K2)((e=>e.seq>t.seq&&e.seq<r.seq),"isBetweenCommits");return[...o.values()].some((t=>i(t)&&s(t)))}),"shouldRerouteArrow"),lt=(0,c.K2)(((t,r,e=0)=>{const n=t+Math.abs(t-r)/2;if(e>5)return n;if(F.every((t=>Math.abs(t-n)>=10)))return F.push(n),n;const o=Math.abs(t-r);return lt(t,r-o/5,e+1)}),"findLane"),yt=(0,c.K2)(((t,r,e,n)=>{const o=W.get(r.id),a=W.get(e.id);if(void 0===o||void 0===a)throw new Error(`Commit positions not found for commits ${r.id} and ${e.id}`);const c=$t(r,e,o,a,n);let s,i="",d="",m=0,$=0,l=j.get(e.branch)?.index;if(e.type===h.MERGE&&r.id!==e.parents[0]&&(l=j.get(r.branch)?.index),c){i="A 10 10, 0, 0, 0,",d="A 10 10, 0, 0, 1,",m=10,$=10;const t=o.y<a.y?lt(o.y,a.y):lt(a.y,o.y),e=o.x<a.x?lt(o.x,a.x):lt(a.x,o.x);"TB"===V?o.x<a.x?s=`M ${o.x} ${o.y} L ${e-m} ${o.y} ${d} ${e} ${o.y+$} L ${e} ${a.y-m} ${i} ${e+$} ${a.y} L ${a.x} ${a.y}`:(l=j.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${e+m} ${o.y} ${i} ${e} ${o.y+$} L ${e} ${a.y-m} ${d} ${e-$} ${a.y} L ${a.x} ${a.y}`):"BT"===V?o.x<a.x?s=`M ${o.x} ${o.y} L ${e-m} ${o.y} ${i} ${e} ${o.y-$} L ${e} ${a.y+m} ${d} ${e+$} ${a.y} L ${a.x} ${a.y}`:(l=j.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${e+m} ${o.y} ${d} ${e} ${o.y-$} L ${e} ${a.y+m} ${i} ${e-$} ${a.y} L ${a.x} ${a.y}`):o.y<a.y?s=`M ${o.x} ${o.y} L ${o.x} ${t-m} ${i} ${o.x+$} ${t} L ${a.x-m} ${t} ${d} ${a.x} ${t+$} L ${a.x} ${a.y}`:(l=j.get(r.branch)?.index,s=`M ${o.x} ${o.y} L ${o.x} ${t+m} ${d} ${o.x+$} ${t} L ${a.x-m} ${t} ${i} ${a.x} ${t-$} L ${a.x} ${a.y}`)}else i="A 20 20, 0, 0, 0,",d="A 20 20, 0, 0, 1,",m=20,$=20,"TB"===V?(o.x<a.x&&(s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${i} ${o.x+$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${d} ${a.x} ${o.y+$} L ${a.x} ${a.y}`),o.x>a.x&&(i="A 20 20, 0, 0, 0,",d="A 20 20, 0, 0, 1,",m=20,$=20,s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${d} ${o.x-$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x+m} ${o.y} ${i} ${a.x} ${o.y+$} L ${a.x} ${a.y}`),o.x===a.x&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`)):"BT"===V?(o.x<a.x&&(s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${d} ${o.x+$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`),o.x>a.x&&(i="A 20 20, 0, 0, 0,",d="A 20 20, 0, 0, 1,",m=20,$=20,s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${i} ${o.x-$} ${a.y} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`),o.x===a.x&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`)):(o.y<a.y&&(s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${d} ${a.x} ${o.y+$} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${o.x} ${a.y-m} ${i} ${o.x+$} ${a.y} L ${a.x} ${a.y}`),o.y>a.y&&(s=e.type===h.MERGE&&r.id!==e.parents[0]?`M ${o.x} ${o.y} L ${a.x-m} ${o.y} ${i} ${a.x} ${o.y-$} L ${a.x} ${a.y}`:`M ${o.x} ${o.y} L ${o.x} ${a.y+m} ${d} ${o.x+$} ${a.y} L ${a.x} ${a.y}`),o.y===a.y&&(s=`M ${o.x} ${o.y} L ${a.x} ${a.y}`));if(void 0===s)throw new Error("Line definition not found");t.append("path").attr("d",s).attr("class","arrow arrow"+l%8)}),"drawArrow"),gt=(0,c.K2)(((t,r)=>{const e=t.append("g").attr("class","commit-arrows");[...r.keys()].forEach((t=>{const n=r.get(t);n.parents&&n.parents.length>0&&n.parents.forEach((t=>{yt(e,r.get(t),n,r)}))}))}),"drawArrows"),pt=(0,c.K2)(((t,r)=>{const e=t.append("g");r.forEach(((t,r)=>{const n=r%8,o=j.get(t.name)?.pos;if(void 0===o)throw new Error(`Position not found for branch ${t.name}`);const a=e.append("line");a.attr("x1",0),a.attr("y1",o),a.attr("x2",U),a.attr("y2",o),a.attr("class","branch branch"+n),"TB"===V?(a.attr("y1",30),a.attr("x1",o),a.attr("y2",U),a.attr("x2",o)):"BT"===V&&(a.attr("y1",U),a.attr("x1",o),a.attr("y2",30),a.attr("x2",o)),F.push(o);const c=t.name,s=Q(c),i=e.insert("rect"),h=e.insert("g").attr("class","branchLabel").insert("g").attr("class","label branch-label"+n);h.node().appendChild(s);const d=s.getBBox();i.attr("class","branchLabelBkg label"+n).attr("rx",4).attr("ry",4).attr("x",-d.width-4-(!0===D?.rotateCommitLabel?30:0)).attr("y",-d.height/2+8).attr("width",d.width+18).attr("height",d.height+4),h.attr("transform","translate("+(-d.width-14-(!0===D?.rotateCommitLabel?30:0))+", "+(o-d.height/2-1)+")"),"TB"===V?(i.attr("x",o-d.width/2-10).attr("y",0),h.attr("transform","translate("+(o-d.width/2-5)+", 0)")):"BT"===V?(i.attr("x",o-d.width/2-10).attr("y",U),h.attr("transform","translate("+(o-d.width/2-5)+", "+U+")")):i.attr("transform","translate(-19, "+(o-d.height/2)+")")}))}),"drawBranches"),xt=(0,c.K2)((function(t,r,e,n,o){return j.set(t,{pos:r,index:e}),r+=50+(o?40:0)+("TB"===V||"BT"===V?n.width/2:0)}),"setBranchPosition");var ft={parser:H,db:v,renderer:{draw:(0,c.K2)((function(t,r,e,n){if(J(),c.Rm.debug("in gitgraph renderer",t+"\n","id:",r,e),!D)throw new Error("GitGraph config not found");const o=D.rotateCommitLabel??!1,s=n.db;_=s.getCommits();const h=s.getBranchesAsObjArray();V=s.getDirection();const d=(0,i.Ltv)(`[id="${r}"]`);let m=0;h.forEach(((t,r)=>{const e=Q(t.name),n=d.append("g"),a=n.insert("g").attr("class","branchLabel"),c=a.insert("g").attr("class","label branch-label");c.node()?.appendChild(e);const s=e.getBBox();m=xt(t.name,m,r,s,o),c.remove(),a.remove(),n.remove()})),mt(d,_,!1),D.showBranches&&pt(d,h),gt(d,_),mt(d,_,!0),a._K.insertTitle(d,"gitTitleText",D.titleTopMargin??0,s.getDiagramTitle()),(0,c.mj)(void 0,d,D.diagramPadding,D.useMaxWidth)}),"draw")},styles:(0,c.K2)((t=>`\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0,1,2,3,4,5,6,7].map((r=>`\n .branch-label${r} { fill: ${t["gitBranchLabel"+r]}; }\n .commit${r} { stroke: ${t["git"+r]}; fill: ${t["git"+r]}; }\n .commit-highlight${r} { stroke: ${t["gitInv"+r]}; fill: ${t["gitInv"+r]}; }\n .label${r} { fill: ${t["git"+r]}; }\n .arrow${r} { stroke: ${t["git"+r]}; }\n `)).join("\n")}\n\n .branch {\n stroke-width: 1;\n stroke: ${t.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelColor};}\n .commit-label-bkg { font-size: ${t.commitLabelFontSize}; fill: ${t.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${t.tagLabelFontSize}; fill: ${t.tagLabelColor};}\n .tag-label-bkg { fill: ${t.tagLabelBackground}; stroke: ${t.tagLabelBorder}; }\n .tag-hole { fill: ${t.textColor}; }\n\n .commit-merge {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n .commit-reverse {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${t.primaryColor};\n fill: ${t.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n }\n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8379.c80faf06.js b/pr-preview/pr-976/assets/js/8379.c80faf06.js new file mode 100644 index 0000000000..75b5488d82 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8379.c80faf06.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8379],{59347:(t,e,n)=>{n.d(e,{CP:()=>l,HT:()=>u,PB:()=>h,aC:()=>c,lC:()=>a,m:()=>o,tk:()=>r});var i=n(45567),s=n(16750),r=(0,i.K2)(((t,e)=>{const n=t.append("rect");if(n.attr("x",e.x),n.attr("y",e.y),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("width",e.width),n.attr("height",e.height),e.name&&n.attr("name",e.name),e.rx&&n.attr("rx",e.rx),e.ry&&n.attr("ry",e.ry),void 0!==e.attrs)for(const i in e.attrs)n.attr(i,e.attrs[i]);return e.class&&n.attr("class",e.class),n}),"drawRect"),a=(0,i.K2)(((t,e)=>{const n={x:e.startx,y:e.starty,width:e.stopx-e.startx,height:e.stopy-e.starty,fill:e.fill,stroke:e.stroke,class:"rect"};r(t,n).lower()}),"drawBackgroundRect"),o=(0,i.K2)(((t,e)=>{const n=e.text.replace(i.H1," "),s=t.append("text");s.attr("x",e.x),s.attr("y",e.y),s.attr("class","legend"),s.style("text-anchor",e.anchor),e.class&&s.attr("class",e.class);const r=s.append("tspan");return r.attr("x",e.x+2*e.textMargin),r.text(n),s}),"drawText"),c=(0,i.K2)(((t,e,n,i)=>{const r=t.append("image");r.attr("x",e),r.attr("y",n);const a=(0,s.J)(i);r.attr("xlink:href",a)}),"drawImage"),l=(0,i.K2)(((t,e,n,i)=>{const r=t.append("use");r.attr("x",e),r.attr("y",n);const a=(0,s.J)(i);r.attr("xlink:href",`#${a}`)}),"drawEmbeddedImage"),h=(0,i.K2)((()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0})),"getNoteRect"),u=(0,i.K2)((()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0})),"getTextObj")},18379:(t,e,n)=>{n.d(e,{diagram:()=>Y});var i=n(59347),s=n(45567),r=n(20007),a=function(){var t=(0,s.K2)((function(t,e,n,i){for(n=n||{},i=t.length;i--;n[t[i]]=e);return n}),"o"),e=[6,8,10,11,12,14,16,17,18],n=[1,9],i=[1,10],r=[1,11],a=[1,12],o=[1,13],c=[1,14],l={trace:(0,s.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:(0,s.K2)((function(t,e,n,i,s,r,a){var o=r.length-1;switch(s){case 1:return r[o-1];case 2:case 6:case 7:this.$=[];break;case 3:r[o-1].push(r[o]),this.$=r[o-1];break;case 4:case 5:this.$=r[o];break;case 8:i.setDiagramTitle(r[o].substr(6)),this.$=r[o].substr(6);break;case 9:this.$=r[o].trim(),i.setAccTitle(this.$);break;case 10:case 11:this.$=r[o].trim(),i.setAccDescription(this.$);break;case 12:i.addSection(r[o].substr(8)),this.$=r[o].substr(8);break;case 13:i.addTask(r[o-1],r[o]),this.$="task"}}),"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:n,12:i,14:r,16:a,17:o,18:c},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:n,12:i,14:r,16:a,17:o,18:c},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:(0,s.K2)((function(t,e){if(!e.recoverable){var n=new Error(t);throw n.hash=e,n}this.trace(t)}),"parseError"),parse:(0,s.K2)((function(t){var e=this,n=[0],i=[],r=[null],a=[],o=this.table,c="",l=0,h=0,u=0,y=a.slice.call(arguments,1),p=Object.create(this.lexer),d={yy:{}};for(var f in this.yy)Object.prototype.hasOwnProperty.call(this.yy,f)&&(d.yy[f]=this.yy[f]);p.setInput(t,d.yy),d.yy.lexer=p,d.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var g=p.yylloc;a.push(g);var x=p.options&&p.options.ranges;function m(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,s.K2)((function(t){n.length=n.length-2*t,r.length=r.length-t,a.length=a.length-t}),"popStack"),(0,s.K2)(m,"lex");for(var k,_,b,w,v,K,$,T,M,S={};;){if(b=n[n.length-1],this.defaultActions[b]?w=this.defaultActions[b]:(null==k&&(k=m()),w=o[b]&&o[b][k]),void 0===w||!w.length||!w[0]){var E="";for(K in M=[],o[b])this.terminals_[K]&&K>2&&M.push("'"+this.terminals_[K]+"'");E=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+M.join(", ")+", got '"+(this.terminals_[k]||k)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==k?"end of input":"'"+(this.terminals_[k]||k)+"'"),this.parseError(E,{text:p.match,token:this.terminals_[k]||k,line:p.yylineno,loc:g,expected:M})}if(w[0]instanceof Array&&w.length>1)throw new Error("Parse Error: multiple actions possible at state: "+b+", token: "+k);switch(w[0]){case 1:n.push(k),r.push(p.yytext),a.push(p.yylloc),n.push(w[1]),k=null,_?(k=_,_=null):(h=p.yyleng,c=p.yytext,l=p.yylineno,g=p.yylloc,u>0&&u--);break;case 2:if($=this.productions_[w[1]][1],S.$=r[r.length-$],S._$={first_line:a[a.length-($||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-($||1)].first_column,last_column:a[a.length-1].last_column},x&&(S._$.range=[a[a.length-($||1)].range[0],a[a.length-1].range[1]]),void 0!==(v=this.performAction.apply(S,[c,h,l,d.yy,w[1],r,a].concat(y))))return v;$&&(n=n.slice(0,-1*$*2),r=r.slice(0,-1*$),a=a.slice(0,-1*$)),n.push(this.productions_[w[1]][0]),r.push(S.$),a.push(S._$),T=o[n[n.length-2]][n[n.length-1]],n.push(T);break;case 3:return!0}}return!0}),"parse")},h=function(){return{EOF:1,parseError:(0,s.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,s.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,s.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,s.K2)((function(t){var e=t.length,n=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),n.length-1&&(this.yylineno-=n.length-1);var s=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:n?(n.length===i.length?this.yylloc.first_column:0)+i[i.length-n.length].length-n[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[s[0],s[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,s.K2)((function(){return this._more=!0,this}),"more"),reject:(0,s.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,s.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,s.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,s.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,s.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,s.K2)((function(t,e){var n,i,s;if(this.options.backtrack_lexer&&(s={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(s.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],n=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),n)return n;if(this._backtrack){for(var r in s)this[r]=s[r];return!1}return!1}),"test_match"),next:(0,s.K2)((function(){if(this.done)return this.EOF;var t,e,n,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var s=this._currentRules(),r=0;r<s.length;r++)if((n=this._input.match(this.rules[s[r]]))&&(!e||n[0].length>e[0].length)){if(e=n,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(n,s[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,s[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,s.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,s.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,s.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,s.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,s.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,s.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,s.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,s.K2)((function(t,e,n,i){switch(n){case 0:case 1:case 3:case 4:break;case 2:return 10;case 5:return 4;case 6:return 11;case 7:return this.begin("acc_title"),12;case 8:return this.popState(),"acc_title_value";case 9:return this.begin("acc_descr"),14;case 10:return this.popState(),"acc_descr_value";case 11:this.begin("acc_descr_multiline");break;case 12:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 17;case 15:return 18;case 16:return 19;case 17:return":";case 18:return 6;case 19:return"INVALID"}}),"anonymous"),rules:[/^(?:%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:journey\b)/i,/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:section\s[^#:\n;]+)/i,/^(?:[^#:\n;]+)/i,/^(?::[^#\n;]+)/i,/^(?::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,9,11,14,15,16,17,18,19],inclusive:!0}}}}();function u(){this.yy={}}return l.lexer=h,(0,s.K2)(u,"Parser"),u.prototype=l,l.Parser=u,new u}();a.parser=a;var o=a,c="",l=[],h=[],u=[],y=(0,s.K2)((function(){l.length=0,h.length=0,c="",u.length=0,(0,s.IU)()}),"clear"),p=(0,s.K2)((function(t){c=t,l.push(t)}),"addSection"),d=(0,s.K2)((function(){return l}),"getSections"),f=(0,s.K2)((function(){let t=k();let e=0;for(;!t&&e<100;)t=k(),e++;return h.push(...u),h}),"getTasks"),g=(0,s.K2)((function(){const t=[];h.forEach((e=>{e.people&&t.push(...e.people)}));return[...new Set(t)].sort()}),"updateActors"),x=(0,s.K2)((function(t,e){const n=e.substr(1).split(":");let i=0,s=[];1===n.length?(i=Number(n[0]),s=[]):(i=Number(n[0]),s=n[1].split(","));const r=s.map((t=>t.trim())),a={section:c,type:c,people:r,task:t,score:i};u.push(a)}),"addTask"),m=(0,s.K2)((function(t){const e={section:c,type:c,description:t,task:t,classes:[]};h.push(e)}),"addTaskOrg"),k=(0,s.K2)((function(){const t=(0,s.K2)((function(t){return u[t].processed}),"compileTask");let e=!0;for(const[n,i]of u.entries())t(n),e=e&&i.processed;return e}),"compileTasks"),_=(0,s.K2)((function(){return g()}),"getActors"),b={getConfig:(0,s.K2)((()=>(0,s.D7)().journey),"getConfig"),clear:y,setDiagramTitle:s.ke,getDiagramTitle:s.ab,setAccTitle:s.SV,getAccTitle:s.iN,setAccDescription:s.EI,getAccDescription:s.m7,addSection:p,getSections:d,getTasks:f,addTask:x,addTaskOrg:m,getActors:_},w=(0,s.K2)((t=>`.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${t.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${t.textColor}\n }\n\n .legend {\n fill: ${t.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${t.textColor}\n }\n\n .face {\n ${t.faceColor?`fill: ${t.faceColor}`:"fill: #FFF8DC"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${t.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${t.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${t.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${t.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${t.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${t.tertiaryColor};\n border: 1px solid ${t.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${t.fillType0?`fill: ${t.fillType0}`:""};\n }\n .task-type-1, .section-type-1 {\n ${t.fillType0?`fill: ${t.fillType1}`:""};\n }\n .task-type-2, .section-type-2 {\n ${t.fillType0?`fill: ${t.fillType2}`:""};\n }\n .task-type-3, .section-type-3 {\n ${t.fillType0?`fill: ${t.fillType3}`:""};\n }\n .task-type-4, .section-type-4 {\n ${t.fillType0?`fill: ${t.fillType4}`:""};\n }\n .task-type-5, .section-type-5 {\n ${t.fillType0?`fill: ${t.fillType5}`:""};\n }\n .task-type-6, .section-type-6 {\n ${t.fillType0?`fill: ${t.fillType6}`:""};\n }\n .task-type-7, .section-type-7 {\n ${t.fillType0?`fill: ${t.fillType7}`:""};\n }\n\n .actor-0 {\n ${t.actor0?`fill: ${t.actor0}`:""};\n }\n .actor-1 {\n ${t.actor1?`fill: ${t.actor1}`:""};\n }\n .actor-2 {\n ${t.actor2?`fill: ${t.actor2}`:""};\n }\n .actor-3 {\n ${t.actor3?`fill: ${t.actor3}`:""};\n }\n .actor-4 {\n ${t.actor4?`fill: ${t.actor4}`:""};\n }\n .actor-5 {\n ${t.actor5?`fill: ${t.actor5}`:""};\n }\n`),"getStyles"),v=(0,s.K2)((function(t,e){return(0,i.tk)(t,e)}),"drawRect"),K=(0,s.K2)((function(t,e){const n=15,i=t.append("circle").attr("cx",e.cx).attr("cy",e.cy).attr("class","face").attr("r",n).attr("stroke-width",2).attr("overflow","visible"),a=t.append("g");function o(t){const i=(0,r.JLW)().startAngle(Math.PI/2).endAngle(Math.PI/2*3).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+2)+")")}function c(t){const i=(0,r.JLW)().startAngle(3*Math.PI/2).endAngle(Math.PI/2*5).innerRadius(7.5).outerRadius(n/2.2);t.append("path").attr("class","mouth").attr("d",i).attr("transform","translate("+e.cx+","+(e.cy+7)+")")}function l(t){t.append("line").attr("class","mouth").attr("stroke",2).attr("x1",e.cx-5).attr("y1",e.cy+7).attr("x2",e.cx+5).attr("y2",e.cy+7).attr("class","mouth").attr("stroke-width","1px").attr("stroke","#666")}return a.append("circle").attr("cx",e.cx-5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),a.append("circle").attr("cx",e.cx+5).attr("cy",e.cy-5).attr("r",1.5).attr("stroke-width",2).attr("fill","#666").attr("stroke","#666"),(0,s.K2)(o,"smile"),(0,s.K2)(c,"sad"),(0,s.K2)(l,"ambivalent"),e.score>3?o(a):e.score<3?c(a):l(a),i}),"drawFace"),$=(0,s.K2)((function(t,e){const n=t.append("circle");return n.attr("cx",e.cx),n.attr("cy",e.cy),n.attr("class","actor-"+e.pos),n.attr("fill",e.fill),n.attr("stroke",e.stroke),n.attr("r",e.r),void 0!==n.class&&n.attr("class",n.class),void 0!==e.title&&n.append("title").text(e.title),n}),"drawCircle"),T=(0,s.K2)((function(t,e){return(0,i.m)(t,e)}),"drawText"),M=(0,s.K2)((function(t,e){function n(t,e,n,i,s){return t+","+e+" "+(t+n)+","+e+" "+(t+n)+","+(e+i-s)+" "+(t+n-1.2*s)+","+(e+i)+" "+t+","+(e+i)}(0,s.K2)(n,"genPoints");const i=t.append("polygon");i.attr("points",n(e.x,e.y,50,20,7)),i.attr("class","labelBox"),e.y=e.y+e.labelMargin,e.x=e.x+.5*e.labelMargin,T(t,e)}),"drawLabel"),S=(0,s.K2)((function(t,e,n){const s=t.append("g"),r=(0,i.PB)();r.x=e.x,r.y=e.y,r.fill=e.fill,r.width=n.width*e.taskCount+n.diagramMarginX*(e.taskCount-1),r.height=n.height,r.class="journey-section section-type-"+e.num,r.rx=3,r.ry=3,v(s,r),C(n)(e.text,s,r.x,r.y,r.width,r.height,{class:"journey-section section-type-"+e.num},n,e.colour)}),"drawSection"),E=-1,I=(0,s.K2)((function(t,e,n){const s=e.x+n.width/2,r=t.append("g");E++;r.append("line").attr("id","task"+E).attr("x1",s).attr("y1",e.y).attr("x2",s).attr("y2",450).attr("class","task-line").attr("stroke-width","1px").attr("stroke-dasharray","4 2").attr("stroke","#666"),K(r,{cx:s,cy:300+30*(5-e.score),score:e.score});const a=(0,i.PB)();a.x=e.x,a.y=e.y,a.fill=e.fill,a.width=n.width,a.height=n.height,a.class="task task-type-"+e.num,a.rx=3,a.ry=3,v(r,a);let o=e.x+14;e.people.forEach((t=>{const n=e.actors[t].color,i={cx:o,cy:e.y,r:7,fill:n,stroke:"#000",title:t,pos:e.actors[t].position};$(r,i),o+=10})),C(n)(e.task,r,a.x,a.y,a.width,a.height,{class:"task"},n,e.colour)}),"drawTask"),P=(0,s.K2)((function(t,e){(0,i.lC)(t,e)}),"drawBackgroundRect"),C=function(){function t(t,e,n,s,r,a,o,c){i(e.append("text").attr("x",n+r/2).attr("y",s+a/2+5).style("font-color",c).style("text-anchor","middle").text(t),o)}function e(t,e,n,s,r,a,o,c,l){const{taskFontSize:h,taskFontFamily:u}=c,y=t.split(/<br\s*\/?>/gi);for(let p=0;p<y.length;p++){const t=p*h-h*(y.length-1)/2,c=e.append("text").attr("x",n+r/2).attr("y",s).attr("fill",l).style("text-anchor","middle").style("font-size",h).style("font-family",u);c.append("tspan").attr("x",n+r/2).attr("dy",t).text(y[p]),c.attr("y",s+a/2).attr("dominant-baseline","central").attr("alignment-baseline","central"),i(c,o)}}function n(t,n,s,r,a,o,c,l){const h=n.append("switch"),u=h.append("foreignObject").attr("x",s).attr("y",r).attr("width",a).attr("height",o).attr("position","fixed").append("xhtml:div").style("display","table").style("height","100%").style("width","100%");u.append("div").attr("class","label").style("display","table-cell").style("text-align","center").style("vertical-align","middle").text(t),e(t,h,s,r,a,o,c,l),i(u,c)}function i(t,e){for(const n in e)n in e&&t.attr(n,e[n])}return(0,s.K2)(t,"byText"),(0,s.K2)(e,"byTspan"),(0,s.K2)(n,"byFo"),(0,s.K2)(i,"_setTextAttrs"),function(i){return"fo"===i.textPlacement?n:"old"===i.textPlacement?t:e}}(),A={drawRect:v,drawCircle:$,drawSection:S,drawText:T,drawLabel:M,drawTask:I,drawBackgroundRect:P,initGraphics:(0,s.K2)((function(t){t.append("defs").append("marker").attr("id","arrowhead").attr("refX",5).attr("refY",2).attr("markerWidth",6).attr("markerHeight",4).attr("orient","auto").append("path").attr("d","M 0,0 V 4 L6,2 Z")}),"initGraphics")},j=(0,s.K2)((function(t){Object.keys(t).forEach((function(e){V[e]=t[e]}))}),"setConf"),D={};function L(t){const e=(0,s.D7)().journey;let n=60;Object.keys(D).forEach((i=>{const s=D[i].color,r={cx:20,cy:n,r:7,fill:s,stroke:"#000",pos:D[i].position};A.drawCircle(t,r);const a={x:40,y:n+7,fill:"#666",text:i,textMargin:5|e.boxTextMargin};A.drawText(t,a),n+=20}))}(0,s.K2)(L,"drawActorLegend");var V=(0,s.D7)().journey,B=V.leftMargin,O=(0,s.K2)((function(t,e,n,i){const a=(0,s.D7)().journey,o=(0,s.D7)().securityLevel;let c;"sandbox"===o&&(c=(0,r.Ltv)("#i"+e));const l="sandbox"===o?(0,r.Ltv)(c.nodes()[0].contentDocument.body):(0,r.Ltv)("body");F.init();const h=l.select("#"+e);A.initGraphics(h);const u=i.db.getTasks(),y=i.db.getDiagramTitle(),p=i.db.getActors();for(const s in D)delete D[s];let d=0;p.forEach((t=>{D[t]={color:a.actorColours[d%a.actorColours.length],position:d},d++})),L(h),F.insert(0,0,B,50*Object.keys(D).length),z(h,u,0);const f=F.getBounds();y&&h.append("text").text(y).attr("x",B).attr("font-size","4ex").attr("font-weight","bold").attr("y",25);const g=f.stopy-f.starty+2*a.diagramMarginY,x=B+f.stopx+2*a.diagramMarginX;(0,s.a$)(h,g,x,a.useMaxWidth),h.append("line").attr("x1",B).attr("y1",4*a.height).attr("x2",x-B-4).attr("y2",4*a.height).attr("stroke-width",4).attr("stroke","black").attr("marker-end","url(#arrowhead)");const m=y?70:0;h.attr("viewBox",`${f.startx} -25 ${x} ${g+m}`),h.attr("preserveAspectRatio","xMinYMin meet"),h.attr("height",g+m+25)}),"draw"),F={data:{startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},verticalPos:0,sequenceItems:[],init:(0,s.K2)((function(){this.sequenceItems=[],this.data={startx:void 0,stopx:void 0,starty:void 0,stopy:void 0},this.verticalPos=0}),"init"),updateVal:(0,s.K2)((function(t,e,n,i){void 0===t[e]?t[e]=n:t[e]=i(n,t[e])}),"updateVal"),updateBounds:(0,s.K2)((function(t,e,n,i){const r=(0,s.D7)().journey,a=this;let o=0;function c(c){return(0,s.K2)((function(s){o++;const l=a.sequenceItems.length-o+1;a.updateVal(s,"starty",e-l*r.boxMargin,Math.min),a.updateVal(s,"stopy",i+l*r.boxMargin,Math.max),a.updateVal(F.data,"startx",t-l*r.boxMargin,Math.min),a.updateVal(F.data,"stopx",n+l*r.boxMargin,Math.max),"activation"!==c&&(a.updateVal(s,"startx",t-l*r.boxMargin,Math.min),a.updateVal(s,"stopx",n+l*r.boxMargin,Math.max),a.updateVal(F.data,"starty",e-l*r.boxMargin,Math.min),a.updateVal(F.data,"stopy",i+l*r.boxMargin,Math.max))}),"updateItemBounds")}(0,s.K2)(c,"updateFn"),this.sequenceItems.forEach(c())}),"updateBounds"),insert:(0,s.K2)((function(t,e,n,i){const s=Math.min(t,n),r=Math.max(t,n),a=Math.min(e,i),o=Math.max(e,i);this.updateVal(F.data,"startx",s,Math.min),this.updateVal(F.data,"starty",a,Math.min),this.updateVal(F.data,"stopx",r,Math.max),this.updateVal(F.data,"stopy",o,Math.max),this.updateBounds(s,a,r,o)}),"insert"),bumpVerticalPos:(0,s.K2)((function(t){this.verticalPos=this.verticalPos+t,this.data.stopy=this.verticalPos}),"bumpVerticalPos"),getVerticalPos:(0,s.K2)((function(){return this.verticalPos}),"getVerticalPos"),getBounds:(0,s.K2)((function(){return this.data}),"getBounds")},N=V.sectionFills,R=V.sectionColours,z=(0,s.K2)((function(t,e,n){const i=(0,s.D7)().journey;let r="";const a=n+(2*i.height+i.diagramMarginY);let o=0,c="#CCC",l="black",h=0;for(const[s,u]of e.entries()){if(r!==u.section){c=N[o%N.length],h=o%N.length,l=R[o%R.length];let n=0;const a=u.section;for(let t=s;t<e.length&&e[t].section==a;t++)n+=1;const y={x:s*i.taskMargin+s*i.width+B,y:50,text:u.section,fill:c,num:h,colour:l,taskCount:n};A.drawSection(t,y,i),r=u.section,o++}const n=u.people.reduce(((t,e)=>(D[e]&&(t[e]=D[e]),t)),{});u.x=s*i.taskMargin+s*i.width+B,u.y=a,u.width=i.diagramMarginX,u.height=i.diagramMarginY,u.colour=l,u.fill=c,u.num=h,u.actors=n,A.drawTask(t,u,i),F.insert(u.x,u.y,u.x+u.width+i.taskMargin,450)}}),"drawTasks"),W={setConf:j,draw:O},Y={parser:o,db:b,renderer:W,styles:w,init:(0,s.K2)((t=>{W.setConf(t.journey),b.clear()}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8496.19c721e5.js b/pr-preview/pr-976/assets/js/8496.19c721e5.js new file mode 100644 index 0000000000..6e9d26e264 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8496.19c721e5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8496],{8496:(t,e,i)=>{i.d(e,{diagram:()=>Y});var n=i(45567),r=i(20007),s=i(62334),a=i(697),l=function(){var t=(0,n.K2)((function(t,e,i,n){for(i=i||{},n=t.length;n--;i[t[n]]=e);return i}),"o"),e=[1,3],i=[1,4],r=[1,5],s=[1,6],a=[5,6,8,9,11,13,31,32,33,34,35,36,44,62,63],l=[1,18],o=[2,7],h=[1,22],c=[1,23],u=[1,24],d=[1,25],y=[1,26],p=[1,27],_=[1,20],g=[1,28],E=[1,29],R=[62,63],m=[5,8,9,11,13,31,32,33,34,35,36,44,51,53,62,63],f=[1,47],I=[1,48],S=[1,49],N=[1,50],b=[1,51],k=[1,52],T=[1,53],x=[53,54],w=[1,64],A=[1,60],q=[1,61],v=[1,62],K=[1,63],$=[1,65],O=[1,69],L=[1,70],C=[1,67],M=[1,68],F=[5,8,9,11,13,31,32,33,34,35,36,44,62,63],D={trace:(0,n.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,requirementType:17,requirementName:18,STRUCT_START:19,requirementBody:20,ID:21,COLONSEP:22,id:23,TEXT:24,text:25,RISK:26,riskLevel:27,VERIFYMTHD:28,verifyType:29,STRUCT_STOP:30,REQUIREMENT:31,FUNCTIONAL_REQUIREMENT:32,INTERFACE_REQUIREMENT:33,PERFORMANCE_REQUIREMENT:34,PHYSICAL_REQUIREMENT:35,DESIGN_CONSTRAINT:36,LOW_RISK:37,MED_RISK:38,HIGH_RISK:39,VERIFY_ANALYSIS:40,VERIFY_DEMONSTRATION:41,VERIFY_INSPECTION:42,VERIFY_TEST:43,ELEMENT:44,elementName:45,elementBody:46,TYPE:47,type:48,DOCREF:49,ref:50,END_ARROW_L:51,relationship:52,LINE:53,END_ARROW_R:54,CONTAINS:55,COPIES:56,DERIVES:57,SATISFIES:58,VERIFIES:59,REFINES:60,TRACES:61,unqString:62,qString:63,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",19:"STRUCT_START",21:"ID",22:"COLONSEP",24:"TEXT",26:"RISK",28:"VERIFYMTHD",30:"STRUCT_STOP",31:"REQUIREMENT",32:"FUNCTIONAL_REQUIREMENT",33:"INTERFACE_REQUIREMENT",34:"PERFORMANCE_REQUIREMENT",35:"PHYSICAL_REQUIREMENT",36:"DESIGN_CONSTRAINT",37:"LOW_RISK",38:"MED_RISK",39:"HIGH_RISK",40:"VERIFY_ANALYSIS",41:"VERIFY_DEMONSTRATION",42:"VERIFY_INSPECTION",43:"VERIFY_TEST",44:"ELEMENT",47:"TYPE",49:"DOCREF",51:"END_ARROW_L",53:"LINE",54:"END_ARROW_R",55:"CONTAINS",56:"COPIES",57:"DERIVES",58:"SATISFIES",59:"VERIFIES",60:"REFINES",61:"TRACES",62:"unqString",63:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[14,5],[20,5],[20,5],[20,5],[20,5],[20,2],[20,1],[17,1],[17,1],[17,1],[17,1],[17,1],[17,1],[27,1],[27,1],[27,1],[29,1],[29,1],[29,1],[29,1],[15,5],[46,5],[46,5],[46,2],[46,1],[16,5],[16,5],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[52,1],[18,1],[18,1],[23,1],[23,1],[25,1],[25,1],[45,1],[45,1],[48,1],[48,1],[50,1],[50,1]],performAction:(0,n.K2)((function(t,e,i,n,r,s,a){var l=s.length-1;switch(r){case 4:this.$=s[l].trim(),n.setAccTitle(this.$);break;case 5:case 6:this.$=s[l].trim(),n.setAccDescription(this.$);break;case 7:this.$=[];break;case 13:n.addRequirement(s[l-3],s[l-4]);break;case 14:n.setNewReqId(s[l-2]);break;case 15:n.setNewReqText(s[l-2]);break;case 16:n.setNewReqRisk(s[l-2]);break;case 17:n.setNewReqVerifyMethod(s[l-2]);break;case 20:this.$=n.RequirementType.REQUIREMENT;break;case 21:this.$=n.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 22:this.$=n.RequirementType.INTERFACE_REQUIREMENT;break;case 23:this.$=n.RequirementType.PERFORMANCE_REQUIREMENT;break;case 24:this.$=n.RequirementType.PHYSICAL_REQUIREMENT;break;case 25:this.$=n.RequirementType.DESIGN_CONSTRAINT;break;case 26:this.$=n.RiskLevel.LOW_RISK;break;case 27:this.$=n.RiskLevel.MED_RISK;break;case 28:this.$=n.RiskLevel.HIGH_RISK;break;case 29:this.$=n.VerifyType.VERIFY_ANALYSIS;break;case 30:this.$=n.VerifyType.VERIFY_DEMONSTRATION;break;case 31:this.$=n.VerifyType.VERIFY_INSPECTION;break;case 32:this.$=n.VerifyType.VERIFY_TEST;break;case 33:n.addElement(s[l-3]);break;case 34:n.setNewElementType(s[l-2]);break;case 35:n.setNewElementDocRef(s[l-2]);break;case 38:n.addRelationship(s[l-2],s[l],s[l-4]);break;case 39:n.addRelationship(s[l-2],s[l-4],s[l]);break;case 40:this.$=n.Relationships.CONTAINS;break;case 41:this.$=n.Relationships.COPIES;break;case 42:this.$=n.Relationships.DERIVES;break;case 43:this.$=n.Relationships.SATISFIES;break;case 44:this.$=n.Relationships.VERIFIES;break;case 45:this.$=n.Relationships.REFINES;break;case 46:this.$=n.Relationships.TRACES}}),"anonymous"),table:[{3:1,4:2,6:e,9:i,11:r,13:s},{1:[3]},{3:8,4:2,5:[1,7],6:e,9:i,11:r,13:s},{5:[1,9]},{10:[1,10]},{12:[1,11]},t(a,[2,6]),{3:12,4:2,6:e,9:i,11:r,13:s},{1:[2,2]},{4:17,5:l,7:13,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},t(a,[2,4]),t(a,[2,5]),{1:[2,1]},{8:[1,30]},{4:17,5:l,7:31,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},{4:17,5:l,7:32,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},{4:17,5:l,7:33,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},{4:17,5:l,7:34,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},{4:17,5:l,7:35,8:o,9:i,11:r,13:s,14:14,15:15,16:16,17:19,23:21,31:h,32:c,33:u,34:d,35:y,36:p,44:_,62:g,63:E},{18:36,62:[1,37],63:[1,38]},{45:39,62:[1,40],63:[1,41]},{51:[1,42],53:[1,43]},t(R,[2,20]),t(R,[2,21]),t(R,[2,22]),t(R,[2,23]),t(R,[2,24]),t(R,[2,25]),t(m,[2,49]),t(m,[2,50]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{19:[1,44]},{19:[2,47]},{19:[2,48]},{19:[1,45]},{19:[2,53]},{19:[2,54]},{52:46,55:f,56:I,57:S,58:N,59:b,60:k,61:T},{52:54,55:f,56:I,57:S,58:N,59:b,60:k,61:T},{5:[1,55]},{5:[1,56]},{53:[1,57]},t(x,[2,40]),t(x,[2,41]),t(x,[2,42]),t(x,[2,43]),t(x,[2,44]),t(x,[2,45]),t(x,[2,46]),{54:[1,58]},{5:w,20:59,21:A,24:q,26:v,28:K,30:$},{5:O,30:L,46:66,47:C,49:M},{23:71,62:g,63:E},{23:72,62:g,63:E},t(F,[2,13]),{22:[1,73]},{22:[1,74]},{22:[1,75]},{22:[1,76]},{5:w,20:77,21:A,24:q,26:v,28:K,30:$},t(F,[2,19]),t(F,[2,33]),{22:[1,78]},{22:[1,79]},{5:O,30:L,46:80,47:C,49:M},t(F,[2,37]),t(F,[2,38]),t(F,[2,39]),{23:81,62:g,63:E},{25:82,62:[1,83],63:[1,84]},{27:85,37:[1,86],38:[1,87],39:[1,88]},{29:89,40:[1,90],41:[1,91],42:[1,92],43:[1,93]},t(F,[2,18]),{48:94,62:[1,95],63:[1,96]},{50:97,62:[1,98],63:[1,99]},t(F,[2,36]),{5:[1,100]},{5:[1,101]},{5:[2,51]},{5:[2,52]},{5:[1,102]},{5:[2,26]},{5:[2,27]},{5:[2,28]},{5:[1,103]},{5:[2,29]},{5:[2,30]},{5:[2,31]},{5:[2,32]},{5:[1,104]},{5:[2,55]},{5:[2,56]},{5:[1,105]},{5:[2,57]},{5:[2,58]},{5:w,20:106,21:A,24:q,26:v,28:K,30:$},{5:w,20:107,21:A,24:q,26:v,28:K,30:$},{5:w,20:108,21:A,24:q,26:v,28:K,30:$},{5:w,20:109,21:A,24:q,26:v,28:K,30:$},{5:O,30:L,46:110,47:C,49:M},{5:O,30:L,46:111,47:C,49:M},t(F,[2,14]),t(F,[2,15]),t(F,[2,16]),t(F,[2,17]),t(F,[2,34]),t(F,[2,35])],defaultActions:{8:[2,2],12:[2,1],30:[2,3],31:[2,8],32:[2,9],33:[2,10],34:[2,11],35:[2,12],37:[2,47],38:[2,48],40:[2,53],41:[2,54],83:[2,51],84:[2,52],86:[2,26],87:[2,27],88:[2,28],90:[2,29],91:[2,30],92:[2,31],93:[2,32],95:[2,55],96:[2,56],98:[2,57],99:[2,58]},parseError:(0,n.K2)((function(t,e){if(!e.recoverable){var i=new Error(t);throw i.hash=e,i}this.trace(t)}),"parseError"),parse:(0,n.K2)((function(t){var e=this,i=[0],r=[],s=[null],a=[],l=this.table,o="",h=0,c=0,u=0,d=a.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var g=y.yylloc;a.push(g);var E=y.options&&y.options.ranges;function R(){var t;return"number"!=typeof(t=r.pop()||y.lex()||1)&&(t instanceof Array&&(t=(r=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,n.K2)((function(t){i.length=i.length-2*t,s.length=s.length-t,a.length=a.length-t}),"popStack"),(0,n.K2)(R,"lex");for(var m,f,I,S,N,b,k,T,x,w={};;){if(I=i[i.length-1],this.defaultActions[I]?S=this.defaultActions[I]:(null==m&&(m=R()),S=l[I]&&l[I][m]),void 0===S||!S.length||!S[0]){var A="";for(b in x=[],l[I])this.terminals_[b]&&b>2&&x.push("'"+this.terminals_[b]+"'");A=y.showPosition?"Parse error on line "+(h+1)+":\n"+y.showPosition()+"\nExpecting "+x.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(h+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(A,{text:y.match,token:this.terminals_[m]||m,line:y.yylineno,loc:g,expected:x})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+I+", token: "+m);switch(S[0]){case 1:i.push(m),s.push(y.yytext),a.push(y.yylloc),i.push(S[1]),m=null,f?(m=f,f=null):(c=y.yyleng,o=y.yytext,h=y.yylineno,g=y.yylloc,u>0&&u--);break;case 2:if(k=this.productions_[S[1]][1],w.$=s[s.length-k],w._$={first_line:a[a.length-(k||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(k||1)].first_column,last_column:a[a.length-1].last_column},E&&(w._$.range=[a[a.length-(k||1)].range[0],a[a.length-1].range[1]]),void 0!==(N=this.performAction.apply(w,[o,c,h,p.yy,S[1],s,a].concat(d))))return N;k&&(i=i.slice(0,-1*k*2),s=s.slice(0,-1*k),a=a.slice(0,-1*k)),i.push(this.productions_[S[1]][0]),s.push(w.$),a.push(w._$),T=l[i[i.length-2]][i[i.length-1]],i.push(T);break;case 3:return!0}}return!0}),"parse")},P=function(){return{EOF:1,parseError:(0,n.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,n.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,n.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,n.K2)((function(t){var e=t.length,i=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var n=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var r=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===n.length?this.yylloc.first_column:0)+n[n.length-i.length].length-i[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[r[0],r[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,n.K2)((function(){return this._more=!0,this}),"more"),reject:(0,n.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,n.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,n.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,n.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,n.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,n.K2)((function(t,e){var i,n,r;if(this.options.backtrack_lexer&&(r={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(r.yylloc.range=this.yylloc.range.slice(0))),(n=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=n.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:n?n[n.length-1].length-n[n.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],i=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),i)return i;if(this._backtrack){for(var s in r)this[s]=r[s];return!1}return!1}),"test_match"),next:(0,n.K2)((function(){if(this.done)return this.EOF;var t,e,i,n;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var r=this._currentRules(),s=0;s<r.length;s++)if((i=this._input.match(this.rules[r[s]]))&&(!e||i[0].length>e[0].length)){if(e=i,n=s,this.options.backtrack_lexer){if(!1!==(t=this.test_match(i,r[s])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,r[n]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,n.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,n.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,n.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,n.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,n.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,n.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,n.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,n.K2)((function(t,e,i,n){switch(i){case 0:return"title";case 1:return this.begin("acc_title"),9;case 2:return this.popState(),"acc_title_value";case 3:return this.begin("acc_descr"),11;case 4:return this.popState(),"acc_descr_value";case 5:this.begin("acc_descr_multiline");break;case 6:case 48:this.popState();break;case 7:return"acc_descr_multiline_value";case 8:return 5;case 9:case 10:case 11:break;case 12:return 8;case 13:return 6;case 14:return 19;case 15:return 30;case 16:return 22;case 17:return 21;case 18:return 24;case 19:return 26;case 20:return 28;case 21:return 31;case 22:return 32;case 23:return 33;case 24:return 34;case 25:return 35;case 26:return 36;case 27:return 37;case 28:return 38;case 29:return 39;case 30:return 40;case 31:return 41;case 32:return 42;case 33:return 43;case 34:return 44;case 35:return 55;case 36:return 56;case 37:return 57;case 38:return 58;case 39:return 59;case 40:return 60;case 41:return 61;case 42:return 47;case 43:return 49;case 44:return 51;case 45:return 54;case 46:return 53;case 47:this.begin("string");break;case 49:return"qString";case 50:return e.yytext=e.yytext.trim(),62}}),"anonymous"),rules:[/^(?:title\s[^#\n;]+)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:(\r?\n)+)/i,/^(?:\s+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:$)/i,/^(?:requirementDiagram\b)/i,/^(?:\{)/i,/^(?:\})/i,/^(?::)/i,/^(?:id\b)/i,/^(?:text\b)/i,/^(?:risk\b)/i,/^(?:verifyMethod\b)/i,/^(?:requirement\b)/i,/^(?:functionalRequirement\b)/i,/^(?:interfaceRequirement\b)/i,/^(?:performanceRequirement\b)/i,/^(?:physicalRequirement\b)/i,/^(?:designConstraint\b)/i,/^(?:low\b)/i,/^(?:medium\b)/i,/^(?:high\b)/i,/^(?:analysis\b)/i,/^(?:demonstration\b)/i,/^(?:inspection\b)/i,/^(?:test\b)/i,/^(?:element\b)/i,/^(?:contains\b)/i,/^(?:copies\b)/i,/^(?:derives\b)/i,/^(?:satisfies\b)/i,/^(?:verifies\b)/i,/^(?:refines\b)/i,/^(?:traces\b)/i,/^(?:type\b)/i,/^(?:docref\b)/i,/^(?:<-)/i,/^(?:->)/i,/^(?:-)/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[\w][^\r\n\{\<\>\-\=]*)/i],conditions:{acc_descr_multiline:{rules:[6,7],inclusive:!1},acc_descr:{rules:[4],inclusive:!1},acc_title:{rules:[2],inclusive:!1},unqString:{rules:[],inclusive:!1},token:{rules:[],inclusive:!1},string:{rules:[48,49],inclusive:!1},INITIAL:{rules:[0,1,3,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,50],inclusive:!0}}}}();function V(){this.yy={}}return D.lexer=P,(0,n.K2)(V,"Parser"),V.prototype=D,D.Parser=V,new V}();l.parser=l;var o=l,h=[],c={},u=new Map,d={},y=new Map,p=(0,n.K2)(((t,e)=>(u.has(t)||u.set(t,{name:t,type:e,id:c.id,text:c.text,risk:c.risk,verifyMethod:c.verifyMethod}),c={},u.get(t))),"addRequirement"),_=(0,n.K2)((()=>u),"getRequirements"),g=(0,n.K2)((t=>{void 0!==c&&(c.id=t)}),"setNewReqId"),E=(0,n.K2)((t=>{void 0!==c&&(c.text=t)}),"setNewReqText"),R=(0,n.K2)((t=>{void 0!==c&&(c.risk=t)}),"setNewReqRisk"),m=(0,n.K2)((t=>{void 0!==c&&(c.verifyMethod=t)}),"setNewReqVerifyMethod"),f=(0,n.K2)((t=>(y.has(t)||(y.set(t,{name:t,type:d.type,docRef:d.docRef}),n.Rm.info("Added new requirement: ",t)),d={},y.get(t))),"addElement"),I=(0,n.K2)((()=>y),"getElements"),S=(0,n.K2)((t=>{void 0!==d&&(d.type=t)}),"setNewElementType"),N=(0,n.K2)((t=>{void 0!==d&&(d.docRef=t)}),"setNewElementDocRef"),b=(0,n.K2)(((t,e,i)=>{h.push({type:t,src:e,dst:i})}),"addRelationship"),k=(0,n.K2)((()=>h),"getRelationships"),T=(0,n.K2)((()=>{h=[],c={},u=new Map,d={},y=new Map,(0,n.IU)()}),"clear"),x={RequirementType:{REQUIREMENT:"Requirement",FUNCTIONAL_REQUIREMENT:"Functional Requirement",INTERFACE_REQUIREMENT:"Interface Requirement",PERFORMANCE_REQUIREMENT:"Performance Requirement",PHYSICAL_REQUIREMENT:"Physical Requirement",DESIGN_CONSTRAINT:"Design Constraint"},RiskLevel:{LOW_RISK:"Low",MED_RISK:"Medium",HIGH_RISK:"High"},VerifyType:{VERIFY_ANALYSIS:"Analysis",VERIFY_DEMONSTRATION:"Demonstration",VERIFY_INSPECTION:"Inspection",VERIFY_TEST:"Test"},Relationships:{CONTAINS:"contains",COPIES:"copies",DERIVES:"derives",SATISFIES:"satisfies",VERIFIES:"verifies",REFINES:"refines",TRACES:"traces"},getConfig:(0,n.K2)((()=>(0,n.D7)().req),"getConfig"),addRequirement:p,getRequirements:_,setNewReqId:g,setNewReqText:E,setNewReqRisk:R,setNewReqVerifyMethod:m,setAccTitle:n.SV,getAccTitle:n.iN,setAccDescription:n.EI,getAccDescription:n.m7,addElement:f,getElements:I,setNewElementType:S,setNewElementDocRef:N,addRelationship:b,getRelationships:k,clear:T},w=(0,n.K2)((t=>`\n\n marker {\n fill: ${t.relationColor};\n stroke: ${t.relationColor};\n }\n\n marker.cross {\n stroke: ${t.lineColor};\n }\n\n svg {\n font-family: ${t.fontFamily};\n font-size: ${t.fontSize};\n }\n\n .reqBox {\n fill: ${t.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${t.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${t.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${t.requirementBorderColor};\n stroke-width: ${t.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${t.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${t.relationLabelColor};\n }\n\n`),"getStyles"),A={CONTAINS:"contains",ARROW:"arrow"},q={ReqMarkers:A,insertLineEndings:(0,n.K2)(((t,e)=>{let i=t.append("defs").append("marker").attr("id",A.CONTAINS+"_line_ending").attr("refX",0).attr("refY",e.line_height/2).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("g");i.append("circle").attr("cx",e.line_height/2).attr("cy",e.line_height/2).attr("r",e.line_height/2).attr("fill","none"),i.append("line").attr("x1",0).attr("x2",e.line_height).attr("y1",e.line_height/2).attr("y2",e.line_height/2).attr("stroke-width",1),i.append("line").attr("y1",0).attr("y2",e.line_height).attr("x1",e.line_height/2).attr("x2",e.line_height/2).attr("stroke-width",1),t.append("defs").append("marker").attr("id",A.ARROW+"_line_ending").attr("refX",e.line_height).attr("refY",.5*e.line_height).attr("markerWidth",e.line_height).attr("markerHeight",e.line_height).attr("orient","auto").append("path").attr("d",`M0,0\n L${e.line_height},${e.line_height/2}\n M${e.line_height},${e.line_height/2}\n L0,${e.line_height}`).attr("stroke-width",1)}),"insertLineEndings")},v={},K=0,$=(0,n.K2)(((t,e)=>t.insert("rect","#"+e).attr("class","req reqBox").attr("x",0).attr("y",0).attr("width",v.rect_min_width+"px").attr("height",v.rect_min_height+"px")),"newRectNode"),O=(0,n.K2)(((t,e,i)=>{let n=v.rect_min_width/2,r=t.append("text").attr("class","req reqLabel reqTitle").attr("id",e).attr("x",n).attr("y",v.rect_padding).attr("dominant-baseline","hanging"),s=0;i.forEach((t=>{0==s?r.append("tspan").attr("text-anchor","middle").attr("x",v.rect_min_width/2).attr("dy",0).text(t):r.append("tspan").attr("text-anchor","middle").attr("x",v.rect_min_width/2).attr("dy",.75*v.line_height).text(t),s++}));let a=1.5*v.rect_padding+s*v.line_height*.75;return t.append("line").attr("class","req-title-line").attr("x1","0").attr("x2",v.rect_min_width).attr("y1",a).attr("y2",a),{titleNode:r,y:a}}),"newTitleNode"),L=(0,n.K2)(((t,e,i,n)=>{let r=t.append("text").attr("class","req reqLabel").attr("id",e).attr("x",v.rect_padding).attr("y",n).attr("dominant-baseline","hanging"),s=0;let a=[];return i.forEach((t=>{let e=t.length;for(;e>30&&s<3;){let i=t.substring(0,30);e=(t=t.substring(30,t.length)).length,a[a.length]=i,s++}if(3==s){let t=a[a.length-1];a[a.length-1]=t.substring(0,t.length-4)+"..."}else a[a.length]=t;s=0})),a.forEach((t=>{r.append("tspan").attr("x",v.rect_padding).attr("dy",v.line_height).text(t)})),r}),"newBodyNode"),C=(0,n.K2)(((t,e,i,n)=>{const r=e.node().getTotalLength(),s=e.node().getPointAtLength(.5*r),a="rel"+K;K++;const l=t.append("text").attr("class","req relationshipLabel").attr("id",a).attr("x",s.x).attr("y",s.y).attr("text-anchor","middle").attr("dominant-baseline","middle").text(n).node().getBBox();t.insert("rect","#"+a).attr("class","req reqLabelBox").attr("x",s.x-l.width/2).attr("y",s.y-l.height/2).attr("width",l.width).attr("height",l.height).attr("fill","white").attr("fill-opacity","85%")}),"addEdgeLabel"),M=(0,n.K2)((function(t,e,i,s,a){const l=i.edge(U(e.src),U(e.dst)),o=(0,r.n8j)().x((function(t){return t.x})).y((function(t){return t.y})),h=t.insert("path","#"+s).attr("class","er relationshipLine").attr("d",o(l.points)).attr("fill","none");e.type==a.db.Relationships.CONTAINS?h.attr("marker-start","url("+n.Y2.getUrl(v.arrowMarkerAbsolute)+"#"+e.type+"_line_ending)"):(h.attr("stroke-dasharray","10,7"),h.attr("marker-end","url("+n.Y2.getUrl(v.arrowMarkerAbsolute)+"#"+q.ReqMarkers.ARROW+"_line_ending)")),C(t,h,v,`<<${e.type}>>`)}),"drawRelationshipFromLayout"),F=(0,n.K2)(((t,e,i)=>{t.forEach(((t,r)=>{r=U(r),n.Rm.info("Added new requirement: ",r);const s=i.append("g").attr("id",r),a=$(s,"req-"+r);let l=[],o=O(s,r+"_title",[`<<${t.type}>>`,`${t.name}`]);l.push(o.titleNode);let h=L(s,r+"_body",[`Id: ${t.id}`,`Text: ${t.text}`,`Risk: ${t.risk}`,`Verification: ${t.verifyMethod}`],o.y);l.push(h);const c=a.node().getBBox();e.setNode(r,{width:c.width,height:c.height,shape:"rect",id:r})}))}),"drawReqs"),D=(0,n.K2)(((t,e,i)=>{t.forEach(((t,n)=>{const r=U(n),s=i.append("g").attr("id",r),a="element-"+r,l=$(s,a);let o=[],h=O(s,a+"_title",["<<Element>>",`${n}`]);o.push(h.titleNode);let c=L(s,a+"_body",[`Type: ${t.type||"Not Specified"}`,`Doc Ref: ${t.docRef||"None"}`],h.y);o.push(c);const u=l.node().getBBox();e.setNode(r,{width:u.width,height:u.height,shape:"rect",id:r})}))}),"drawElements"),P=(0,n.K2)(((t,e)=>(t.forEach((function(t){let i=U(t.src),n=U(t.dst);e.setEdge(i,n,{relationship:t})})),t)),"addRelationships"),V=(0,n.K2)((function(t,e){e.nodes().forEach((function(i){void 0!==i&&void 0!==e.node(i)&&(t.select("#"+i),t.select("#"+i).attr("transform","translate("+(e.node(i).x-e.node(i).width/2)+","+(e.node(i).y-e.node(i).height/2)+" )"))}))}),"adjustEntities"),U=(0,n.K2)((t=>t.replace(/\s/g,"").replace(/\./g,"_")),"elementString"),Y={parser:o,db:x,renderer:{draw:(0,n.K2)(((t,e,i,l)=>{const o=(v=(0,n.D7)().requirement).securityLevel;let h;"sandbox"===o&&(h=(0,r.Ltv)("#i"+e));const c=("sandbox"===o?(0,r.Ltv)(h.nodes()[0].contentDocument.body):(0,r.Ltv)("body")).select(`[id='${e}']`);q.insertLineEndings(c,v);const u=new a.T({multigraph:!1,compound:!1,directed:!0}).setGraph({rankdir:v.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));let d=l.db.getRequirements(),y=l.db.getElements(),p=l.db.getRelationships();F(d,u,c),D(y,u,c),P(p,u),(0,s.Zp)(u),V(c,u),p.forEach((function(t){M(c,t,u,e,l)}));const _=v.rect_padding,g=c.node().getBBox(),E=g.width+2*_,R=g.height+2*_;(0,n.a$)(c,R,E,v.useMaxWidth),c.attr("viewBox",`${g.x-_} ${g.y-_} ${E} ${R}`)}),"draw")},styles:w}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8731.c272170f.js b/pr-preview/pr-976/assets/js/8731.c272170f.js new file mode 100644 index 0000000000..83f1f369ca --- /dev/null +++ b/pr-preview/pr-976/assets/js/8731.c272170f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8731],{59850:(e,t,n)=>{t.Qi=t.XO=void 0;const r=n(69590),i=n(78585),s=n(62676);var o;!function(e){e.None=Object.freeze({isCancellationRequested:!1,onCancellationRequested:s.Event.None}),e.Cancelled=Object.freeze({isCancellationRequested:!0,onCancellationRequested:s.Event.None}),e.is=function(t){const n=t;return n&&(n===e.None||n===e.Cancelled||i.boolean(n.isCancellationRequested)&&!!n.onCancellationRequested)}}(o||(t.XO=o={}));const a=Object.freeze((function(e,t){const n=(0,r.default)().timer.setTimeout(e.bind(t),0);return{dispose(){n.dispose()}}}));class c{constructor(){this._isCancelled=!1}cancel(){this._isCancelled||(this._isCancelled=!0,this._emitter&&(this._emitter.fire(void 0),this.dispose()))}get isCancellationRequested(){return this._isCancelled}get onCancellationRequested(){return this._isCancelled?a:(this._emitter||(this._emitter=new s.Emitter),this._emitter.event)}dispose(){this._emitter&&(this._emitter.dispose(),this._emitter=void 0)}}t.Qi=class{get token(){return this._token||(this._token=new c),this._token}cancel(){this._token?this._token.cancel():this._token=o.Cancelled}dispose(){this._token?this._token instanceof c&&this._token.dispose():this._token=o.None}}},62676:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Emitter=t.Event=void 0;const r=n(69590);var i;!function(e){const t={dispose(){}};e.None=function(){return t}}(i||(t.Event=i={}));class s{add(e,t=null,n){this._callbacks||(this._callbacks=[],this._contexts=[]),this._callbacks.push(e),this._contexts.push(t),Array.isArray(n)&&n.push({dispose:()=>this.remove(e,t)})}remove(e,t=null){if(!this._callbacks)return;let n=!1;for(let r=0,i=this._callbacks.length;r<i;r++)if(this._callbacks[r]===e){if(this._contexts[r]===t)return this._callbacks.splice(r,1),void this._contexts.splice(r,1);n=!0}if(n)throw new Error("When adding a listener with a context, you should remove it with the same context")}invoke(...e){if(!this._callbacks)return[];const t=[],n=this._callbacks.slice(0),i=this._contexts.slice(0);for(let o=0,a=n.length;o<a;o++)try{t.push(n[o].apply(i[o],e))}catch(s){(0,r.default)().console.error(s)}return t}isEmpty(){return!this._callbacks||0===this._callbacks.length}dispose(){this._callbacks=void 0,this._contexts=void 0}}class o{constructor(e){this._options=e}get event(){return this._event||(this._event=(e,t,n)=>{this._callbacks||(this._callbacks=new s),this._options&&this._options.onFirstListenerAdd&&this._callbacks.isEmpty()&&this._options.onFirstListenerAdd(this),this._callbacks.add(e,t);const r={dispose:()=>{this._callbacks&&(this._callbacks.remove(e,t),r.dispose=o._noop,this._options&&this._options.onLastListenerRemove&&this._callbacks.isEmpty()&&this._options.onLastListenerRemove(this))}};return Array.isArray(n)&&n.push(r),r}),this._event}fire(e){this._callbacks&&this._callbacks.invoke.call(this._callbacks,e)}dispose(){this._callbacks&&(this._callbacks.dispose(),this._callbacks=void 0)}}t.Emitter=o,o._noop=function(){}},78585:(e,t)=>{function n(e){return"string"==typeof e||e instanceof String}function r(e){return Array.isArray(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.stringArray=t.array=t.func=t.error=t.number=t.string=t.boolean=void 0,t.boolean=function(e){return!0===e||!1===e},t.string=n,t.number=function(e){return"number"==typeof e||e instanceof Number},t.error=function(e){return e instanceof Error},t.func=function(e){return"function"==typeof e},t.array=r,t.stringArray=function(e){return r(e)&&e.every((e=>n(e)))}},69590:(e,t)=>{let n;function r(){if(void 0===n)throw new Error("No runtime abstraction layer installed");return n}Object.defineProperty(t,"__esModule",{value:!0}),function(e){e.install=function(e){if(void 0===e)throw new Error("No runtime abstraction layer provided");n=e}}(r||(r={})),t.default=r},97021:(e,t,n)=>{n.d(t,{v:()=>a});var r=n(19369),i=n(33394),s=class extends r.mR{static{(0,r.K2)(this,"InfoTokenBuilder")}constructor(){super(["info","showInfo"])}},o={parser:{TokenBuilder:(0,r.K2)((()=>new s),"TokenBuilder"),ValueConverter:(0,r.K2)((()=>new r.Tm),"ValueConverter")}};function a(e=i.DD){const t=(0,i.WQ)((0,i.uM)(e),r.sr),n=(0,i.WQ)((0,i.tG)({shared:t}),r.e5,o);return t.ServiceRegistry.register(n),{shared:t,Info:n}}(0,r.K2)(a,"createInfoServices")},88685:(e,t,n)=>{n.d(t,{f:()=>c});var r=n(19369),i=n(33394),s=class extends r.mR{static{(0,r.K2)(this,"PieTokenBuilder")}constructor(){super(["pie","showData"])}},o=class extends r.dg{static{(0,r.K2)(this,"PieValueConverter")}runCustomConverter(e,t,n){if("PIE_SECTION_LABEL"===e.name)return t.replace(/"/g,"").trim()}},a={parser:{TokenBuilder:(0,r.K2)((()=>new s),"TokenBuilder"),ValueConverter:(0,r.K2)((()=>new o),"ValueConverter")}};function c(e=i.DD){const t=(0,i.WQ)((0,i.uM)(e),r.sr),n=(0,i.WQ)((0,i.tG)({shared:t}),r.KX,a);return t.ServiceRegistry.register(n),{shared:t,Pie:n}}(0,r.K2)(c,"createPieServices")},71609:(e,t,n)=>{n.d(t,{$:()=>a});var r=n(19369),i=n(33394),s=class extends r.mR{static{(0,r.K2)(this,"PacketTokenBuilder")}constructor(){super(["packet-beta"])}},o={parser:{TokenBuilder:(0,r.K2)((()=>new s),"TokenBuilder"),ValueConverter:(0,r.K2)((()=>new r.Tm),"ValueConverter")}};function a(e=i.DD){const t=(0,i.WQ)((0,i.uM)(e),r.sr),n=(0,i.WQ)((0,i.tG)({shared:t}),r.AM,o);return t.ServiceRegistry.register(n),{shared:t,Packet:n}}(0,r.K2)(a,"createPacketServices")},49936:(e,t,n)=>{n.d(t,{S:()=>c});var r=n(19369),i=n(33394),s=class extends r.mR{static{(0,r.K2)(this,"ArchitectureTokenBuilder")}constructor(){super(["architecture"])}},o=class extends r.dg{static{(0,r.K2)(this,"ArchitectureValueConverter")}runCustomConverter(e,t,n){return"ARCH_ICON"===e.name?t.replace(/[()]/g,"").trim():"ARCH_TEXT_ICON"===e.name?t.replace(/["()]/g,""):"ARCH_TITLE"===e.name?t.replace(/[[\]]/g,"").trim():void 0}},a={parser:{TokenBuilder:(0,r.K2)((()=>new s),"TokenBuilder"),ValueConverter:(0,r.K2)((()=>new o),"ValueConverter")}};function c(e=i.DD){const t=(0,i.WQ)((0,i.uM)(e),r.sr),n=(0,i.WQ)((0,i.tG)({shared:t}),r.jE,a);return t.ServiceRegistry.register(n),{shared:t,Architecture:n}}(0,r.K2)(c,"createArchitectureServices")},82785:(e,t,n)=>{n.d(t,{b:()=>a});var r=n(19369),i=n(33394),s=class extends r.mR{static{(0,r.K2)(this,"GitGraphTokenBuilder")}constructor(){super(["gitGraph"])}},o={parser:{TokenBuilder:(0,r.K2)((()=>new s),"TokenBuilder"),ValueConverter:(0,r.K2)((()=>new r.Tm),"ValueConverter")}};function a(e=i.DD){const t=(0,i.WQ)((0,i.uM)(e),r.sr),n=(0,i.WQ)((0,i.tG)({shared:t}),r.eZ,o);return t.ServiceRegistry.register(n),{shared:t,GitGraph:n}}(0,r.K2)(a,"createGitGraphServices")},19369:(e,t,n)=>{n.d(t,{AM:()=>$,K2:()=>s,KX:()=>w,Tm:()=>P,dg:()=>_,e5:()=>C,eZ:()=>O,jE:()=>L,mR:()=>M,sr:()=>N});var r=n(33394),i=Object.defineProperty,s=(e,t)=>i(e,"name",{value:t,configurable:!0});s((function(e){return g.isInstance(e,"Architecture")}),"isArchitecture");var o="Branch";s((function(e){return g.isInstance(e,o)}),"isBranch");var a="Commit";s((function(e){return g.isInstance(e,a)}),"isCommit");s((function(e){return g.isInstance(e,"Common")}),"isCommon");var c="GitGraph";s((function(e){return g.isInstance(e,c)}),"isGitGraph");s((function(e){return g.isInstance(e,"Info")}),"isInfo");var l="Merge";s((function(e){return g.isInstance(e,l)}),"isMerge");s((function(e){return g.isInstance(e,"Packet")}),"isPacket");s((function(e){return g.isInstance(e,"PacketBlock")}),"isPacketBlock");s((function(e){return g.isInstance(e,"Pie")}),"isPie");s((function(e){return g.isInstance(e,"PieSection")}),"isPieSection");var u,d,h,f,p,m=class extends r.kD{static{s(this,"MermaidAstReflection")}getAllTypes(){return["Architecture","Branch","Checkout","CherryPicking","Commit","Common","Direction","Edge","GitGraph","Group","Info","Junction","Merge","Packet","PacketBlock","Pie","PieSection","Service","Statement"]}computeIsSubtype(e,t){switch(e){case o:case"Checkout":case"CherryPicking":case a:case l:return this.isSubtype("Statement",t);case"Direction":return this.isSubtype(c,t);default:return!1}}getReferenceType(e){const t=`${e.container.$type}:${e.property}`;throw new Error(`${t} is not a valid reference id.`)}getTypeMetaData(e){switch(e){case"Architecture":return{name:"Architecture",properties:[{name:"accDescr"},{name:"accTitle"},{name:"edges",defaultValue:[]},{name:"groups",defaultValue:[]},{name:"junctions",defaultValue:[]},{name:"services",defaultValue:[]},{name:"title"}]};case"Branch":return{name:"Branch",properties:[{name:"name"},{name:"order"}]};case"Checkout":return{name:"Checkout",properties:[{name:"branch"}]};case"CherryPicking":return{name:"CherryPicking",properties:[{name:"id"},{name:"parent"},{name:"tags",defaultValue:[]}]};case"Commit":return{name:"Commit",properties:[{name:"id"},{name:"message"},{name:"tags",defaultValue:[]},{name:"type"}]};case"Common":return{name:"Common",properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case"Edge":return{name:"Edge",properties:[{name:"lhsDir"},{name:"lhsGroup",defaultValue:!1},{name:"lhsId"},{name:"lhsInto",defaultValue:!1},{name:"rhsDir"},{name:"rhsGroup",defaultValue:!1},{name:"rhsId"},{name:"rhsInto",defaultValue:!1},{name:"title"}]};case"GitGraph":return{name:"GitGraph",properties:[{name:"accDescr"},{name:"accTitle"},{name:"statements",defaultValue:[]},{name:"title"}]};case"Group":return{name:"Group",properties:[{name:"icon"},{name:"id"},{name:"in"},{name:"title"}]};case"Info":return{name:"Info",properties:[{name:"accDescr"},{name:"accTitle"},{name:"title"}]};case"Junction":return{name:"Junction",properties:[{name:"id"},{name:"in"}]};case"Merge":return{name:"Merge",properties:[{name:"branch"},{name:"id"},{name:"tags",defaultValue:[]},{name:"type"}]};case"Packet":return{name:"Packet",properties:[{name:"accDescr"},{name:"accTitle"},{name:"blocks",defaultValue:[]},{name:"title"}]};case"PacketBlock":return{name:"PacketBlock",properties:[{name:"end"},{name:"label"},{name:"start"}]};case"Pie":return{name:"Pie",properties:[{name:"accDescr"},{name:"accTitle"},{name:"sections",defaultValue:[]},{name:"showData",defaultValue:!1},{name:"title"}]};case"PieSection":return{name:"PieSection",properties:[{name:"label"},{name:"value"}]};case"Service":return{name:"Service",properties:[{name:"icon"},{name:"iconText"},{name:"id"},{name:"in"},{name:"title"}]};case"Direction":return{name:"Direction",properties:[{name:"accDescr"},{name:"accTitle"},{name:"dir"},{name:"statements",defaultValue:[]},{name:"title"}]};default:return{name:e,properties:[]}}}},g=new m,y=s((()=>u??(u=(0,r.y0)('{"$type":"Grammar","isDeclared":true,"name":"Info","imports":[],"rules":[{"$type":"ParserRule","name":"Info","entry":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"info"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"Keyword","value":"showInfo"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"*"}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"?"}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"TitleAndAccessibilities","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"EOL","fragment":true,"dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}'))),"InfoGrammar"),A=s((()=>d??(d=(0,r.y0)('{"$type":"Grammar","isDeclared":true,"name":"Packet","imports":[],"rules":[{"$type":"ParserRule","name":"Packet","entry":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"packet-beta"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"Assignment","feature":"blocks","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"+"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PacketBlock","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"start","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"end","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}}],"cardinality":"?"},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/0|[1-9][0-9]*/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|\'[^\']*\'/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"TitleAndAccessibilities","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"EOL","fragment":true,"dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}'))),"PacketGrammar"),T=s((()=>h??(h=(0,r.y0)('{"$type":"Grammar","isDeclared":true,"name":"Pie","imports":[],"rules":[{"$type":"ParserRule","name":"Pie","entry":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"pie"},{"$type":"Assignment","feature":"showData","operator":"?=","terminal":{"$type":"Keyword","value":"showData"},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"*"}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"Assignment","feature":"sections","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]},"cardinality":"+"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"PieSection","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"label","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}},{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"value","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"PIE_SECTION_LABEL","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]+\\"/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"PIE_SECTION_VALUE","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/(0|[1-9][0-9]*)(\\\\.[0-9]+)?/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"TitleAndAccessibilities","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"EOL","fragment":true,"dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}'))),"PieGrammar"),v=s((()=>f??(f=(0,r.y0)('{"$type":"Grammar","isDeclared":true,"name":"Architecture","imports":[],"rules":[{"$type":"ParserRule","name":"Architecture","entry":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"Keyword","value":"architecture-beta"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]}]},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[],"cardinality":"*"}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","fragment":true,"definition":{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"groups","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}},{"$type":"Assignment","feature":"services","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@6"},"arguments":[]}},{"$type":"Assignment","feature":"junctions","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@7"},"arguments":[]}},{"$type":"Assignment","feature":"edges","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@8"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"LeftPort","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Keyword","value":":"},{"$type":"Assignment","feature":"lhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"RightPort","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"rhsDir","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@9"},"arguments":[]}},{"$type":"Keyword","value":":"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Arrow","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]},{"$type":"Assignment","feature":"lhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},"cardinality":"?"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"--"},{"$type":"Group","elements":[{"$type":"Keyword","value":"-"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]}},{"$type":"Keyword","value":"-"}]}]},{"$type":"Assignment","feature":"rhsInto","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Group","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"group"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]},"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Service","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"service"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"iconText","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"Assignment","feature":"icon","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]}}],"cardinality":"?"},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},"cardinality":"?"},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Junction","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"junction"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"in"},{"$type":"Assignment","feature":"in","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Edge","definition":{"$type":"Group","elements":[{"$type":"Assignment","feature":"lhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"lhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]},{"$type":"Assignment","feature":"rhsId","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@10"},"arguments":[]}},{"$type":"Assignment","feature":"rhsGroup","operator":"?=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"ARROW_DIRECTION","definition":{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"TerminalAlternatives","elements":[{"$type":"CharacterRange","left":{"$type":"Keyword","value":"L"}},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"R"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"T"}}]},{"$type":"CharacterRange","left":{"$type":"Keyword","value":"B"}}]},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_ID","definition":{"$type":"RegexToken","regex":"/[\\\\w]+/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TEXT_ICON","definition":{"$type":"RegexToken","regex":"/\\\\(\\"[^\\"]+\\"\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_ICON","definition":{"$type":"RegexToken","regex":"/\\\\([\\\\w-:]+\\\\)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARCH_TITLE","definition":{"$type":"RegexToken","regex":"/\\\\[[\\\\w ]+\\\\]/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_GROUP","definition":{"$type":"RegexToken","regex":"/\\\\{group\\\\}/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ARROW_INTO","definition":{"$type":"RegexToken","regex":"/<|>/"},"fragment":false,"hidden":false},{"$type":"ParserRule","name":"TitleAndAccessibilities","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@21"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"EOL","fragment":true,"dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false}],"definesHiddenTokens":false,"hiddenTokens":[],"interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"types":[],"usedGrammars":[]}'))),"ArchitectureGrammar"),R=s((()=>p??(p=(0,r.y0)('{"$type":"Grammar","isDeclared":true,"name":"GitGraph","interfaces":[{"$type":"Interface","name":"Common","attributes":[{"$type":"TypeAttribute","name":"accDescr","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"accTitle","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}},{"$type":"TypeAttribute","name":"title","isOptional":true,"type":{"$type":"SimpleType","primitiveType":"string"}}],"superTypes":[]}],"rules":[{"$type":"ParserRule","name":"TitleAndAccessibilities","fragment":true,"definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Assignment","feature":"accDescr","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@3"},"arguments":[]}},{"$type":"Assignment","feature":"accTitle","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@4"},"arguments":[]}},{"$type":"Assignment","feature":"title","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@5"},"arguments":[]}}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}],"cardinality":"+"},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"EOL","fragment":true,"dataType":"string","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"+"},{"$type":"EndOfFile"}]},"definesHiddenTokens":false,"entry":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"NEWLINE","definition":{"$type":"RegexToken","regex":"/\\\\r?\\\\n/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_DESCR","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accDescr(?:[\\\\t ]*:([^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)|\\\\s*{([^}]*)})/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ACC_TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*accTitle[\\\\t ]*:(?:[^\\\\n\\\\r]*?(?=%%)|[^\\\\n\\\\r]*)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"TITLE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*title(?:[\\\\t ][^\\\\n\\\\r]*?(?=%%)|[\\\\t ][^\\\\n\\\\r]*|)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","hidden":true,"name":"WHITESPACE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]+/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"YAML","definition":{"$type":"RegexToken","regex":"/---[\\\\t ]*\\\\r?\\\\n(?:[\\\\S\\\\s]*?\\\\r?\\\\n)?---(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"DIRECTIVE","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%{[\\\\S\\\\s]*?}%%(?:\\\\r?\\\\n|(?!\\\\S))/"},"fragment":false},{"$type":"TerminalRule","hidden":true,"name":"SINGLE_LINE_COMMENT","definition":{"$type":"RegexToken","regex":"/[\\\\t ]*%%[^\\\\n\\\\r]*/"},"fragment":false},{"$type":"ParserRule","name":"GitGraph","entry":true,"definition":{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"Keyword","value":":"}]},{"$type":"Keyword","value":"gitGraph:"},{"$type":"Group","elements":[{"$type":"Keyword","value":"gitGraph"},{"$type":"RuleCall","rule":{"$ref":"#/rules@12"},"arguments":[]},{"$type":"Keyword","value":":"}]}]},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Group","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[],"cardinality":"*"},{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@0"},"arguments":[]},{"$type":"Assignment","feature":"statements","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@11"},"arguments":[]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@2"},"arguments":[]}],"cardinality":"*"}]}]},"definesHiddenTokens":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Statement","definition":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@13"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@14"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@15"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@16"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@17"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Direction","definition":{"$type":"Assignment","feature":"dir","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"LR"},{"$type":"Keyword","value":"TB"},{"$type":"Keyword","value":"BT"}]}},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Commit","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"commit"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"msg:","cardinality":"?"},{"$type":"Assignment","feature":"message","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Branch","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"branch"},{"$type":"Assignment","feature":"name","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"Group","elements":[{"$type":"Keyword","value":"order:"},{"$type":"Assignment","feature":"order","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@18"},"arguments":[]}}],"cardinality":"?"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Merge","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"merge"},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"type:"},{"$type":"Assignment","feature":"type","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"NORMAL"},{"$type":"Keyword","value":"REVERSE"},{"$type":"Keyword","value":"HIGHLIGHT"}]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"Checkout","definition":{"$type":"Group","elements":[{"$type":"Alternatives","elements":[{"$type":"Keyword","value":"checkout"},{"$type":"Keyword","value":"switch"}]},{"$type":"Assignment","feature":"branch","operator":"=","terminal":{"$type":"Alternatives","elements":[{"$type":"RuleCall","rule":{"$ref":"#/rules@19"},"arguments":[]},{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}]}},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"ParserRule","name":"CherryPicking","definition":{"$type":"Group","elements":[{"$type":"Keyword","value":"cherry-pick"},{"$type":"Alternatives","elements":[{"$type":"Group","elements":[{"$type":"Keyword","value":"id:"},{"$type":"Assignment","feature":"id","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"tag:"},{"$type":"Assignment","feature":"tags","operator":"+=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]},{"$type":"Group","elements":[{"$type":"Keyword","value":"parent:"},{"$type":"Assignment","feature":"parent","operator":"=","terminal":{"$type":"RuleCall","rule":{"$ref":"#/rules@20"},"arguments":[]}}]}],"cardinality":"*"},{"$type":"RuleCall","rule":{"$ref":"#/rules@1"},"arguments":[]}]},"definesHiddenTokens":false,"entry":false,"fragment":false,"hiddenTokens":[],"parameters":[],"wildcard":false},{"$type":"TerminalRule","name":"INT","type":{"$type":"ReturnType","name":"number"},"definition":{"$type":"RegexToken","regex":"/[0-9]+(?=\\\\s)/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"ID","type":{"$type":"ReturnType","name":"string"},"definition":{"$type":"RegexToken","regex":"/\\\\w([-\\\\./\\\\w]*[-\\\\w])?/"},"fragment":false,"hidden":false},{"$type":"TerminalRule","name":"STRING","definition":{"$type":"RegexToken","regex":"/\\"[^\\"]*\\"|\'[^\']*\'/"},"fragment":false,"hidden":false}],"definesHiddenTokens":false,"hiddenTokens":[],"imports":[],"types":[],"usedGrammars":[]}'))),"GitGraphGrammar"),E={languageId:"info",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1},k={languageId:"packet",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1},x={languageId:"pie",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1},I={languageId:"architecture",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1},S={languageId:"gitGraph",fileExtensions:[".mmd",".mermaid"],caseInsensitive:!1},N={AstReflection:s((()=>new m),"AstReflection")},C={Grammar:s((()=>y()),"Grammar"),LanguageMetaData:s((()=>E),"LanguageMetaData"),parser:{}},$={Grammar:s((()=>A()),"Grammar"),LanguageMetaData:s((()=>k),"LanguageMetaData"),parser:{}},w={Grammar:s((()=>T()),"Grammar"),LanguageMetaData:s((()=>x),"LanguageMetaData"),parser:{}},L={Grammar:s((()=>v()),"Grammar"),LanguageMetaData:s((()=>I),"LanguageMetaData"),parser:{}},O={Grammar:s((()=>R()),"Grammar"),LanguageMetaData:s((()=>S),"LanguageMetaData"),parser:{}},b={ACC_DESCR:/accDescr(?:[\t ]*:([^\n\r]*)|\s*{([^}]*)})/,ACC_TITLE:/accTitle[\t ]*:([^\n\r]*)/,TITLE:/title([\t ][^\n\r]*|)/},_=class extends r.dM{static{s(this,"AbstractMermaidValueConverter")}runConverter(e,t,n){let r=this.runCommonConverter(e,t,n);return void 0===r&&(r=this.runCustomConverter(e,t,n)),void 0===r?super.runConverter(e,t,n):r}runCommonConverter(e,t,n){const r=b[e.name];if(void 0===r)return;const i=r.exec(t);return null!==i?void 0!==i[1]?i[1].trim().replace(/[\t ]{2,}/gm," "):void 0!==i[2]?i[2].replace(/^\s*/gm,"").replace(/\s+$/gm,"").replace(/[\t ]{2,}/gm," ").replace(/[\n\r]{2,}/gm,"\n"):void 0:void 0}},P=class extends _{static{s(this,"CommonValueConverter")}runCustomConverter(e,t,n){}},M=class extends r.QU{static{s(this,"AbstractMermaidTokenBuilder")}constructor(e){super(),this.keywords=new Set(e)}buildKeywordTokens(e,t,n){const r=super.buildKeywordTokens(e,t,n);return r.forEach((e=>{this.keywords.has(e.name)&&void 0!==e.PATTERN&&(e.PATTERN=new RegExp(e.PATTERN.toString()+"(?:(?=%%)|(?!\\S))"))})),r}};(class extends M{static{s(this,"CommonTokenBuilder")}})},78731:(e,t,n)=>{n.d(t,{qg:()=>o});n(82785),n(97021),n(71609),n(88685),n(49936);var r=n(19369),i={},s={info:(0,r.K2)((async()=>{const{createInfoServices:e}=await n.e(890).then(n.bind(n,10890)),t=e().Info.parser.LangiumParser;i.info=t}),"info"),packet:(0,r.K2)((async()=>{const{createPacketServices:e}=await n.e(6452).then(n.bind(n,6452)),t=e().Packet.parser.LangiumParser;i.packet=t}),"packet"),pie:(0,r.K2)((async()=>{const{createPieServices:e}=await n.e(7723).then(n.bind(n,57723)),t=e().Pie.parser.LangiumParser;i.pie=t}),"pie"),architecture:(0,r.K2)((async()=>{const{createArchitectureServices:e}=await n.e(9720).then(n.bind(n,39720)),t=e().Architecture.parser.LangiumParser;i.architecture=t}),"architecture"),gitGraph:(0,r.K2)((async()=>{const{createGitGraphServices:e}=await n.e(2387).then(n.bind(n,82387)),t=e().GitGraph.parser.LangiumParser;i.gitGraph=t}),"gitGraph")};async function o(e,t){const n=s[e];if(!n)throw new Error(`Unknown diagram type: ${e}`);i[e]||await n();const r=i[e].parse(t);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new a(r);return r.value}(0,r.K2)(o,"parse");var a=class extends Error{constructor(e){super(`Parsing failed: ${e.lexerErrors.map((e=>e.message)).join("\n")} ${e.parserErrors.map((e=>e.message)).join("\n")}`),this.result=e}static{(0,r.K2)(this,"MermaidParseError")}}},33394:(e,t,n)=>{function r(e){return"object"==typeof e&&null!==e&&"string"==typeof e.$type}function i(e){return"object"==typeof e&&null!==e&&"string"==typeof e.$refText}function s(e){return"object"==typeof e&&null!==e&&r(e.container)&&i(e.reference)&&"string"==typeof e.message}n.d(t,{kD:()=>o,QU:()=>nl,dM:()=>rl,DD:()=>Bu,tG:()=>bu,uM:()=>_u,WQ:()=>Pu,y0:()=>Hu});class o{constructor(){this.subtypes={},this.allSubtypes={}}isInstance(e,t){return r(e)&&this.isSubtype(e.$type,t)}isSubtype(e,t){if(e===t)return!0;let n=this.subtypes[e];n||(n=this.subtypes[e]={});const r=n[t];if(void 0!==r)return r;{const r=this.computeIsSubtype(e,t);return n[t]=r,r}}getAllSubTypes(e){const t=this.allSubtypes[e];if(t)return t;{const t=this.getAllTypes(),n=[];for(const r of t)this.isSubtype(r,e)&&n.push(r);return this.allSubtypes[e]=n,n}}}function a(e){return"object"==typeof e&&null!==e&&Array.isArray(e.content)}function c(e){return"object"==typeof e&&null!==e&&"object"==typeof e.tokenType}function l(e){return a(e)&&"string"==typeof e.fullText}class u{constructor(e,t){this.startFn=e,this.nextFn=t}iterator(){const e={state:this.startFn(),next:()=>this.nextFn(e.state),[Symbol.iterator]:()=>e};return e}[Symbol.iterator](){return this.iterator()}isEmpty(){const e=this.iterator();return Boolean(e.next().done)}count(){const e=this.iterator();let t=0,n=e.next();for(;!n.done;)t++,n=e.next();return t}toArray(){const e=[],t=this.iterator();let n;do{n=t.next(),void 0!==n.value&&e.push(n.value)}while(!n.done);return e}toSet(){return new Set(this)}toMap(e,t){const n=this.map((n=>[e?e(n):n,t?t(n):n]));return new Map(n)}toString(){return this.join()}concat(e){const t=e[Symbol.iterator]();return new u((()=>({first:this.startFn(),firstDone:!1})),(e=>{let n;if(!e.firstDone){do{if(n=this.nextFn(e.first),!n.done)return n}while(!n.done);e.firstDone=!0}do{if(n=t.next(),!n.done)return n}while(!n.done);return p}))}join(e=","){const t=this.iterator();let n,r="",i=!1;do{n=t.next(),n.done||(i&&(r+=e),r+=d(n.value)),i=!0}while(!n.done);return r}indexOf(e,t=0){const n=this.iterator();let r=0,i=n.next();for(;!i.done;){if(r>=t&&i.value===e)return r;i=n.next(),r++}return-1}every(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(!e(n.value))return!1;n=t.next()}return!0}some(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(e(n.value))return!0;n=t.next()}return!1}forEach(e){const t=this.iterator();let n=0,r=t.next();for(;!r.done;)e(r.value,n),r=t.next(),n++}map(e){return new u(this.startFn,(t=>{const{done:n,value:r}=this.nextFn(t);return n?p:{done:!1,value:e(r)}}))}filter(e){return new u(this.startFn,(t=>{let n;do{if(n=this.nextFn(t),!n.done&&e(n.value))return n}while(!n.done);return p}))}nonNullable(){return this.filter((e=>null!=e))}reduce(e,t){const n=this.iterator();let r=t,i=n.next();for(;!i.done;)r=void 0===r?i.value:e(r,i.value),i=n.next();return r}reduceRight(e,t){return this.recursiveReduce(this.iterator(),e,t)}recursiveReduce(e,t,n){const r=e.next();if(r.done)return n;const i=this.recursiveReduce(e,t,n);return void 0===i?r.value:t(i,r.value)}find(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(e(n.value))return n.value;n=t.next()}}findIndex(e){const t=this.iterator();let n=0,r=t.next();for(;!r.done;){if(e(r.value))return n;r=t.next(),n++}return-1}includes(e){const t=this.iterator();let n=t.next();for(;!n.done;){if(n.value===e)return!0;n=t.next()}return!1}flatMap(e){return new u((()=>({this:this.startFn()})),(t=>{do{if(t.iterator){const e=t.iterator.next();if(!e.done)return e;t.iterator=void 0}const{done:n,value:r}=this.nextFn(t.this);if(!n){const n=e(r);if(!h(n))return{done:!1,value:n};t.iterator=n[Symbol.iterator]()}}while(t.iterator);return p}))}flat(e){if(void 0===e&&(e=1),e<=0)return this;const t=e>1?this.flat(e-1):this;return new u((()=>({this:t.startFn()})),(e=>{do{if(e.iterator){const t=e.iterator.next();if(!t.done)return t;e.iterator=void 0}const{done:n,value:r}=t.nextFn(e.this);if(!n){if(!h(r))return{done:!1,value:r};e.iterator=r[Symbol.iterator]()}}while(e.iterator);return p}))}head(){const e=this.iterator().next();if(!e.done)return e.value}tail(e=1){return new u((()=>{const t=this.startFn();for(let n=0;n<e;n++){if(this.nextFn(t).done)return t}return t}),this.nextFn)}limit(e){return new u((()=>({size:0,state:this.startFn()})),(t=>(t.size++,t.size>e?p:this.nextFn(t.state))))}distinct(e){const t=new Set;return this.filter((n=>{const r=e?e(n):n;return!t.has(r)&&(t.add(r),!0)}))}exclude(e,t){const n=new Set;for(const r of e){const e=t?t(r):r;n.add(e)}return this.filter((e=>{const r=t?t(e):e;return!n.has(r)}))}}function d(e){return"string"==typeof e?e:void 0===e?"undefined":"function"==typeof e.toString?e.toString():Object.prototype.toString.call(e)}function h(e){return!!e&&"function"==typeof e[Symbol.iterator]}const f=new u((()=>{}),(()=>p)),p=Object.freeze({done:!0,value:void 0});function m(...e){if(1===e.length){const t=e[0];if(t instanceof u)return t;if(h(t))return new u((()=>t[Symbol.iterator]()),(e=>e.next()));if("number"==typeof t.length)return new u((()=>({index:0})),(e=>e.index<t.length?{done:!1,value:t[e.index++]}:p))}return e.length>1?new u((()=>({collIndex:0,arrIndex:0})),(t=>{do{if(t.iterator){const e=t.iterator.next();if(!e.done)return e;t.iterator=void 0}if(t.array){if(t.arrIndex<t.array.length)return{done:!1,value:t.array[t.arrIndex++]};t.array=void 0,t.arrIndex=0}if(t.collIndex<e.length){const n=e[t.collIndex++];h(n)?t.iterator=n[Symbol.iterator]():n&&"number"==typeof n.length&&(t.array=n)}}while(t.iterator||t.array||t.collIndex<e.length);return p})):f}class g extends u{constructor(e,t,n){super((()=>({iterators:(null==n?void 0:n.includeRoot)?[[e][Symbol.iterator]()]:[t(e)[Symbol.iterator]()],pruned:!1})),(e=>{for(e.pruned&&(e.iterators.pop(),e.pruned=!1);e.iterators.length>0;){const n=e.iterators[e.iterators.length-1].next();if(!n.done)return e.iterators.push(t(n.value)[Symbol.iterator]()),n;e.iterators.pop()}return p}))}iterator(){const e={state:this.startFn(),next:()=>this.nextFn(e.state),prune:()=>{e.state.pruned=!0},[Symbol.iterator]:()=>e};return e}}var y,A;function T(e){return new g(e,(e=>a(e)?e.content:[]),{includeRoot:!0})}function v(e){return{start:{character:e.startColumn-1,line:e.startLine-1},end:{character:e.endColumn,line:e.endLine-1}}}function R(e){if(!e)return;const{offset:t,end:n,range:r}=e;return{range:r,offset:t,end:n,length:n-t}}function E(e,t){const n=function(e,t){if(e.end.line<t.start.line||e.end.line===t.start.line&&e.end.character<e.start.character)return A.Before;if(e.start.line>t.end.line||e.start.line===t.end.line&&e.start.character>t.end.character)return A.After;const n=e.start.line>t.start.line||e.start.line===t.start.line&&e.start.character>=t.start.character,r=e.end.line<t.end.line||e.end.line===t.end.line&&e.end.character<=t.end.character;return n&&r?A.Inside:n?A.OverlapBack:A.OverlapFront}(e,t);return n>A.After}!function(e){e.sum=function(e){return e.reduce(((e,t)=>e+t),0)},e.product=function(e){return e.reduce(((e,t)=>e*t),0)},e.min=function(e){return e.reduce(((e,t)=>Math.min(e,t)))},e.max=function(e){return e.reduce(((e,t)=>Math.max(e,t)))}}(y||(y={})),function(e){e[e.Before=0]="Before",e[e.After=1]="After",e[e.OverlapFront=2]="OverlapFront",e[e.OverlapBack=3]="OverlapBack",e[e.Inside=4]="Inside"}(A||(A={}));const k=/^[\w\p{L}]$/u;function x(e,t){if(e){const n=function(e,t=!0){for(;e.container;){const n=e.container;let r=n.content.indexOf(e);for(;r>0;){r--;const e=n.content[r];if(t||!e.hidden)return e}e=n}return}(e,!0);if(n&&I(n,t))return n;if(l(e)){for(let n=e.content.findIndex((e=>!e.hidden))-1;n>=0;n--){const r=e.content[n];if(I(r,t))return r}}}}function I(e,t){return c(e)&&t.includes(e.tokenType.name)}class S extends Error{constructor(e,t){super(e?`${t} at ${e.range.start.line}:${e.range.start.character}`:t)}}function N(e){throw new Error("Error! The input value was not handled.")}const C="AbstractRule";const $="AbstractType";const w="Condition";const L="TypeDefinition";const O="ValueLiteral";const b="AbstractElement";const _="ArrayLiteral";const P="ArrayType";const M="BooleanLiteral";const D="Conjunction";const U="Disjunction";const F="Grammar";const G="InferredType";function K(e){return Oe.isInstance(e,G)}const B="Interface";function j(e){return Oe.isInstance(e,B)}const V="Negation";const H="NumberLiteral";const W="Parameter";const z="ParameterReference";const Y="ParserRule";function X(e){return Oe.isInstance(e,Y)}const q="ReferenceType";const Q="ReturnType";const J="SimpleType";const Z="StringLiteral";const ee="TerminalRule";function te(e){return Oe.isInstance(e,ee)}const ne="Type";function re(e){return Oe.isInstance(e,ne)}const ie="UnionType";const se="Action";function oe(e){return Oe.isInstance(e,se)}const ae="Alternatives";function ce(e){return Oe.isInstance(e,ae)}const le="Assignment";function ue(e){return Oe.isInstance(e,le)}const de="CharacterRange";const he="CrossReference";function fe(e){return Oe.isInstance(e,he)}const pe="EndOfFile";const me="Group";function ge(e){return Oe.isInstance(e,me)}const ye="Keyword";function Ae(e){return Oe.isInstance(e,ye)}const Te="NegatedToken";const ve="RegexToken";const Re="RuleCall";function Ee(e){return Oe.isInstance(e,Re)}const ke="TerminalAlternatives";const xe="TerminalGroup";const Ie="TerminalRuleCall";function Se(e){return Oe.isInstance(e,Ie)}const Ne="UnorderedGroup";function Ce(e){return Oe.isInstance(e,Ne)}const $e="UntilToken";const we="Wildcard";class Le extends o{getAllTypes(){return["AbstractElement","AbstractRule","AbstractType","Action","Alternatives","ArrayLiteral","ArrayType","Assignment","BooleanLiteral","CharacterRange","Condition","Conjunction","CrossReference","Disjunction","EndOfFile","Grammar","GrammarImport","Group","InferredType","Interface","Keyword","NamedArgument","NegatedToken","Negation","NumberLiteral","Parameter","ParameterReference","ParserRule","ReferenceType","RegexToken","ReturnType","RuleCall","SimpleType","StringLiteral","TerminalAlternatives","TerminalGroup","TerminalRule","TerminalRuleCall","Type","TypeAttribute","TypeDefinition","UnionType","UnorderedGroup","UntilToken","ValueLiteral","Wildcard"]}computeIsSubtype(e,t){switch(e){case se:case ae:case le:case de:case he:case pe:case me:case ye:case Te:case ve:case Re:case ke:case xe:case Ie:case Ne:case $e:case we:return this.isSubtype(b,t);case _:case H:case Z:return this.isSubtype(O,t);case P:case q:case J:case ie:return this.isSubtype(L,t);case M:return this.isSubtype(w,t)||this.isSubtype(O,t);case D:case U:case V:case z:return this.isSubtype(w,t);case G:case B:case ne:return this.isSubtype($,t);case Y:return this.isSubtype(C,t)||this.isSubtype($,t);case ee:return this.isSubtype(C,t);default:return!1}}getReferenceType(e){const t=`${e.container.$type}:${e.property}`;switch(t){case"Action:type":case"CrossReference:type":case"Interface:superTypes":case"ParserRule:returnType":case"SimpleType:typeRef":return $;case"Grammar:hiddenTokens":case"ParserRule:hiddenTokens":case"RuleCall:rule":return C;case"Grammar:usedGrammars":return F;case"NamedArgument:parameter":case"ParameterReference:parameter":return W;case"TerminalRuleCall:rule":return ee;default:throw new Error(`${t} is not a valid reference id.`)}}getTypeMetaData(e){switch(e){case"AbstractElement":return{name:"AbstractElement",properties:[{name:"cardinality"},{name:"lookahead"}]};case"ArrayLiteral":return{name:"ArrayLiteral",properties:[{name:"elements",defaultValue:[]}]};case"ArrayType":return{name:"ArrayType",properties:[{name:"elementType"}]};case"BooleanLiteral":return{name:"BooleanLiteral",properties:[{name:"true",defaultValue:!1}]};case"Conjunction":return{name:"Conjunction",properties:[{name:"left"},{name:"right"}]};case"Disjunction":return{name:"Disjunction",properties:[{name:"left"},{name:"right"}]};case"Grammar":return{name:"Grammar",properties:[{name:"definesHiddenTokens",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"imports",defaultValue:[]},{name:"interfaces",defaultValue:[]},{name:"isDeclared",defaultValue:!1},{name:"name"},{name:"rules",defaultValue:[]},{name:"types",defaultValue:[]},{name:"usedGrammars",defaultValue:[]}]};case"GrammarImport":return{name:"GrammarImport",properties:[{name:"path"}]};case"InferredType":return{name:"InferredType",properties:[{name:"name"}]};case"Interface":return{name:"Interface",properties:[{name:"attributes",defaultValue:[]},{name:"name"},{name:"superTypes",defaultValue:[]}]};case"NamedArgument":return{name:"NamedArgument",properties:[{name:"calledByName",defaultValue:!1},{name:"parameter"},{name:"value"}]};case"Negation":return{name:"Negation",properties:[{name:"value"}]};case"NumberLiteral":return{name:"NumberLiteral",properties:[{name:"value"}]};case"Parameter":return{name:"Parameter",properties:[{name:"name"}]};case"ParameterReference":return{name:"ParameterReference",properties:[{name:"parameter"}]};case"ParserRule":return{name:"ParserRule",properties:[{name:"dataType"},{name:"definesHiddenTokens",defaultValue:!1},{name:"definition"},{name:"entry",defaultValue:!1},{name:"fragment",defaultValue:!1},{name:"hiddenTokens",defaultValue:[]},{name:"inferredType"},{name:"name"},{name:"parameters",defaultValue:[]},{name:"returnType"},{name:"wildcard",defaultValue:!1}]};case"ReferenceType":return{name:"ReferenceType",properties:[{name:"referenceType"}]};case"ReturnType":return{name:"ReturnType",properties:[{name:"name"}]};case"SimpleType":return{name:"SimpleType",properties:[{name:"primitiveType"},{name:"stringType"},{name:"typeRef"}]};case"StringLiteral":return{name:"StringLiteral",properties:[{name:"value"}]};case"TerminalRule":return{name:"TerminalRule",properties:[{name:"definition"},{name:"fragment",defaultValue:!1},{name:"hidden",defaultValue:!1},{name:"name"},{name:"type"}]};case"Type":return{name:"Type",properties:[{name:"name"},{name:"type"}]};case"TypeAttribute":return{name:"TypeAttribute",properties:[{name:"defaultValue"},{name:"isOptional",defaultValue:!1},{name:"name"},{name:"type"}]};case"UnionType":return{name:"UnionType",properties:[{name:"types",defaultValue:[]}]};case"Action":return{name:"Action",properties:[{name:"cardinality"},{name:"feature"},{name:"inferredType"},{name:"lookahead"},{name:"operator"},{name:"type"}]};case"Alternatives":return{name:"Alternatives",properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case"Assignment":return{name:"Assignment",properties:[{name:"cardinality"},{name:"feature"},{name:"lookahead"},{name:"operator"},{name:"terminal"}]};case"CharacterRange":return{name:"CharacterRange",properties:[{name:"cardinality"},{name:"left"},{name:"lookahead"},{name:"right"}]};case"CrossReference":return{name:"CrossReference",properties:[{name:"cardinality"},{name:"deprecatedSyntax",defaultValue:!1},{name:"lookahead"},{name:"terminal"},{name:"type"}]};case"EndOfFile":return{name:"EndOfFile",properties:[{name:"cardinality"},{name:"lookahead"}]};case"Group":return{name:"Group",properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"guardCondition"},{name:"lookahead"}]};case"Keyword":return{name:"Keyword",properties:[{name:"cardinality"},{name:"lookahead"},{name:"value"}]};case"NegatedToken":return{name:"NegatedToken",properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case"RegexToken":return{name:"RegexToken",properties:[{name:"cardinality"},{name:"lookahead"},{name:"regex"}]};case"RuleCall":return{name:"RuleCall",properties:[{name:"arguments",defaultValue:[]},{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case"TerminalAlternatives":return{name:"TerminalAlternatives",properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case"TerminalGroup":return{name:"TerminalGroup",properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case"TerminalRuleCall":return{name:"TerminalRuleCall",properties:[{name:"cardinality"},{name:"lookahead"},{name:"rule"}]};case"UnorderedGroup":return{name:"UnorderedGroup",properties:[{name:"cardinality"},{name:"elements",defaultValue:[]},{name:"lookahead"}]};case"UntilToken":return{name:"UntilToken",properties:[{name:"cardinality"},{name:"lookahead"},{name:"terminal"}]};case"Wildcard":return{name:"Wildcard",properties:[{name:"cardinality"},{name:"lookahead"}]};default:return{name:e,properties:[]}}}}const Oe=new Le;function be(e){for(const[t,n]of Object.entries(e))t.startsWith("$")||(Array.isArray(n)?n.forEach(((n,i)=>{r(n)&&(n.$container=e,n.$containerProperty=t,n.$containerIndex=i)})):r(n)&&(n.$container=e,n.$containerProperty=t))}function _e(e,t){let n=e;for(;n;){if(t(n))return n;n=n.$container}}function Pe(e){const t=function(e){for(;e.$container;)e=e.$container;return e}(e),n=t.$document;if(!n)throw new Error("AST node has no document.");return n}function Me(e,t){if(!e)throw new Error("Node must be an AstNode.");const n=null==t?void 0:t.range;return new u((()=>({keys:Object.keys(e),keyIndex:0,arrayIndex:0})),(t=>{for(;t.keyIndex<t.keys.length;){const i=t.keys[t.keyIndex];if(!i.startsWith("$")){const s=e[i];if(r(s)){if(t.keyIndex++,Fe(s,n))return{done:!1,value:s}}else if(Array.isArray(s)){for(;t.arrayIndex<s.length;){const e=s[t.arrayIndex++];if(r(e)&&Fe(e,n))return{done:!1,value:e}}t.arrayIndex=0}}t.keyIndex++}return p}))}function De(e,t){if(!e)throw new Error("Root node must be an AstNode.");return new g(e,(e=>Me(e,t)))}function Ue(e,t){if(!e)throw new Error("Root node must be an AstNode.");return(null==t?void 0:t.range)&&!Fe(e,t.range)?new g(e,(()=>[])):new g(e,(e=>Me(e,t)),{includeRoot:!0})}function Fe(e,t){var n;if(!t)return!0;const r=null===(n=e.$cstNode)||void 0===n?void 0:n.range;return!!r&&E(r,t)}function Ge(e){return new u((()=>({keys:Object.keys(e),keyIndex:0,arrayIndex:0})),(t=>{for(;t.keyIndex<t.keys.length;){const n=t.keys[t.keyIndex];if(!n.startsWith("$")){const r=e[n];if(i(r))return t.keyIndex++,{done:!1,value:{reference:r,container:e,property:n}};if(Array.isArray(r)){for(;t.arrayIndex<r.length;){const s=t.arrayIndex++,o=r[s];if(i(o))return{done:!1,value:{reference:o,container:e,property:n,index:s}}}t.arrayIndex=0}}t.keyIndex++}return p}))}function Ke(e){return Array.isArray(e)?[...e.map(Ke)]:e}function Be(e){return e.charCodeAt(0)}function je(e,t){Array.isArray(e)?e.forEach((function(e){t.push(e)})):t.push(e)}function Ve(e,t){if(!0===e[t])throw"duplicate flag "+t;e[t];e[t]=!0}function He(e){if(void 0===e)throw Error("Internal Error - Should never get here!");return!0}function We(){throw Error("Internal Error - Should never get here!")}function ze(e){return"Character"===e.type}const Ye=[];for(let Wu=Be("0");Wu<=Be("9");Wu++)Ye.push(Wu);const Xe=[Be("_")].concat(Ye);for(let Wu=Be("a");Wu<=Be("z");Wu++)Xe.push(Wu);for(let Wu=Be("A");Wu<=Be("Z");Wu++)Xe.push(Wu);const qe=[Be(" "),Be("\f"),Be("\n"),Be("\r"),Be("\t"),Be("\v"),Be("\t"),Be("\xa0"),Be("\u1680"),Be("\u2000"),Be("\u2001"),Be("\u2002"),Be("\u2003"),Be("\u2004"),Be("\u2005"),Be("\u2006"),Be("\u2007"),Be("\u2008"),Be("\u2009"),Be("\u200a"),Be("\u2028"),Be("\u2029"),Be("\u202f"),Be("\u205f"),Be("\u3000"),Be("\ufeff")],Qe=/[0-9a-fA-F]/,Je=/[0-9]/,Ze=/[1-9]/;class et{constructor(){this.idx=0,this.input="",this.groupIdx=0}saveState(){return{idx:this.idx,input:this.input,groupIdx:this.groupIdx}}restoreState(e){this.idx=e.idx,this.input=e.input,this.groupIdx=e.groupIdx}pattern(e){this.idx=0,this.input=e,this.groupIdx=0,this.consumeChar("/");const t=this.disjunction();this.consumeChar("/");const n={type:"Flags",loc:{begin:this.idx,end:e.length},global:!1,ignoreCase:!1,multiLine:!1,unicode:!1,sticky:!1};for(;this.isRegExpFlag();)switch(this.popChar()){case"g":Ve(n,"global");break;case"i":Ve(n,"ignoreCase");break;case"m":Ve(n,"multiLine");break;case"u":Ve(n,"unicode");break;case"y":Ve(n,"sticky")}if(this.idx!==this.input.length)throw Error("Redundant input: "+this.input.substring(this.idx));return{type:"Pattern",flags:n,value:t,loc:this.loc(0)}}disjunction(){const e=[],t=this.idx;for(e.push(this.alternative());"|"===this.peekChar();)this.consumeChar("|"),e.push(this.alternative());return{type:"Disjunction",value:e,loc:this.loc(t)}}alternative(){const e=[],t=this.idx;for(;this.isTerm();)e.push(this.term());return{type:"Alternative",value:e,loc:this.loc(t)}}term(){return this.isAssertion()?this.assertion():this.atom()}assertion(){const e=this.idx;switch(this.popChar()){case"^":return{type:"StartAnchor",loc:this.loc(e)};case"$":return{type:"EndAnchor",loc:this.loc(e)};case"\\":switch(this.popChar()){case"b":return{type:"WordBoundary",loc:this.loc(e)};case"B":return{type:"NonWordBoundary",loc:this.loc(e)}}throw Error("Invalid Assertion Escape");case"(":let t;switch(this.consumeChar("?"),this.popChar()){case"=":t="Lookahead";break;case"!":t="NegativeLookahead"}He(t);const n=this.disjunction();return this.consumeChar(")"),{type:t,value:n,loc:this.loc(e)}}return We()}quantifier(e=!1){let t;const n=this.idx;switch(this.popChar()){case"*":t={atLeast:0,atMost:1/0};break;case"+":t={atLeast:1,atMost:1/0};break;case"?":t={atLeast:0,atMost:1};break;case"{":const n=this.integerIncludingZero();switch(this.popChar()){case"}":t={atLeast:n,atMost:n};break;case",":let e;this.isDigit()?(e=this.integerIncludingZero(),t={atLeast:n,atMost:e}):t={atLeast:n,atMost:1/0},this.consumeChar("}")}if(!0===e&&void 0===t)return;He(t)}if(!0!==e||void 0!==t)return He(t)?("?"===this.peekChar(0)?(this.consumeChar("?"),t.greedy=!1):t.greedy=!0,t.type="Quantifier",t.loc=this.loc(n),t):void 0}atom(){let e;const t=this.idx;switch(this.peekChar()){case".":e=this.dotAll();break;case"\\":e=this.atomEscape();break;case"[":e=this.characterClass();break;case"(":e=this.group()}return void 0===e&&this.isPatternCharacter()&&(e=this.patternCharacter()),He(e)?(e.loc=this.loc(t),this.isQuantifier()&&(e.quantifier=this.quantifier()),e):We()}dotAll(){return this.consumeChar("."),{type:"Set",complement:!0,value:[Be("\n"),Be("\r"),Be("\u2028"),Be("\u2029")]}}atomEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"1":case"2":case"3":case"4":case"5":case"6":case"7":case"8":case"9":return this.decimalEscapeAtom();case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}decimalEscapeAtom(){return{type:"GroupBackReference",value:this.positiveInteger()}}characterClassEscape(){let e,t=!1;switch(this.popChar()){case"d":e=Ye;break;case"D":e=Ye,t=!0;break;case"s":e=qe;break;case"S":e=qe,t=!0;break;case"w":e=Xe;break;case"W":e=Xe,t=!0}return He(e)?{type:"Set",value:e,complement:t}:We()}controlEscapeAtom(){let e;switch(this.popChar()){case"f":e=Be("\f");break;case"n":e=Be("\n");break;case"r":e=Be("\r");break;case"t":e=Be("\t");break;case"v":e=Be("\v")}return He(e)?{type:"Character",value:e}:We()}controlLetterEscapeAtom(){this.consumeChar("c");const e=this.popChar();if(!1===/[a-zA-Z]/.test(e))throw Error("Invalid ");return{type:"Character",value:e.toUpperCase().charCodeAt(0)-64}}nulCharacterAtom(){return this.consumeChar("0"),{type:"Character",value:Be("\0")}}hexEscapeSequenceAtom(){return this.consumeChar("x"),this.parseHexDigits(2)}regExpUnicodeEscapeSequenceAtom(){return this.consumeChar("u"),this.parseHexDigits(4)}identityEscapeAtom(){return{type:"Character",value:Be(this.popChar())}}classPatternCharacterAtom(){switch(this.peekChar()){case"\n":case"\r":case"\u2028":case"\u2029":case"\\":case"]":throw Error("TBD");default:return{type:"Character",value:Be(this.popChar())}}}characterClass(){const e=[];let t=!1;for(this.consumeChar("["),"^"===this.peekChar(0)&&(this.consumeChar("^"),t=!0);this.isClassAtom();){const t=this.classAtom();t.type;if(ze(t)&&this.isRangeDash()){this.consumeChar("-");const n=this.classAtom();n.type;if(ze(n)){if(n.value<t.value)throw Error("Range out of order in character class");e.push({from:t.value,to:n.value})}else je(t.value,e),e.push(Be("-")),je(n.value,e)}else je(t.value,e)}return this.consumeChar("]"),{type:"Set",complement:t,value:e}}classAtom(){switch(this.peekChar()){case"]":case"\n":case"\r":case"\u2028":case"\u2029":throw Error("TBD");case"\\":return this.classEscape();default:return this.classPatternCharacterAtom()}}classEscape(){switch(this.consumeChar("\\"),this.peekChar()){case"b":return this.consumeChar("b"),{type:"Character",value:Be("\b")};case"d":case"D":case"s":case"S":case"w":case"W":return this.characterClassEscape();case"f":case"n":case"r":case"t":case"v":return this.controlEscapeAtom();case"c":return this.controlLetterEscapeAtom();case"0":return this.nulCharacterAtom();case"x":return this.hexEscapeSequenceAtom();case"u":return this.regExpUnicodeEscapeSequenceAtom();default:return this.identityEscapeAtom()}}group(){let e=!0;if(this.consumeChar("("),"?"===this.peekChar(0))this.consumeChar("?"),this.consumeChar(":"),e=!1;else this.groupIdx++;const t=this.disjunction();this.consumeChar(")");const n={type:"Group",capturing:e,value:t};return e&&(n.idx=this.groupIdx),n}positiveInteger(){let e=this.popChar();if(!1===Ze.test(e))throw Error("Expecting a positive integer");for(;Je.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}integerIncludingZero(){let e=this.popChar();if(!1===Je.test(e))throw Error("Expecting an integer");for(;Je.test(this.peekChar(0));)e+=this.popChar();return parseInt(e,10)}patternCharacter(){const e=this.popChar();switch(e){case"\n":case"\r":case"\u2028":case"\u2029":case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":throw Error("TBD");default:return{type:"Character",value:Be(e)}}}isRegExpFlag(){switch(this.peekChar(0)){case"g":case"i":case"m":case"u":case"y":return!0;default:return!1}}isRangeDash(){return"-"===this.peekChar()&&this.isClassAtom(1)}isDigit(){return Je.test(this.peekChar(0))}isClassAtom(e=0){switch(this.peekChar(e)){case"]":case"\n":case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}isTerm(){return this.isAtom()||this.isAssertion()}isAtom(){if(this.isPatternCharacter())return!0;switch(this.peekChar(0)){case".":case"\\":case"[":case"(":return!0;default:return!1}}isAssertion(){switch(this.peekChar(0)){case"^":case"$":return!0;case"\\":switch(this.peekChar(1)){case"b":case"B":return!0;default:return!1}case"(":return"?"===this.peekChar(1)&&("="===this.peekChar(2)||"!"===this.peekChar(2));default:return!1}}isQuantifier(){const e=this.saveState();try{return void 0!==this.quantifier(!0)}catch(t){return!1}finally{this.restoreState(e)}}isPatternCharacter(){switch(this.peekChar()){case"^":case"$":case"\\":case".":case"*":case"+":case"?":case"(":case")":case"[":case"|":case"/":case"\n":case"\r":case"\u2028":case"\u2029":return!1;default:return!0}}parseHexDigits(e){let t="";for(let n=0;n<e;n++){const e=this.popChar();if(!1===Qe.test(e))throw Error("Expecting a HexDecimal digits");t+=e}return{type:"Character",value:parseInt(t,16)}}peekChar(e=0){return this.input[this.idx+e]}popChar(){const e=this.peekChar(0);return this.consumeChar(void 0),e}consumeChar(e){if(void 0!==e&&this.input[this.idx]!==e)throw Error("Expected: '"+e+"' but found: '"+this.input[this.idx]+"' at offset: "+this.idx);if(this.idx>=this.input.length)throw Error("Unexpected end of input");this.idx++}loc(e){return{begin:e,end:this.idx}}}class tt{visitChildren(e){for(const t in e){const n=e[t];e.hasOwnProperty(t)&&(void 0!==n.type?this.visit(n):Array.isArray(n)&&n.forEach((e=>{this.visit(e)}),this))}}visit(e){switch(e.type){case"Pattern":this.visitPattern(e);break;case"Flags":this.visitFlags(e);break;case"Disjunction":this.visitDisjunction(e);break;case"Alternative":this.visitAlternative(e);break;case"StartAnchor":this.visitStartAnchor(e);break;case"EndAnchor":this.visitEndAnchor(e);break;case"WordBoundary":this.visitWordBoundary(e);break;case"NonWordBoundary":this.visitNonWordBoundary(e);break;case"Lookahead":this.visitLookahead(e);break;case"NegativeLookahead":this.visitNegativeLookahead(e);break;case"Character":this.visitCharacter(e);break;case"Set":this.visitSet(e);break;case"Group":this.visitGroup(e);break;case"GroupBackReference":this.visitGroupBackReference(e);break;case"Quantifier":this.visitQuantifier(e)}this.visitChildren(e)}visitPattern(e){}visitFlags(e){}visitDisjunction(e){}visitAlternative(e){}visitStartAnchor(e){}visitEndAnchor(e){}visitWordBoundary(e){}visitNonWordBoundary(e){}visitLookahead(e){}visitNegativeLookahead(e){}visitCharacter(e){}visitSet(e){}visitGroup(e){}visitGroupBackReference(e){}visitQuantifier(e){}}const nt=/\r?\n/gm,rt=new et;const it=new class extends tt{constructor(){super(...arguments),this.isStarting=!0,this.endRegexpStack=[],this.multiline=!1}get endRegex(){return this.endRegexpStack.join("")}reset(e){this.multiline=!1,this.regex=e,this.startRegexp="",this.isStarting=!0,this.endRegexpStack=[]}visitGroup(e){e.quantifier&&(this.isStarting=!1,this.endRegexpStack=[])}visitCharacter(e){const t=String.fromCharCode(e.value);if(this.multiline||"\n"!==t||(this.multiline=!0),e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{const e=at(t);this.endRegexpStack.push(e),this.isStarting&&(this.startRegexp+=e)}}visitSet(e){if(!this.multiline){const t=this.regex.substring(e.loc.begin,e.loc.end),n=new RegExp(t);this.multiline=Boolean("\n".match(n))}if(e.quantifier)this.isStarting=!1,this.endRegexpStack=[];else{const t=this.regex.substring(e.loc.begin,e.loc.end);this.endRegexpStack.push(t),this.isStarting&&(this.startRegexp+=t)}}visitChildren(e){if("Group"===e.type){if(e.quantifier)return}super.visitChildren(e)}};function st(e){try{return"string"==typeof e&&(e=new RegExp(e)),e=e.toString(),it.reset(e),it.visit(rt.pattern(e)),it.multiline}catch(t){return!1}}function ot(e){return("string"==typeof e?new RegExp(e):e).test(" ")}function at(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function ct(e,t){const n=function(e){"string"==typeof e&&(e=new RegExp(e));const t=e,n=e.source;let r=0;function i(){let e,s="";function o(e){s+=n.substr(r,e),r+=e}function a(e){s+="(?:"+n.substr(r,e)+"|$)",r+=e}for(;r<n.length;)switch(n[r]){case"\\":switch(n[r+1]){case"c":a(3);break;case"x":a(4);break;case"u":t.unicode?"{"===n[r+2]?a(n.indexOf("}",r)-r+1):a(6):a(2);break;case"p":case"P":t.unicode?a(n.indexOf("}",r)-r+1):a(2);break;case"k":a(n.indexOf(">",r)-r+1);break;default:a(2)}break;case"[":e=/\[(?:\\.|.)*?\]/g,e.lastIndex=r,e=e.exec(n)||[],a(e[0].length);break;case"|":case"^":case"$":case"*":case"+":case"?":o(1);break;case"{":e=/\{\d+,?\d*\}/g,e.lastIndex=r,e=e.exec(n),e?o(e[0].length):a(1);break;case"(":if("?"===n[r+1])switch(n[r+2]){case":":s+="(?:",r+=3,s+=i()+"|$)";break;case"=":s+="(?=",r+=3,s+=i()+")";break;case"!":e=r,r+=3,i(),s+=n.substr(e,r-e);break;case"<":switch(n[r+3]){case"=":case"!":e=r,r+=4,i(),s+=n.substr(e,r-e);break;default:o(n.indexOf(">",r)-r+1),s+=i()+"|$)"}}else o(1),s+=i()+"|$)";break;case")":return++r,s;default:a(1)}return s}return new RegExp(i(),e.flags)}(e),r=t.match(n);return!!r&&r[0].length>0}function lt(e,t){const n=new Set,r=function(e){return e.rules.find((e=>X(e)&&e.entry))}(e);if(!r)return new Set(e.rules);const i=[r].concat(function(e){return e.rules.filter((e=>te(e)&&e.hidden))}(e));for(const o of i)ut(o,n,t);const s=new Set;for(const o of e.rules)(n.has(o.name)||te(o)&&o.hidden)&&s.add(o);return s}function ut(e,t,n){t.add(e.name),De(e).forEach((e=>{if(Ee(e)||n&&Se(e)){const r=e.rule.ref;r&&!t.has(r.name)&&ut(r,t,n)}}))}function dt(e,t,n){if(!e||!t)return;const r=ht(e,t,e.astNode,!0);return 0!==r.length?r[n=void 0!==n?Math.max(0,Math.min(n,r.length-1)):0]:void 0}function ht(e,t,n,r){if(!r){const n=_e(e.grammarSource,ue);if(n&&n.feature===t)return[e]}return a(e)&&e.astNode===n?e.content.flatMap((e=>ht(e,t,n,!1))):[]}function ft(e,t,n){if(e.astNode!==n)return[];if(Ae(e.grammarSource)&&e.grammarSource.value===t)return[e];const r=T(e).iterator();let i;const s=[];do{if(i=r.next(),!i.done){const e=i.value;e.astNode===n?Ae(e.grammarSource)&&e.grammarSource.value===t&&s.push(e):r.prune()}}while(!i.done);return s}function pt(e){let t=e;return K(t)&&(oe(t.$container)?t=t.$container.$container:X(t.$container)?t=t.$container:N(t.$container)),mt(e,t,new Map)}function mt(e,t,n){var r,i;function s(t,r){let i;return _e(t,ue)||(i=mt(r,r,n)),n.set(e,i),i}if(n.has(e))return n.get(e);n.set(e,void 0);for(const o of De(t)){if(ue(o)&&"name"===o.feature.toLowerCase())return n.set(e,o),o;if(Ee(o)&&X(o.rule.ref))return s(o,o.rule.ref);if(i=o,Oe.isInstance(i,J)&&(null===(r=o.typeRef)||void 0===r?void 0:r.ref))return s(o,o.typeRef.ref)}}function gt(e){return yt(e,new Set)}function yt(e,t){if(t.has(e))return!0;t.add(e);for(const n of De(e))if(Ee(n)){if(!n.rule.ref)return!1;if(X(n.rule.ref)&&!yt(n.rule.ref,t))return!1}else{if(ue(n))return!1;if(oe(n))return!1}return Boolean(e.definition)}function At(e){if(e.inferredType)return e.inferredType.name;if(e.dataType)return e.dataType;if(e.returnType){const t=e.returnType.ref;if(t){if(X(t))return t.name;if(j(t)||re(t))return t.name}}}function Tt(e){var t,n;if(X(e))return gt(e)?e.name:null!==(t=At(e))&&void 0!==t?t:e.name;if(j(e)||re(e)||(n=e,Oe.isInstance(n,Q)))return e.name;if(oe(e)){const t=function(e){var t;if(e.inferredType)return e.inferredType.name;if(null===(t=e.type)||void 0===t?void 0:t.ref)return Tt(e.type.ref);return}(e);if(t)return t}else if(K(e))return e.name;throw new Error("Cannot get name of Unknown Type")}function vt(e){const t={s:!1,i:!1,u:!1},n=Et(e.definition,t),r=Object.entries(t).filter((([,e])=>e)).map((([e])=>e)).join("");return new RegExp(n,r)}const Rt=/[\s\S]/.source;function Et(e,t){if(s=e,Oe.isInstance(s,ke))return xt((i=e).elements.map((e=>Et(e))).join("|"),{cardinality:i.cardinality,lookahead:i.lookahead});if(function(e){return Oe.isInstance(e,xe)}(e))return xt((r=e).elements.map((e=>Et(e))).join(""),{cardinality:r.cardinality,lookahead:r.lookahead});if(function(e){return Oe.isInstance(e,de)}(e))return function(e){if(e.right)return xt(`[${kt(e.left)}-${kt(e.right)}]`,{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1});return xt(kt(e.left),{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1})}(e);if(Se(e)){const t=e.rule.ref;if(!t)throw new Error("Missing rule reference.");return xt(Et(t.definition),{cardinality:e.cardinality,lookahead:e.lookahead})}if(function(e){return Oe.isInstance(e,Te)}(e))return function(e){return xt(`(?!${Et(e.terminal)})${Rt}*?`,{cardinality:e.cardinality,lookahead:e.lookahead})}(e);if(function(e){return Oe.isInstance(e,$e)}(e))return xt(`${Rt}*?${Et((n=e).terminal)}`,{cardinality:n.cardinality,lookahead:n.lookahead});if(function(e){return Oe.isInstance(e,ve)}(e)){const n=e.regex.lastIndexOf("/"),r=e.regex.substring(1,n),i=e.regex.substring(n+1);return t&&(t.i=i.includes("i"),t.s=i.includes("s"),t.u=i.includes("u")),xt(r,{cardinality:e.cardinality,lookahead:e.lookahead,wrap:!1})}if(function(e){return Oe.isInstance(e,we)}(e))return xt(Rt,{cardinality:e.cardinality,lookahead:e.lookahead});throw new Error(`Invalid terminal element: ${null==e?void 0:e.$type}`);var n,r,i,s}function kt(e){return at(e.value)}function xt(e,t){var n;return(!1!==t.wrap||t.lookahead)&&(e=`(${null!==(n=t.lookahead)&&void 0!==n?n:""}${e})`),t.cardinality?`${e}${t.cardinality}`:e}var It=n(8058),St=n(38207),Nt=n(66401),Ct=n(74722),$t=n(48585),wt=n(50053);function Lt(e){function t(){}t.prototype=e;const n=new t;function r(){return typeof n.bar}return r(),r(),e}const Ot=function(e,t,n){var r=-1,i=e.length;t<0&&(t=-t>i?0:i+t),(n=n>i?i:n)<0&&(n+=i),i=t>n?0:n-t>>>0,t>>>=0;for(var s=Array(i);++r<i;)s[r]=e[r+t];return s};var bt=n(18593);const _t=function(e,t,n){var r=null==e?0:e.length;return r?(t=n||void 0===t?1:(0,bt.A)(t),Ot(e,t<0?0:t,r)):[]};var Pt=n(9703),Mt=n(52851),Dt=n(22031),Ut=n(3767),Ft=n(38446),Gt=n(97271),Kt=n(27422),Bt=Object.prototype.hasOwnProperty;const jt=(0,Ut.A)((function(e,t){if((0,Gt.A)(t)||(0,Ft.A)(t))(0,Dt.A)(t,(0,Kt.A)(t),e);else for(var n in t)Bt.call(t,n)&&(0,Mt.A)(e,n,t[n])}));var Vt=n(45572),Ht=n(23958),Wt=n(99354),zt=n(83973);const Yt=function(e,t){if(null==e)return{};var n=(0,Vt.A)((0,zt.A)(e),(function(e){return[e]}));return t=(0,Ht.A)(t),(0,Wt.A)(e,n,(function(e,n){return t(e,n[0])}))};var Xt=n(88496),qt=n(53098);const Qt=function(e){return(0,qt.A)(e)&&"[object RegExp]"==(0,Xt.A)(e)};var Jt=n(52789),Zt=n(64841),en=Zt.A&&Zt.A.isRegExp;const tn=en?(0,Jt.A)(en):Qt;function nn(e){return t=e,(0,Pt.A)(t.LABEL)&&""!==t.LABEL?e.LABEL:e.name;var t}class rn{get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){this._definition=e}accept(e){e.visit(this),(0,It.A)(this.definition,(t=>{t.accept(e)}))}}class sn extends rn{constructor(e){super([]),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}set definition(e){}get definition(){return void 0!==this.referencedRule?this.referencedRule.definition:[]}accept(e){e.visit(this)}}class on extends rn{constructor(e){super(e.definition),this.orgText="",jt(this,Yt(e,(e=>void 0!==e)))}}class an extends rn{constructor(e){super(e.definition),this.ignoreAmbiguities=!1,jt(this,Yt(e,(e=>void 0!==e)))}}class cn extends rn{constructor(e){super(e.definition),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}}class ln extends rn{constructor(e){super(e.definition),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}}class un extends rn{constructor(e){super(e.definition),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}}class dn extends rn{constructor(e){super(e.definition),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}}class hn extends rn{constructor(e){super(e.definition),this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}}class fn extends rn{get definition(){return this._definition}set definition(e){this._definition=e}constructor(e){super(e.definition),this.idx=1,this.ignoreAmbiguities=!1,this.hasPredicates=!1,jt(this,Yt(e,(e=>void 0!==e)))}}class pn{constructor(e){this.idx=1,jt(this,Yt(e,(e=>void 0!==e)))}accept(e){e.visit(this)}}function mn(e){function t(e){return(0,Ct.A)(e,mn)}if(e instanceof sn){const t={type:"NonTerminal",name:e.nonTerminalName,idx:e.idx};return(0,Pt.A)(e.label)&&(t.label=e.label),t}if(e instanceof an)return{type:"Alternative",definition:t(e.definition)};if(e instanceof cn)return{type:"Option",idx:e.idx,definition:t(e.definition)};if(e instanceof ln)return{type:"RepetitionMandatory",idx:e.idx,definition:t(e.definition)};if(e instanceof un)return{type:"RepetitionMandatoryWithSeparator",idx:e.idx,separator:mn(new pn({terminalType:e.separator})),definition:t(e.definition)};if(e instanceof hn)return{type:"RepetitionWithSeparator",idx:e.idx,separator:mn(new pn({terminalType:e.separator})),definition:t(e.definition)};if(e instanceof dn)return{type:"Repetition",idx:e.idx,definition:t(e.definition)};if(e instanceof fn)return{type:"Alternation",idx:e.idx,definition:t(e.definition)};if(e instanceof pn){const t={type:"Terminal",name:e.terminalType.name,label:nn(e.terminalType),idx:e.idx};(0,Pt.A)(e.label)&&(t.terminalLabel=e.label);const n=e.terminalType.PATTERN;return e.terminalType.PATTERN&&(t.pattern=tn(n)?n.source:n),t}if(e instanceof on)return{type:"Rule",name:e.name,orgText:e.orgText,definition:t(e.definition)};throw Error("non exhaustive match")}class gn{visit(e){const t=e;switch(t.constructor){case sn:return this.visitNonTerminal(t);case an:return this.visitAlternative(t);case cn:return this.visitOption(t);case ln:return this.visitRepetitionMandatory(t);case un:return this.visitRepetitionMandatoryWithSeparator(t);case hn:return this.visitRepetitionWithSeparator(t);case dn:return this.visitRepetition(t);case fn:return this.visitAlternation(t);case pn:return this.visitTerminal(t);case on:return this.visitRule(t);default:throw Error("non exhaustive match")}}visitNonTerminal(e){}visitAlternative(e){}visitOption(e){}visitRepetition(e){}visitRepetitionMandatory(e){}visitRepetitionMandatoryWithSeparator(e){}visitRepetitionWithSeparator(e){}visitAlternation(e){}visitTerminal(e){}visitRule(e){}}var yn=n(63736),An=n(6240);const Tn=function(e,t){var n;return(0,An.A)(e,(function(e,r,i){return!(n=t(e,r,i))})),!!n};var vn=n(92049),Rn=n(6832);const En=function(e,t,n){var r=(0,vn.A)(e)?yn.A:Tn;return n&&(0,Rn.A)(e,t,n)&&(t=void 0),r(e,(0,Ht.A)(t,3))};var kn=n(60818),xn=Math.max;const In=function(e,t,n,r){e=(0,Ft.A)(e)?e:(0,St.A)(e),n=n&&!r?(0,bt.A)(n):0;var i=e.length;return n<0&&(n=xn(i+n,0)),(0,Pt.A)(e)?n<=i&&e.indexOf(t,n)>-1:!!i&&(0,kn.A)(e,t,n)>-1};const Sn=function(e,t){for(var n=-1,r=null==e?0:e.length;++n<r;)if(!t(e[n],n,e))return!1;return!0};const Nn=function(e,t){var n=!0;return(0,An.A)(e,(function(e,r,i){return n=!!t(e,r,i)})),n};const Cn=function(e,t,n){var r=(0,vn.A)(e)?Sn:Nn;return n&&(0,Rn.A)(e,t,n)&&(t=void 0),r(e,(0,Ht.A)(t,3))};function $n(e,t=[]){return!!(e instanceof cn||e instanceof dn||e instanceof hn)||(e instanceof fn?En(e.definition,(e=>$n(e,t))):!(e instanceof sn&&In(t,e))&&(e instanceof rn&&(e instanceof sn&&t.push(e),Cn(e.definition,(e=>$n(e,t))))))}function wn(e){if(e instanceof sn)return"SUBRULE";if(e instanceof cn)return"OPTION";if(e instanceof fn)return"OR";if(e instanceof ln)return"AT_LEAST_ONE";if(e instanceof un)return"AT_LEAST_ONE_SEP";if(e instanceof hn)return"MANY_SEP";if(e instanceof dn)return"MANY";if(e instanceof pn)return"CONSUME";throw Error("non exhaustive match")}class Ln{walk(e,t=[]){(0,It.A)(e.definition,((n,r)=>{const i=_t(e.definition,r+1);if(n instanceof sn)this.walkProdRef(n,i,t);else if(n instanceof pn)this.walkTerminal(n,i,t);else if(n instanceof an)this.walkFlat(n,i,t);else if(n instanceof cn)this.walkOption(n,i,t);else if(n instanceof ln)this.walkAtLeastOne(n,i,t);else if(n instanceof un)this.walkAtLeastOneSep(n,i,t);else if(n instanceof hn)this.walkManySep(n,i,t);else if(n instanceof dn)this.walkMany(n,i,t);else{if(!(n instanceof fn))throw Error("non exhaustive match");this.walkOr(n,i,t)}}))}walkTerminal(e,t,n){}walkProdRef(e,t,n){}walkFlat(e,t,n){const r=t.concat(n);this.walk(e,r)}walkOption(e,t,n){const r=t.concat(n);this.walk(e,r)}walkAtLeastOne(e,t,n){const r=[new cn({definition:e.definition})].concat(t,n);this.walk(e,r)}walkAtLeastOneSep(e,t,n){const r=On(e,t,n);this.walk(e,r)}walkMany(e,t,n){const r=[new cn({definition:e.definition})].concat(t,n);this.walk(e,r)}walkManySep(e,t,n){const r=On(e,t,n);this.walk(e,r)}walkOr(e,t,n){const r=t.concat(n);(0,It.A)(e.definition,(e=>{const t=new an({definition:[e]});this.walk(t,r)}))}}function On(e,t,n){return[new cn({definition:[new pn({terminalType:e.separator})].concat(e.definition)})].concat(t,n)}var bn=n(99902);const _n=function(e){return e&&e.length?(0,bn.A)(e):[]};var Pn=n(34098);function Mn(e){if(e instanceof sn)return Mn(e.referencedRule);if(e instanceof pn)return[e.terminalType];if(function(e){return e instanceof an||e instanceof cn||e instanceof dn||e instanceof ln||e instanceof un||e instanceof hn||e instanceof pn||e instanceof on}(e))return function(e){let t=[];const n=e.definition;let r,i=0,s=n.length>i,o=!0;for(;s&&o;)r=n[i],o=$n(r),t=t.concat(Mn(r)),i+=1,s=n.length>i;return _n(t)}(e);if(function(e){return e instanceof fn}(e))return function(e){const t=(0,Ct.A)(e.definition,(e=>Mn(e)));return _n((0,Pn.A)(t))}(e);throw Error("non exhaustive match")}const Dn="_~IN~_";class Un extends Ln{constructor(e){super(),this.topProd=e,this.follows={}}startWalking(){return this.walk(this.topProd),this.follows}walkTerminal(e,t,n){}walkProdRef(e,t,n){const r=(i=e.referencedRule,s=e.idx,i.name+s+Dn+this.topProd.name);var i,s;const o=t.concat(n),a=Mn(new an({definition:o}));this.follows[r]=a}}var Fn=n(69592),Gn=n(23068),Kn=n(2634),Bn=n(51790);const jn=function(e){if("function"!=typeof e)throw new TypeError("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!e.call(this);case 1:return!e.call(this,t[0]);case 2:return!e.call(this,t[0],t[1]);case 3:return!e.call(this,t[0],t[1],t[2])}return!e.apply(this,t)}};const Vn=function(e,t){return((0,vn.A)(e)?Kn.A:Bn.A)(e,jn((0,Ht.A)(t,3)))};var Hn=n(89610),Wn=Math.max;const zn=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;var i=null==n?0:(0,bt.A)(n);return i<0&&(i=Wn(r+i,0)),(0,kn.A)(e,t,i)};var Yn=n(89463),Xn=n(94092),qn=n(62062),Qn=n(83149),Jn=n(87809),Zn=n(64099);const er=function(e,t,n,r){var i=-1,s=Qn.A,o=!0,a=e.length,c=[],l=t.length;if(!a)return c;n&&(t=(0,Vt.A)(t,(0,Jt.A)(n))),r?(s=Jn.A,o=!1):t.length>=200&&(s=Zn.A,o=!1,t=new qn.A(t));e:for(;++i<a;){var u=e[i],d=null==n?u:n(u);if(u=r||0!==u?u:0,o&&d==d){for(var h=l;h--;)if(t[h]===d)continue e;c.push(u)}else s(t,d,r)||c.push(u)}return c};var tr=n(13588),nr=n(24326),rr=n(53533);const ir=(0,nr.A)((function(e,t){return(0,rr.A)(e)?er(e,(0,tr.A)(t,1,rr.A,!0)):[]}));const sr=function(e){for(var t=-1,n=null==e?0:e.length,r=0,i=[];++t<n;){var s=e[t];s&&(i[r++]=s)}return i};const or=function(e){return e&&e.length?e[0]:void 0};var ar=n(16145);function cr(e){console&&console.error&&console.error(`Error: ${e}`)}function lr(e){console&&console.warn&&console.warn(`Warning: ${e}`)}let ur={};const dr=new et;function hr(e){const t=e.toString();if(ur.hasOwnProperty(t))return ur[t];{const e=dr.pattern(t);return ur[t]=e,e}}const fr="Complement Sets are not supported for first char optimization",pr='Unable to use "first char" lexer optimizations:\n';function mr(e,t=!1){try{const t=hr(e);return gr(t.value,{},t.flags.ignoreCase)}catch(n){if(n.message===fr)t&&lr(`${pr}\tUnable to optimize: < ${e.toString()} >\n\tComplement Sets cannot be automatically optimized.\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#COMPLEMENT for details.`);else{let n="";t&&(n="\n\tThis will disable the lexer's first char optimizations.\n\tSee: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#REGEXP_PARSING for details."),cr(`${pr}\n\tFailed parsing: < ${e.toString()} >\n\tUsing the @chevrotain/regexp-to-ast library\n\tPlease open an issue at: https://github.com/chevrotain/chevrotain/issues`+n)}}return[]}function gr(e,t,n){switch(e.type){case"Disjunction":for(let i=0;i<e.value.length;i++)gr(e.value[i],t,n);break;case"Alternative":const r=e.value;for(let e=0;e<r.length;e++){const i=r[e];switch(i.type){case"EndAnchor":case"GroupBackReference":case"Lookahead":case"NegativeLookahead":case"StartAnchor":case"WordBoundary":case"NonWordBoundary":continue}const s=i;switch(s.type){case"Character":yr(s.value,t,n);break;case"Set":if(!0===s.complement)throw Error(fr);(0,It.A)(s.value,(e=>{if("number"==typeof e)yr(e,t,n);else{const r=e;if(!0===n)for(let e=r.from;e<=r.to;e++)yr(e,t,n);else{for(let e=r.from;e<=r.to&&e<Fr;e++)yr(e,t,n);if(r.to>=Fr){const e=r.from>=Fr?r.from:Fr,n=r.to,i=Kr(e),s=Kr(n);for(let r=i;r<=s;r++)t[r]=r}}}}));break;case"Group":gr(s.value,t,n);break;default:throw Error("Non Exhaustive Match")}const o=void 0!==s.quantifier&&0===s.quantifier.atLeast;if("Group"===s.type&&!1===Tr(s)||"Group"!==s.type&&!1===o)break}break;default:throw Error("non exhaustive match!")}return(0,St.A)(t)}function yr(e,t,n){const r=Kr(e);t[r]=r,!0===n&&function(e,t){const n=String.fromCharCode(e),r=n.toUpperCase();if(r!==n){const e=Kr(r.charCodeAt(0));t[e]=e}else{const e=n.toLowerCase();if(e!==n){const n=Kr(e.charCodeAt(0));t[n]=n}}}(e,t)}function Ar(e,t){return(0,ar.A)(e.value,(e=>{if("number"==typeof e)return In(t,e);{const n=e;return void 0!==(0,ar.A)(t,(e=>n.from<=e&&e<=n.to))}}))}function Tr(e){const t=e.quantifier;return!(!t||0!==t.atLeast)||!!e.value&&((0,vn.A)(e.value)?Cn(e.value,Tr):Tr(e.value))}class vr extends tt{constructor(e){super(),this.targetCharCodes=e,this.found=!1}visitChildren(e){if(!0!==this.found){switch(e.type){case"Lookahead":return void this.visitLookahead(e);case"NegativeLookahead":return void this.visitNegativeLookahead(e)}super.visitChildren(e)}}visitCharacter(e){In(this.targetCharCodes,e.value)&&(this.found=!0)}visitSet(e){e.complement?void 0===Ar(e,this.targetCharCodes)&&(this.found=!0):void 0!==Ar(e,this.targetCharCodes)&&(this.found=!0)}}function Rr(e,t){if(t instanceof RegExp){const n=hr(t),r=new vr(e);return r.visit(n),r.found}return void 0!==(0,ar.A)(t,(t=>In(e,t.charCodeAt(0))))}const Er="PATTERN",kr="defaultMode",xr="modes";let Ir="boolean"==typeof new RegExp("(?:)").sticky;function Sr(e,t){const n=(t=(0,Gn.A)(t,{useSticky:Ir,debug:!1,safeMode:!1,positionTracking:"full",lineTerminatorCharacters:["\r","\n"],tracer:(e,t)=>t()})).tracer;let r;n("initCharCodeToOptimizedIndexMap",(()=>{!function(){if((0,Nt.A)(Gr)){Gr=new Array(65536);for(let e=0;e<65536;e++)Gr[e]=e>255?255+~~(e/255):e}}()})),n("Reject Lexer.NA",(()=>{r=Vn(e,(e=>e[Er]===ii.NA))}));let i,s,o,a,c,l,u,d,h,f,p,m=!1;n("Transform Patterns",(()=>{m=!1,i=(0,Ct.A)(r,(e=>{const n=e[Er];if(tn(n)){const e=n.source;return 1!==e.length||"^"===e||"$"===e||"."===e||n.ignoreCase?2!==e.length||"\\"!==e[0]||In(["d","D","s","S","t","r","n","t","0","c","b","B","f","v","w","W"],e[1])?t.useSticky?Lr(n):wr(n):e[1]:e}if((0,Hn.A)(n))return m=!0,{exec:n};if("object"==typeof n)return m=!0,n;if("string"==typeof n){if(1===n.length)return n;{const e=n.replace(/[\\^$.*+?()[\]{}|]/g,"\\$&"),r=new RegExp(e);return t.useSticky?Lr(r):wr(r)}}throw Error("non exhaustive match")}))})),n("misc mapping",(()=>{s=(0,Ct.A)(r,(e=>e.tokenTypeIdx)),o=(0,Ct.A)(r,(e=>{const t=e.GROUP;if(t!==ii.SKIPPED){if((0,Pt.A)(t))return t;if((0,Fn.A)(t))return!1;throw Error("non exhaustive match")}})),a=(0,Ct.A)(r,(e=>{const t=e.LONGER_ALT;if(t){return(0,vn.A)(t)?(0,Ct.A)(t,(e=>zn(r,e))):[zn(r,t)]}})),c=(0,Ct.A)(r,(e=>e.PUSH_MODE)),l=(0,Ct.A)(r,(e=>(0,$t.A)(e,"POP_MODE")))})),n("Line Terminator Handling",(()=>{const e=Dr(t.lineTerminatorCharacters);u=(0,Ct.A)(r,(e=>!1)),"onlyOffset"!==t.positionTracking&&(u=(0,Ct.A)(r,(t=>(0,$t.A)(t,"LINE_BREAKS")?!!t.LINE_BREAKS:!1===Mr(t,e)&&Rr(e,t.PATTERN))))})),n("Misc Mapping #2",(()=>{d=(0,Ct.A)(r,br),h=(0,Ct.A)(i,_r),f=(0,Yn.A)(r,((e,t)=>{const n=t.GROUP;return(0,Pt.A)(n)&&n!==ii.SKIPPED&&(e[n]=[]),e}),{}),p=(0,Ct.A)(i,((e,t)=>({pattern:i[t],longerAlt:a[t],canLineTerminator:u[t],isCustom:d[t],short:h[t],group:o[t],push:c[t],pop:l[t],tokenTypeIdx:s[t],tokenType:r[t]})))}));let g=!0,y=[];return t.safeMode||n("First Char Optimization",(()=>{y=(0,Yn.A)(r,((e,n,r)=>{if("string"==typeof n.PATTERN){const t=Kr(n.PATTERN.charCodeAt(0));Ur(e,t,p[r])}else if((0,vn.A)(n.START_CHARS_HINT)){let t;(0,It.A)(n.START_CHARS_HINT,(n=>{const i=Kr("string"==typeof n?n.charCodeAt(0):n);t!==i&&(t=i,Ur(e,i,p[r]))}))}else if(tn(n.PATTERN))if(n.PATTERN.unicode)g=!1,t.ensureOptimizations&&cr(`${pr}\tUnable to analyze < ${n.PATTERN.toString()} > pattern.\n\tThe regexp unicode flag is not currently supported by the regexp-to-ast library.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNICODE_OPTIMIZE`);else{const i=mr(n.PATTERN,t.ensureOptimizations);(0,Nt.A)(i)&&(g=!1),(0,It.A)(i,(t=>{Ur(e,t,p[r])}))}else t.ensureOptimizations&&cr(`${pr}\tTokenType: <${n.name}> is using a custom token pattern without providing <start_chars_hint> parameter.\n\tThis will disable the lexer's first char optimizations.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_OPTIMIZE`),g=!1;return e}),[])})),{emptyGroups:f,patternIdxToConfig:p,charCodeToPatternIdxToConfig:y,hasCustom:m,canBeOptimized:g}}function Nr(e,t){let n=[];const r=function(e){const t=(0,Xn.A)(e,(e=>!(0,$t.A)(e,Er))),n=(0,Ct.A)(t,(e=>({message:"Token Type: ->"+e.name+"<- missing static 'PATTERN' property",type:ni.MISSING_PATTERN,tokenTypes:[e]}))),r=ir(e,t);return{errors:n,valid:r}}(e);n=n.concat(r.errors);const i=function(e){const t=(0,Xn.A)(e,(e=>{const t=e[Er];return!(tn(t)||(0,Hn.A)(t)||(0,$t.A)(t,"exec")||(0,Pt.A)(t))})),n=(0,Ct.A)(t,(e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' can only be a RegExp, a Function matching the {CustomPatternMatcherFunc} type or an Object matching the {ICustomPattern} interface.",type:ni.INVALID_PATTERN,tokenTypes:[e]}))),r=ir(e,t);return{errors:n,valid:r}}(r.valid),s=i.valid;return n=n.concat(i.errors),n=n.concat(function(e){let t=[];const n=(0,Xn.A)(e,(e=>tn(e[Er])));return t=t.concat(function(e){class t extends tt{constructor(){super(...arguments),this.found=!1}visitEndAnchor(e){this.found=!0}}const n=(0,Xn.A)(e,(e=>{const n=e.PATTERN;try{const e=hr(n),r=new t;return r.visit(e),r.found}catch(r){return Cr.test(n.source)}})),r=(0,Ct.A)(n,(e=>({message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+e.name+"<- static 'PATTERN' cannot contain end of input anchor '$'\n\tSee chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:ni.EOI_ANCHOR_FOUND,tokenTypes:[e]})));return r}(n)),t=t.concat(function(e){class t extends tt{constructor(){super(...arguments),this.found=!1}visitStartAnchor(e){this.found=!0}}const n=(0,Xn.A)(e,(e=>{const n=e.PATTERN;try{const e=hr(n),r=new t;return r.visit(e),r.found}catch(r){return $r.test(n.source)}})),r=(0,Ct.A)(n,(e=>({message:"Unexpected RegExp Anchor Error:\n\tToken Type: ->"+e.name+"<- static 'PATTERN' cannot contain start of input anchor '^'\n\tSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#ANCHORS\tfor details.",type:ni.SOI_ANCHOR_FOUND,tokenTypes:[e]})));return r}(n)),t=t.concat(function(e){const t=(0,Xn.A)(e,(e=>{const t=e[Er];return t instanceof RegExp&&(t.multiline||t.global)})),n=(0,Ct.A)(t,(e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' may NOT contain global('g') or multiline('m')",type:ni.UNSUPPORTED_FLAGS_FOUND,tokenTypes:[e]})));return n}(n)),t=t.concat(function(e){const t=[];let n=(0,Ct.A)(e,(n=>(0,Yn.A)(e,((e,r)=>(n.PATTERN.source!==r.PATTERN.source||In(t,r)||r.PATTERN===ii.NA||(t.push(r),e.push(r)),e)),[])));n=sr(n);const r=(0,Xn.A)(n,(e=>e.length>1)),i=(0,Ct.A)(r,(e=>{const t=(0,Ct.A)(e,(e=>e.name));return{message:`The same RegExp pattern ->${or(e).PATTERN}<-has been used in all of the following Token Types: ${t.join(", ")} <-`,type:ni.DUPLICATE_PATTERNS_FOUND,tokenTypes:e}}));return i}(n)),t=t.concat(function(e){const t=(0,Xn.A)(e,(e=>e.PATTERN.test(""))),n=(0,Ct.A)(t,(e=>({message:"Token Type: ->"+e.name+"<- static 'PATTERN' must not match an empty string",type:ni.EMPTY_MATCH_PATTERN,tokenTypes:[e]})));return n}(n)),t}(s)),n=n.concat(function(e){const t=(0,Xn.A)(e,(e=>{if(!(0,$t.A)(e,"GROUP"))return!1;const t=e.GROUP;return t!==ii.SKIPPED&&t!==ii.NA&&!(0,Pt.A)(t)})),n=(0,Ct.A)(t,(e=>({message:"Token Type: ->"+e.name+"<- static 'GROUP' can only be Lexer.SKIPPED/Lexer.NA/A String",type:ni.INVALID_GROUP_TYPE_FOUND,tokenTypes:[e]})));return n}(s)),n=n.concat(function(e,t){const n=(0,Xn.A)(e,(e=>void 0!==e.PUSH_MODE&&!In(t,e.PUSH_MODE))),r=(0,Ct.A)(n,(e=>({message:`Token Type: ->${e.name}<- static 'PUSH_MODE' value cannot refer to a Lexer Mode ->${e.PUSH_MODE}<-which does not exist`,type:ni.PUSH_MODE_DOES_NOT_EXIST,tokenTypes:[e]})));return r}(s,t)),n=n.concat(function(e){const t=[],n=(0,Yn.A)(e,((e,t,n)=>{const r=t.PATTERN;return r===ii.NA||((0,Pt.A)(r)?e.push({str:r,idx:n,tokenType:t}):tn(r)&&function(e){const t=[".","\\","[","]","|","^","$","(",")","?","*","+","{"];return void 0===(0,ar.A)(t,(t=>-1!==e.source.indexOf(t)))}(r)&&e.push({str:r.source,idx:n,tokenType:t})),e}),[]);return(0,It.A)(e,((e,r)=>{(0,It.A)(n,(({str:n,idx:i,tokenType:s})=>{if(r<i&&function(e,t){if(tn(t)){const n=t.exec(e);return null!==n&&0===n.index}if((0,Hn.A)(t))return t(e,0,[],{});if((0,$t.A)(t,"exec"))return t.exec(e,0,[],{});if("string"==typeof t)return t===e;throw Error("non exhaustive match")}(n,e.PATTERN)){const n=`Token: ->${s.name}<- can never be matched.\nBecause it appears AFTER the Token Type ->${e.name}<-in the lexer's definition.\nSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#UNREACHABLE`;t.push({message:n,type:ni.UNREACHABLE_PATTERN,tokenTypes:[e,s]})}}))})),t}(s)),n}const Cr=/[^\\][$]/;const $r=/[^\\[][\^]|^\^/;function wr(e){const t=e.ignoreCase?"i":"";return new RegExp(`^(?:${e.source})`,t)}function Lr(e){const t=e.ignoreCase?"iy":"y";return new RegExp(`${e.source}`,t)}function Or(e,t,n){const r=[];let i=!1;const s=sr((0,Pn.A)((0,St.A)(e.modes))),o=Vn(s,(e=>e[Er]===ii.NA)),a=Dr(n);return t&&(0,It.A)(o,(e=>{const t=Mr(e,a);if(!1!==t){const n=function(e,t){if(t.issue===ni.IDENTIFY_TERMINATOR)return`Warning: unable to identify line terminator usage in pattern.\n\tThe problem is in the <${e.name}> Token Type\n\t Root cause: ${t.errMsg}.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#IDENTIFY_TERMINATOR`;if(t.issue===ni.CUSTOM_LINE_BREAK)return`Warning: A Custom Token Pattern should specify the <line_breaks> option.\n\tThe problem is in the <${e.name}> Token Type\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#CUSTOM_LINE_BREAK`;throw Error("non exhaustive match")}(e,t),i={message:n,type:t.issue,tokenType:e};r.push(i)}else(0,$t.A)(e,"LINE_BREAKS")?!0===e.LINE_BREAKS&&(i=!0):Rr(a,e.PATTERN)&&(i=!0)})),t&&!i&&r.push({message:"Warning: No LINE_BREAKS Found.\n\tThis Lexer has been defined to track line and column information,\n\tBut none of the Token Types can be identified as matching a line terminator.\n\tSee https://chevrotain.io/docs/guide/resolving_lexer_errors.html#LINE_BREAKS \n\tfor details.",type:ni.NO_LINE_BREAKS_FLAGS}),r}function br(e){const t=e.PATTERN;if(tn(t))return!1;if((0,Hn.A)(t))return!0;if((0,$t.A)(t,"exec"))return!0;if((0,Pt.A)(t))return!1;throw Error("non exhaustive match")}function _r(e){return!(!(0,Pt.A)(e)||1!==e.length)&&e.charCodeAt(0)}const Pr={test:function(e){const t=e.length;for(let n=this.lastIndex;n<t;n++){const t=e.charCodeAt(n);if(10===t)return this.lastIndex=n+1,!0;if(13===t)return 10===e.charCodeAt(n+1)?this.lastIndex=n+2:this.lastIndex=n+1,!0}return!1},lastIndex:0};function Mr(e,t){if((0,$t.A)(e,"LINE_BREAKS"))return!1;if(tn(e.PATTERN)){try{Rr(t,e.PATTERN)}catch(n){return{issue:ni.IDENTIFY_TERMINATOR,errMsg:n.message}}return!1}if((0,Pt.A)(e.PATTERN))return!1;if(br(e))return{issue:ni.CUSTOM_LINE_BREAK};throw Error("non exhaustive match")}function Dr(e){return(0,Ct.A)(e,(e=>(0,Pt.A)(e)?e.charCodeAt(0):e))}function Ur(e,t,n){void 0===e[t]?e[t]=[n]:e[t].push(n)}const Fr=256;let Gr=[];function Kr(e){return e<Fr?e:Gr[e]}var Br=n(29008),jr=n(42302),Vr=n(26666);function Hr(e){const t=(new Date).getTime(),n=e();return{time:(new Date).getTime()-t,value:n}}function Wr(e,t){const n=e.tokenTypeIdx;return n===t.tokenTypeIdx||!0===t.isParent&&!0===t.categoryMatchesMap[n]}function zr(e,t){return e.tokenTypeIdx===t.tokenTypeIdx}let Yr=1;const Xr={};function qr(e){const t=function(e){let t=(0,wt.A)(e),n=e,r=!0;for(;r;){n=sr((0,Pn.A)((0,Ct.A)(n,(e=>e.CATEGORIES))));const e=ir(n,t);t=t.concat(e),(0,Nt.A)(e)?r=!1:n=e}return t}(e);!function(e){(0,It.A)(e,(e=>{var t;Jr(e)||(Xr[Yr]=e,e.tokenTypeIdx=Yr++),Zr(e)&&!(0,vn.A)(e.CATEGORIES)&&(e.CATEGORIES=[e.CATEGORIES]),Zr(e)||(e.CATEGORIES=[]),t=e,(0,$t.A)(t,"categoryMatches")||(e.categoryMatches=[]),function(e){return(0,$t.A)(e,"categoryMatchesMap")}(e)||(e.categoryMatchesMap={})}))}(t),function(e){(0,It.A)(e,(e=>{Qr([],e)}))}(t),function(e){(0,It.A)(e,(e=>{e.categoryMatches=[],(0,It.A)(e.categoryMatchesMap,((t,n)=>{e.categoryMatches.push(Xr[n].tokenTypeIdx)}))}))}(t),(0,It.A)(t,(e=>{e.isParent=e.categoryMatches.length>0}))}function Qr(e,t){(0,It.A)(e,(e=>{t.categoryMatchesMap[e.tokenTypeIdx]=!0})),(0,It.A)(t.CATEGORIES,(n=>{const r=e.concat(t);In(r,n)||Qr(r,n)}))}function Jr(e){return(0,$t.A)(e,"tokenTypeIdx")}function Zr(e){return(0,$t.A)(e,"CATEGORIES")}function ei(e){return(0,$t.A)(e,"tokenTypeIdx")}const ti={buildUnableToPopLexerModeMessage:e=>`Unable to pop Lexer Mode after encountering Token ->${e.image}<- The Mode Stack is empty`,buildUnexpectedCharactersMessage:(e,t,n,r,i)=>`unexpected character: ->${e.charAt(t)}<- at offset: ${t}, skipped ${n} characters.`};var ni;!function(e){e[e.MISSING_PATTERN=0]="MISSING_PATTERN",e[e.INVALID_PATTERN=1]="INVALID_PATTERN",e[e.EOI_ANCHOR_FOUND=2]="EOI_ANCHOR_FOUND",e[e.UNSUPPORTED_FLAGS_FOUND=3]="UNSUPPORTED_FLAGS_FOUND",e[e.DUPLICATE_PATTERNS_FOUND=4]="DUPLICATE_PATTERNS_FOUND",e[e.INVALID_GROUP_TYPE_FOUND=5]="INVALID_GROUP_TYPE_FOUND",e[e.PUSH_MODE_DOES_NOT_EXIST=6]="PUSH_MODE_DOES_NOT_EXIST",e[e.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE=7]="MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE",e[e.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY=8]="MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY",e[e.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST=9]="MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST",e[e.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED=10]="LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED",e[e.SOI_ANCHOR_FOUND=11]="SOI_ANCHOR_FOUND",e[e.EMPTY_MATCH_PATTERN=12]="EMPTY_MATCH_PATTERN",e[e.NO_LINE_BREAKS_FLAGS=13]="NO_LINE_BREAKS_FLAGS",e[e.UNREACHABLE_PATTERN=14]="UNREACHABLE_PATTERN",e[e.IDENTIFY_TERMINATOR=15]="IDENTIFY_TERMINATOR",e[e.CUSTOM_LINE_BREAK=16]="CUSTOM_LINE_BREAK",e[e.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE=17]="MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE"}(ni||(ni={}));const ri={deferDefinitionErrorsHandling:!1,positionTracking:"full",lineTerminatorsPattern:/\n|\r\n?/g,lineTerminatorCharacters:["\n","\r"],ensureOptimizations:!1,safeMode:!1,errorMessageProvider:ti,traceInitPerf:!1,skipValidations:!1,recoveryEnabled:!0};Object.freeze(ri);class ii{constructor(e,t=ri){if(this.lexerDefinition=e,this.lexerDefinitionErrors=[],this.lexerDefinitionWarning=[],this.patternIdxToConfig={},this.charCodeToPatternIdxToConfig={},this.modes=[],this.emptyGroups={},this.trackStartLines=!0,this.trackEndLines=!0,this.hasCustom=!1,this.canModeBeOptimized={},this.TRACE_INIT=(e,t)=>{if(!0===this.traceInitPerf){this.traceInitIndent++;const n=new Array(this.traceInitIndent+1).join("\t");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${n}--\x3e <${e}>`);const{time:r,value:i}=Hr(t),s=r>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&s(`${n}<-- <${e}> time: ${r}ms`),this.traceInitIndent--,i}return t()},"boolean"==typeof t)throw Error("The second argument to the Lexer constructor is now an ILexerConfig Object.\na boolean 2nd argument is no longer supported");this.config=jt({},ri,t);const n=this.config.traceInitPerf;!0===n?(this.traceInitMaxIdent=1/0,this.traceInitPerf=!0):"number"==typeof n&&(this.traceInitMaxIdent=n,this.traceInitPerf=!0),this.traceInitIndent=-1,this.TRACE_INIT("Lexer Constructor",(()=>{let n,r=!0;this.TRACE_INIT("Lexer Config handling",(()=>{if(this.config.lineTerminatorsPattern===ri.lineTerminatorsPattern)this.config.lineTerminatorsPattern=Pr;else if(this.config.lineTerminatorCharacters===ri.lineTerminatorCharacters)throw Error("Error: Missing <lineTerminatorCharacters> property on the Lexer config.\n\tFor details See: https://chevrotain.io/docs/guide/resolving_lexer_errors.html#MISSING_LINE_TERM_CHARS");if(t.safeMode&&t.ensureOptimizations)throw Error('"safeMode" and "ensureOptimizations" flags are mutually exclusive.');this.trackStartLines=/full|onlyStart/i.test(this.config.positionTracking),this.trackEndLines=/full/i.test(this.config.positionTracking),(0,vn.A)(e)?n={modes:{defaultMode:(0,wt.A)(e)},defaultMode:kr}:(r=!1,n=(0,wt.A)(e))})),!1===this.config.skipValidations&&(this.TRACE_INIT("performRuntimeChecks",(()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(function(e){const t=[];return(0,$t.A)(e,kr)||t.push({message:"A MultiMode Lexer cannot be initialized without a <"+kr+"> property in its definition\n",type:ni.MULTI_MODE_LEXER_WITHOUT_DEFAULT_MODE}),(0,$t.A)(e,xr)||t.push({message:"A MultiMode Lexer cannot be initialized without a <modes> property in its definition\n",type:ni.MULTI_MODE_LEXER_WITHOUT_MODES_PROPERTY}),(0,$t.A)(e,xr)&&(0,$t.A)(e,kr)&&!(0,$t.A)(e.modes,e.defaultMode)&&t.push({message:`A MultiMode Lexer cannot be initialized with a ${kr}: <${e.defaultMode}>which does not exist\n`,type:ni.MULTI_MODE_LEXER_DEFAULT_MODE_VALUE_DOES_NOT_EXIST}),(0,$t.A)(e,xr)&&(0,It.A)(e.modes,((e,n)=>{(0,It.A)(e,((r,i)=>{if((0,Fn.A)(r))t.push({message:`A Lexer cannot be initialized using an undefined Token Type. Mode:<${n}> at index: <${i}>\n`,type:ni.LEXER_DEFINITION_CANNOT_CONTAIN_UNDEFINED});else if((0,$t.A)(r,"LONGER_ALT")){const i=(0,vn.A)(r.LONGER_ALT)?r.LONGER_ALT:[r.LONGER_ALT];(0,It.A)(i,(i=>{(0,Fn.A)(i)||In(e,i)||t.push({message:`A MultiMode Lexer cannot be initialized with a longer_alt <${i.name}> on token <${r.name}> outside of mode <${n}>\n`,type:ni.MULTI_MODE_LEXER_LONGER_ALT_NOT_IN_CURRENT_MODE})}))}}))})),t}(n,this.trackStartLines,this.config.lineTerminatorCharacters))})),this.TRACE_INIT("performWarningRuntimeChecks",(()=>{this.lexerDefinitionWarning=this.lexerDefinitionWarning.concat(Or(n,this.trackStartLines,this.config.lineTerminatorCharacters))}))),n.modes=n.modes?n.modes:{},(0,It.A)(n.modes,((e,t)=>{n.modes[t]=Vn(e,(e=>(0,Fn.A)(e)))}));const i=(0,Kt.A)(n.modes);if((0,It.A)(n.modes,((e,n)=>{this.TRACE_INIT(`Mode: <${n}> processing`,(()=>{if(this.modes.push(n),!1===this.config.skipValidations&&this.TRACE_INIT("validatePatterns",(()=>{this.lexerDefinitionErrors=this.lexerDefinitionErrors.concat(Nr(e,i))})),(0,Nt.A)(this.lexerDefinitionErrors)){let r;qr(e),this.TRACE_INIT("analyzeTokenTypes",(()=>{r=Sr(e,{lineTerminatorCharacters:this.config.lineTerminatorCharacters,positionTracking:t.positionTracking,ensureOptimizations:t.ensureOptimizations,safeMode:t.safeMode,tracer:this.TRACE_INIT})})),this.patternIdxToConfig[n]=r.patternIdxToConfig,this.charCodeToPatternIdxToConfig[n]=r.charCodeToPatternIdxToConfig,this.emptyGroups=jt({},this.emptyGroups,r.emptyGroups),this.hasCustom=r.hasCustom||this.hasCustom,this.canModeBeOptimized[n]=r.canBeOptimized}}))})),this.defaultMode=n.defaultMode,!(0,Nt.A)(this.lexerDefinitionErrors)&&!this.config.deferDefinitionErrorsHandling){const e=(0,Ct.A)(this.lexerDefinitionErrors,(e=>e.message)).join("-----------------------\n");throw new Error("Errors detected in definition of Lexer:\n"+e)}(0,It.A)(this.lexerDefinitionWarning,(e=>{lr(e.message)})),this.TRACE_INIT("Choosing sub-methods implementations",(()=>{if(Ir?(this.chopInput=Br.A,this.match=this.matchWithTest):(this.updateLastIndex=jr.A,this.match=this.matchWithExec),r&&(this.handleModes=jr.A),!1===this.trackStartLines&&(this.computeNewColumn=Br.A),!1===this.trackEndLines&&(this.updateTokenEndLineColumnLocation=jr.A),/full/i.test(this.config.positionTracking))this.createTokenInstance=this.createFullToken;else if(/onlyStart/i.test(this.config.positionTracking))this.createTokenInstance=this.createStartOnlyToken;else{if(!/onlyOffset/i.test(this.config.positionTracking))throw Error(`Invalid <positionTracking> config option: "${this.config.positionTracking}"`);this.createTokenInstance=this.createOffsetOnlyToken}this.hasCustom?(this.addToken=this.addTokenUsingPush,this.handlePayload=this.handlePayloadWithCustom):(this.addToken=this.addTokenUsingMemberAccess,this.handlePayload=this.handlePayloadNoCustom)})),this.TRACE_INIT("Failed Optimization Warnings",(()=>{const e=(0,Yn.A)(this.canModeBeOptimized,((e,t,n)=>(!1===t&&e.push(n),e)),[]);if(t.ensureOptimizations&&!(0,Nt.A)(e))throw Error(`Lexer Modes: < ${e.join(", ")} > cannot be optimized.\n\t Disable the "ensureOptimizations" lexer config flag to silently ignore this and run the lexer in an un-optimized mode.\n\t Or inspect the console log for details on how to resolve these issues.`)})),this.TRACE_INIT("clearRegExpParserCache",(()=>{ur={}})),this.TRACE_INIT("toFastProperties",(()=>{Lt(this)}))}))}tokenize(e,t=this.defaultMode){if(!(0,Nt.A)(this.lexerDefinitionErrors)){const e=(0,Ct.A)(this.lexerDefinitionErrors,(e=>e.message)).join("-----------------------\n");throw new Error("Unable to Tokenize because Errors detected in definition of Lexer:\n"+e)}return this.tokenizeInternal(e,t)}tokenizeInternal(e,t){let n,r,i,s,o,a,c,l,u,d,h,f,p,m,g;const y=e,A=y.length;let T=0,v=0;const R=this.hasCustom?0:Math.floor(e.length/10),E=new Array(R),k=[];let x=this.trackStartLines?1:void 0,I=this.trackStartLines?1:void 0;const S=function(e){const t={},n=(0,Kt.A)(e);return(0,It.A)(n,(n=>{const r=e[n];if(!(0,vn.A)(r))throw Error("non exhaustive match");t[n]=[]})),t}(this.emptyGroups),N=this.trackStartLines,C=this.config.lineTerminatorsPattern;let $=0,w=[],L=[];const O=[],b=[];let _;function P(){return w}function M(e){const t=Kr(e),n=L[t];return void 0===n?b:n}Object.freeze(b);const D=e=>{if(1===O.length&&void 0===e.tokenType.PUSH_MODE){const t=this.config.errorMessageProvider.buildUnableToPopLexerModeMessage(e);k.push({offset:e.startOffset,line:e.startLine,column:e.startColumn,length:e.image.length,message:t})}else{O.pop();const e=(0,Vr.A)(O);w=this.patternIdxToConfig[e],L=this.charCodeToPatternIdxToConfig[e],$=w.length;const t=this.canModeBeOptimized[e]&&!1===this.config.safeMode;_=L&&t?M:P}};function U(e){O.push(e),L=this.charCodeToPatternIdxToConfig[e],w=this.patternIdxToConfig[e],$=w.length,$=w.length;const t=this.canModeBeOptimized[e]&&!1===this.config.safeMode;_=L&&t?M:P}let F;U.call(this,t);const G=this.config.recoveryEnabled;for(;T<A;){a=null;const t=y.charCodeAt(T),R=_(t),L=R.length;for(n=0;n<L;n++){F=R[n];const r=F.pattern;c=null;const u=F.short;if(!1!==u?t===u&&(a=r):!0===F.isCustom?(g=r.exec(y,T,E,S),null!==g?(a=g[0],void 0!==g.payload&&(c=g.payload)):a=null):(this.updateLastIndex(r,T),a=this.match(r,e,T)),null!==a){if(o=F.longerAlt,void 0!==o){const t=o.length;for(i=0;i<t;i++){const t=w[o[i]],n=t.pattern;if(l=null,!0===t.isCustom?(g=n.exec(y,T,E,S),null!==g?(s=g[0],void 0!==g.payload&&(l=g.payload)):s=null):(this.updateLastIndex(n,T),s=this.match(n,e,T)),s&&s.length>a.length){a=s,c=l,F=t;break}}}break}}if(null!==a){if(u=a.length,d=F.group,void 0!==d&&(h=F.tokenTypeIdx,f=this.createTokenInstance(a,T,h,F.tokenType,x,I,u),this.handlePayload(f,c),!1===d?v=this.addToken(E,v,f):S[d].push(f)),e=this.chopInput(e,u),T+=u,I=this.computeNewColumn(I,u),!0===N&&!0===F.canLineTerminator){let e,t,n=0;C.lastIndex=0;do{e=C.test(a),!0===e&&(t=C.lastIndex-1,n++)}while(!0===e);0!==n&&(x+=n,I=u-t,this.updateTokenEndLineColumnLocation(f,d,t,n,x,I,u))}this.handleModes(F,D,U,f)}else{const t=T,n=x,i=I;let s=!1===G;for(;!1===s&&T<A;)for(e=this.chopInput(e,1),T++,r=0;r<$;r++){const t=w[r],n=t.pattern,i=t.short;if(!1!==i?y.charCodeAt(T)===i&&(s=!0):!0===t.isCustom?s=null!==n.exec(y,T,E,S):(this.updateLastIndex(n,T),s=null!==n.exec(e)),!0===s)break}if(p=T-t,I=this.computeNewColumn(I,p),m=this.config.errorMessageProvider.buildUnexpectedCharactersMessage(y,t,p,n,i),k.push({offset:t,line:n,column:i,length:p,message:m}),!1===G)break}}return this.hasCustom||(E.length=v),{tokens:E,groups:S,errors:k}}handleModes(e,t,n,r){if(!0===e.pop){const i=e.push;t(r),void 0!==i&&n.call(this,i)}else void 0!==e.push&&n.call(this,e.push)}chopInput(e,t){return e.substring(t)}updateLastIndex(e,t){e.lastIndex=t}updateTokenEndLineColumnLocation(e,t,n,r,i,s,o){let a,c;void 0!==t&&(a=n===o-1,c=a?-1:0,1===r&&!0===a||(e.endLine=i+c,e.endColumn=s-1-c))}computeNewColumn(e,t){return e+t}createOffsetOnlyToken(e,t,n,r){return{image:e,startOffset:t,tokenTypeIdx:n,tokenType:r}}createStartOnlyToken(e,t,n,r,i,s){return{image:e,startOffset:t,startLine:i,startColumn:s,tokenTypeIdx:n,tokenType:r}}createFullToken(e,t,n,r,i,s,o){return{image:e,startOffset:t,endOffset:t+o-1,startLine:i,endLine:i,startColumn:s,endColumn:s+o-1,tokenTypeIdx:n,tokenType:r}}addTokenUsingPush(e,t,n){return e.push(n),t}addTokenUsingMemberAccess(e,t,n){return e[t]=n,++t}handlePayloadNoCustom(e,t){}handlePayloadWithCustom(e,t){null!==t&&(e.payload=t)}matchWithTest(e,t,n){return!0===e.test(t)?t.substring(n,e.lastIndex):null}matchWithExec(e,t){const n=e.exec(t);return null!==n?n[0]:null}}function si(e){return oi(e)?e.LABEL:e.name}function oi(e){return(0,Pt.A)(e.LABEL)&&""!==e.LABEL}ii.SKIPPED="This marks a skipped Token pattern, this means each token identified by it willbe consumed and then thrown into oblivion, this can be used to for example to completely ignore whitespace.",ii.NA=/NOT_APPLICABLE/;const ai="parent",ci="categories",li="label",ui="group",di="push_mode",hi="pop_mode",fi="longer_alt",pi="line_breaks",mi="start_chars_hint";function gi(e){return function(e){const t=e.pattern,n={};n.name=e.name,(0,Fn.A)(t)||(n.PATTERN=t);if((0,$t.A)(e,ai))throw"The parent property is no longer supported.\nSee: https://github.com/chevrotain/chevrotain/issues/564#issuecomment-349062346 for details.";(0,$t.A)(e,ci)&&(n.CATEGORIES=e[ci]);qr([n]),(0,$t.A)(e,li)&&(n.LABEL=e[li]);(0,$t.A)(e,ui)&&(n.GROUP=e[ui]);(0,$t.A)(e,hi)&&(n.POP_MODE=e[hi]);(0,$t.A)(e,di)&&(n.PUSH_MODE=e[di]);(0,$t.A)(e,fi)&&(n.LONGER_ALT=e[fi]);(0,$t.A)(e,pi)&&(n.LINE_BREAKS=e[pi]);(0,$t.A)(e,mi)&&(n.START_CHARS_HINT=e[mi]);return n}(e)}const yi=gi({name:"EOF",pattern:ii.NA});function Ai(e,t,n,r,i,s,o,a){return{image:t,startOffset:n,endOffset:r,startLine:i,endLine:s,startColumn:o,endColumn:a,tokenTypeIdx:e.tokenTypeIdx,tokenType:e}}function Ti(e,t){return Wr(e,t)}qr([yi]);const vi={buildMismatchTokenMessage:({expected:e,actual:t,previous:n,ruleName:r})=>`Expecting ${oi(e)?`--\x3e ${si(e)} <--`:`token of type --\x3e ${e.name} <--`} but found --\x3e '${t.image}' <--`,buildNotAllInputParsedMessage:({firstRedundant:e,ruleName:t})=>"Redundant input, expecting EOF but found: "+e.image,buildNoViableAltMessage({expectedPathsPerAlt:e,actual:t,previous:n,customUserDescription:r,ruleName:i}){const s="Expecting: ",o="\nbut found: '"+or(t).image+"'";if(r)return s+r+o;{const t=(0,Yn.A)(e,((e,t)=>e.concat(t)),[]),n=(0,Ct.A)(t,(e=>`[${(0,Ct.A)(e,(e=>si(e))).join(", ")}]`));return s+`one of these possible Token sequences:\n${(0,Ct.A)(n,((e,t)=>` ${t+1}. ${e}`)).join("\n")}`+o}},buildEarlyExitMessage({expectedIterationPaths:e,actual:t,customUserDescription:n,ruleName:r}){const i="Expecting: ",s="\nbut found: '"+or(t).image+"'";if(n)return i+n+s;return i+`expecting at least one iteration which starts with one of these possible Token sequences::\n <${(0,Ct.A)(e,(e=>`[${(0,Ct.A)(e,(e=>si(e))).join(",")}]`)).join(" ,")}>`+s}};Object.freeze(vi);const Ri={buildRuleNotFoundError:(e,t)=>"Invalid grammar, reference to a rule which is not defined: ->"+t.nonTerminalName+"<-\ninside top level rule: ->"+e.name+"<-"},Ei={buildDuplicateFoundError(e,t){const n=e.name,r=or(t),i=r.idx,s=wn(r),o=(a=r)instanceof pn?a.terminalType.name:a instanceof sn?a.nonTerminalName:"";var a;let c=`->${s}${i>0?i:""}<- ${o?`with argument: ->${o}<-`:""}\n appears more than once (${t.length} times) in the top level rule: ->${n}<-. \n For further details see: https://chevrotain.io/docs/FAQ.html#NUMERICAL_SUFFIXES \n `;return c=c.replace(/[ \t]+/g," "),c=c.replace(/\s\s+/g,"\n"),c},buildNamespaceConflictError:e=>`Namespace conflict found in grammar.\nThe grammar has both a Terminal(Token) and a Non-Terminal(Rule) named: <${e.name}>.\nTo resolve this make sure each Terminal and Non-Terminal names are unique\nThis is easy to accomplish by using the convention that Terminal names start with an uppercase letter\nand Non-Terminal names start with a lower case letter.`,buildAlternationPrefixAmbiguityError(e){const t=(0,Ct.A)(e.prefixPath,(e=>si(e))).join(", "),n=0===e.alternation.idx?"":e.alternation.idx;return`Ambiguous alternatives: <${e.ambiguityIndices.join(" ,")}> due to common lookahead prefix\nin <OR${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\nSee: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#COMMON_PREFIX\nFor Further details.`},buildAlternationAmbiguityError(e){const t=(0,Ct.A)(e.prefixPath,(e=>si(e))).join(", "),n=0===e.alternation.idx?"":e.alternation.idx;let r=`Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(" ,")}> in <OR${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\n`;return r+="See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.",r},buildEmptyRepetitionError(e){let t=wn(e.repetition);0!==e.repetition.idx&&(t+=e.repetition.idx);return`The repetition <${t}> within Rule <${e.topLevelRule.name}> can never consume any tokens.\nThis could lead to an infinite loop.`},buildTokenNameError:e=>"deprecated",buildEmptyAlternationError:e=>`Ambiguous empty alternative: <${e.emptyChoiceIdx+1}> in <OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\nOnly the last alternative may be an empty alternative.`,buildTooManyAlternativesError:e=>`An Alternation cannot have more than 256 alternatives:\n<OR${e.alternation.idx}> inside <${e.topLevelRule.name}> Rule.\n has ${e.alternation.definition.length+1} alternatives.`,buildLeftRecursionError(e){const t=e.topLevelRule.name;return`Left Recursion found in grammar.\nrule: <${t}> can be invoked from itself (directly or indirectly)\nwithout consuming any Tokens. The grammar path that causes this is: \n ${`${t} --\x3e ${(0,Ct.A)(e.leftRecursionPath,(e=>e.name)).concat([t]).join(" --\x3e ")}`}\n To fix this refactor your grammar to remove the left recursion.\nsee: https://en.wikipedia.org/wiki/LL_parser#Left_factoring.`},buildInvalidRuleNameError:e=>"deprecated",buildDuplicateRuleNameError(e){let t;t=e.topLevelRule instanceof on?e.topLevelRule.name:e.topLevelRule;return`Duplicate definition, rule: ->${t}<- is already defined in the grammar: ->${e.grammarName}<-`}};class ki extends gn{constructor(e,t){super(),this.nameToTopRule=e,this.errMsgProvider=t,this.errors=[]}resolveRefs(){(0,It.A)((0,St.A)(this.nameToTopRule),(e=>{this.currTopLevel=e,e.accept(this)}))}visitNonTerminal(e){const t=this.nameToTopRule[e.nonTerminalName];if(t)e.referencedRule=t;else{const t=this.errMsgProvider.buildRuleNotFoundError(this.currTopLevel,e);this.errors.push({message:t,type:to.UNRESOLVED_SUBRULE_REF,ruleName:this.currTopLevel.name,unresolvedRefName:e.nonTerminalName})}}}const xi=function(e,t){return(0,tr.A)((0,Ct.A)(e,t),1)};var Ii=n(52528);const Si=function(e,t,n,r){for(var i=-1,s=null==e?0:e.length;++i<s;){var o=e[i];t(r,o,n(o),e)}return r};const Ni=function(e,t,n,r){return(0,An.A)(e,(function(e,i,s){t(r,e,n(e),s)})),r};const Ci=function(e,t){return function(n,r){var i=(0,vn.A)(n)?Si:Ni,s=t?t():{};return i(n,e,(0,Ht.A)(r,2),s)}};var $i=Object.prototype.hasOwnProperty;const wi=Ci((function(e,t,n){$i.call(e,n)?e[n].push(t):(0,Ii.A)(e,n,[t])}));const Li=function(e,t,n){var r=null==e?0:e.length;return r?(t=n||void 0===t?1:(0,bt.A)(t),Ot(e,0,(t=r-t)<0?0:t)):[]};class Oi extends Ln{constructor(e,t){super(),this.topProd=e,this.path=t,this.possibleTokTypes=[],this.nextProductionName="",this.nextProductionOccurrence=0,this.found=!1,this.isAtEndOfPath=!1}startWalking(){if(this.found=!1,this.path.ruleStack[0]!==this.topProd.name)throw Error("The path does not start with the walker's top Rule!");return this.ruleStack=(0,wt.A)(this.path.ruleStack).reverse(),this.occurrenceStack=(0,wt.A)(this.path.occurrenceStack).reverse(),this.ruleStack.pop(),this.occurrenceStack.pop(),this.updateExpectedNext(),this.walk(this.topProd),this.possibleTokTypes}walk(e,t=[]){this.found||super.walk(e,t)}walkProdRef(e,t,n){if(e.referencedRule.name===this.nextProductionName&&e.idx===this.nextProductionOccurrence){const r=t.concat(n);this.updateExpectedNext(),this.walk(e.referencedRule,r)}}updateExpectedNext(){(0,Nt.A)(this.ruleStack)?(this.nextProductionName="",this.nextProductionOccurrence=0,this.isAtEndOfPath=!0):(this.nextProductionName=this.ruleStack.pop(),this.nextProductionOccurrence=this.occurrenceStack.pop())}}class bi extends Oi{constructor(e,t){super(e,t),this.path=t,this.nextTerminalName="",this.nextTerminalOccurrence=0,this.nextTerminalName=this.path.lastTok.name,this.nextTerminalOccurrence=this.path.lastTokOccurrence}walkTerminal(e,t,n){if(this.isAtEndOfPath&&e.terminalType.name===this.nextTerminalName&&e.idx===this.nextTerminalOccurrence&&!this.found){const e=t.concat(n),r=new an({definition:e});this.possibleTokTypes=Mn(r),this.found=!0}}}class _i extends Ln{constructor(e,t){super(),this.topRule=e,this.occurrence=t,this.result={token:void 0,occurrence:void 0,isEndOfRule:void 0}}startWalking(){return this.walk(this.topRule),this.result}}class Pi extends _i{walkMany(e,t,n){if(e.idx===this.occurrence){const e=or(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof pn&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkMany(e,t,n)}}class Mi extends _i{walkManySep(e,t,n){if(e.idx===this.occurrence){const e=or(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof pn&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkManySep(e,t,n)}}class Di extends _i{walkAtLeastOne(e,t,n){if(e.idx===this.occurrence){const e=or(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof pn&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkAtLeastOne(e,t,n)}}class Ui extends _i{walkAtLeastOneSep(e,t,n){if(e.idx===this.occurrence){const e=or(t.concat(n));this.result.isEndOfRule=void 0===e,e instanceof pn&&(this.result.token=e.terminalType,this.result.occurrence=e.idx)}else super.walkAtLeastOneSep(e,t,n)}}function Fi(e,t,n=[]){n=(0,wt.A)(n);let r=[],i=0;function s(s){const o=Fi(s.concat(_t(e,i+1)),t,n);return r.concat(o)}for(;n.length<t&&i<e.length;){const t=e[i];if(t instanceof an)return s(t.definition);if(t instanceof sn)return s(t.definition);if(t instanceof cn)r=s(t.definition);else{if(t instanceof ln){return s(t.definition.concat([new dn({definition:t.definition})]))}if(t instanceof un){return s([new an({definition:t.definition}),new dn({definition:[new pn({terminalType:t.separator})].concat(t.definition)})])}if(t instanceof hn){const e=t.definition.concat([new dn({definition:[new pn({terminalType:t.separator})].concat(t.definition)})]);r=s(e)}else if(t instanceof dn){const e=t.definition.concat([new dn({definition:t.definition})]);r=s(e)}else{if(t instanceof fn)return(0,It.A)(t.definition,(e=>{!1===(0,Nt.A)(e.definition)&&(r=s(e.definition))})),r;if(!(t instanceof pn))throw Error("non exhaustive match");n.push(t.terminalType)}}i++}return r.push({partialPath:n,suffixDef:_t(e,i)}),r}function Gi(e,t,n,r){const i="EXIT_NONE_TERMINAL",s=[i],o="EXIT_ALTERNATIVE";let a=!1;const c=t.length,l=c-r-1,u=[],d=[];for(d.push({idx:-1,def:e,ruleStack:[],occurrenceStack:[]});!(0,Nt.A)(d);){const e=d.pop();if(e===o){a&&(0,Vr.A)(d).idx<=l&&d.pop();continue}const r=e.def,h=e.idx,f=e.ruleStack,p=e.occurrenceStack;if((0,Nt.A)(r))continue;const m=r[0];if(m===i){const e={idx:h,def:_t(r),ruleStack:Li(f),occurrenceStack:Li(p)};d.push(e)}else if(m instanceof pn)if(h<c-1){const e=h+1;if(n(t[e],m.terminalType)){const t={idx:e,def:_t(r),ruleStack:f,occurrenceStack:p};d.push(t)}}else{if(h!==c-1)throw Error("non exhaustive match");u.push({nextTokenType:m.terminalType,nextTokenOccurrence:m.idx,ruleStack:f,occurrenceStack:p}),a=!0}else if(m instanceof sn){const e=(0,wt.A)(f);e.push(m.nonTerminalName);const t=(0,wt.A)(p);t.push(m.idx);const n={idx:h,def:m.definition.concat(s,_t(r)),ruleStack:e,occurrenceStack:t};d.push(n)}else if(m instanceof cn){const e={idx:h,def:_t(r),ruleStack:f,occurrenceStack:p};d.push(e),d.push(o);const t={idx:h,def:m.definition.concat(_t(r)),ruleStack:f,occurrenceStack:p};d.push(t)}else if(m instanceof ln){const e=new dn({definition:m.definition,idx:m.idx}),t={idx:h,def:m.definition.concat([e],_t(r)),ruleStack:f,occurrenceStack:p};d.push(t)}else if(m instanceof un){const e=new pn({terminalType:m.separator}),t=new dn({definition:[e].concat(m.definition),idx:m.idx}),n={idx:h,def:m.definition.concat([t],_t(r)),ruleStack:f,occurrenceStack:p};d.push(n)}else if(m instanceof hn){const e={idx:h,def:_t(r),ruleStack:f,occurrenceStack:p};d.push(e),d.push(o);const t=new pn({terminalType:m.separator}),n=new dn({definition:[t].concat(m.definition),idx:m.idx}),i={idx:h,def:m.definition.concat([n],_t(r)),ruleStack:f,occurrenceStack:p};d.push(i)}else if(m instanceof dn){const e={idx:h,def:_t(r),ruleStack:f,occurrenceStack:p};d.push(e),d.push(o);const t=new dn({definition:m.definition,idx:m.idx}),n={idx:h,def:m.definition.concat([t],_t(r)),ruleStack:f,occurrenceStack:p};d.push(n)}else if(m instanceof fn)for(let t=m.definition.length-1;t>=0;t--){const e={idx:h,def:m.definition[t].definition.concat(_t(r)),ruleStack:f,occurrenceStack:p};d.push(e),d.push(o)}else if(m instanceof an)d.push({idx:h,def:m.definition.concat(_t(r)),ruleStack:f,occurrenceStack:p});else{if(!(m instanceof on))throw Error("non exhaustive match");d.push(Ki(m,h,f,p))}}return u}function Ki(e,t,n,r){const i=(0,wt.A)(n);i.push(e.name);const s=(0,wt.A)(r);return s.push(1),{idx:t,def:e.definition,ruleStack:i,occurrenceStack:s}}var Bi;function ji(e){if(e instanceof cn||"Option"===e)return Bi.OPTION;if(e instanceof dn||"Repetition"===e)return Bi.REPETITION;if(e instanceof ln||"RepetitionMandatory"===e)return Bi.REPETITION_MANDATORY;if(e instanceof un||"RepetitionMandatoryWithSeparator"===e)return Bi.REPETITION_MANDATORY_WITH_SEPARATOR;if(e instanceof hn||"RepetitionWithSeparator"===e)return Bi.REPETITION_WITH_SEPARATOR;if(e instanceof fn||"Alternation"===e)return Bi.ALTERNATION;throw Error("non exhaustive match")}function Vi(e){const{occurrence:t,rule:n,prodType:r,maxLookahead:i}=e,s=ji(r);return s===Bi.ALTERNATION?Zi(t,n,i):es(t,n,s,i)}function Hi(e,t,n,r){const i=e.length,s=Cn(e,(e=>Cn(e,(e=>1===e.length))));if(t)return function(t){const r=(0,Ct.A)(t,(e=>e.GATE));for(let s=0;s<i;s++){const t=e[s],i=t.length,o=r[s];if(void 0===o||!1!==o.call(this))e:for(let e=0;e<i;e++){const r=t[e],i=r.length;for(let e=0;e<i;e++){const t=this.LA(e+1);if(!1===n(t,r[e]))continue e}return s}}};if(s&&!r){const t=(0,Ct.A)(e,(e=>(0,Pn.A)(e))),n=(0,Yn.A)(t,((e,t,n)=>((0,It.A)(t,(t=>{(0,$t.A)(e,t.tokenTypeIdx)||(e[t.tokenTypeIdx]=n),(0,It.A)(t.categoryMatches,(t=>{(0,$t.A)(e,t)||(e[t]=n)}))})),e)),{});return function(){const e=this.LA(1);return n[e.tokenTypeIdx]}}return function(){for(let t=0;t<i;t++){const r=e[t],i=r.length;e:for(let e=0;e<i;e++){const i=r[e],s=i.length;for(let e=0;e<s;e++){const t=this.LA(e+1);if(!1===n(t,i[e]))continue e}return t}}}}function Wi(e,t,n){const r=Cn(e,(e=>1===e.length)),i=e.length;if(r&&!n){const t=(0,Pn.A)(e);if(1===t.length&&(0,Nt.A)(t[0].categoryMatches)){const e=t[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===e}}{const e=(0,Yn.A)(t,((e,t,n)=>(e[t.tokenTypeIdx]=!0,(0,It.A)(t.categoryMatches,(t=>{e[t]=!0})),e)),[]);return function(){const t=this.LA(1);return!0===e[t.tokenTypeIdx]}}}return function(){e:for(let n=0;n<i;n++){const r=e[n],i=r.length;for(let e=0;e<i;e++){const n=this.LA(e+1);if(!1===t(n,r[e]))continue e}return!0}return!1}}!function(e){e[e.OPTION=0]="OPTION",e[e.REPETITION=1]="REPETITION",e[e.REPETITION_MANDATORY=2]="REPETITION_MANDATORY",e[e.REPETITION_MANDATORY_WITH_SEPARATOR=3]="REPETITION_MANDATORY_WITH_SEPARATOR",e[e.REPETITION_WITH_SEPARATOR=4]="REPETITION_WITH_SEPARATOR",e[e.ALTERNATION=5]="ALTERNATION"}(Bi||(Bi={}));class zi extends Ln{constructor(e,t,n){super(),this.topProd=e,this.targetOccurrence=t,this.targetProdType=n}startWalking(){return this.walk(this.topProd),this.restDef}checkIsTarget(e,t,n,r){return e.idx===this.targetOccurrence&&this.targetProdType===t&&(this.restDef=n.concat(r),!0)}walkOption(e,t,n){this.checkIsTarget(e,Bi.OPTION,t,n)||super.walkOption(e,t,n)}walkAtLeastOne(e,t,n){this.checkIsTarget(e,Bi.REPETITION_MANDATORY,t,n)||super.walkOption(e,t,n)}walkAtLeastOneSep(e,t,n){this.checkIsTarget(e,Bi.REPETITION_MANDATORY_WITH_SEPARATOR,t,n)||super.walkOption(e,t,n)}walkMany(e,t,n){this.checkIsTarget(e,Bi.REPETITION,t,n)||super.walkOption(e,t,n)}walkManySep(e,t,n){this.checkIsTarget(e,Bi.REPETITION_WITH_SEPARATOR,t,n)||super.walkOption(e,t,n)}}class Yi extends gn{constructor(e,t,n){super(),this.targetOccurrence=e,this.targetProdType=t,this.targetRef=n,this.result=[]}checkIsTarget(e,t){e.idx!==this.targetOccurrence||this.targetProdType!==t||void 0!==this.targetRef&&e!==this.targetRef||(this.result=e.definition)}visitOption(e){this.checkIsTarget(e,Bi.OPTION)}visitRepetition(e){this.checkIsTarget(e,Bi.REPETITION)}visitRepetitionMandatory(e){this.checkIsTarget(e,Bi.REPETITION_MANDATORY)}visitRepetitionMandatoryWithSeparator(e){this.checkIsTarget(e,Bi.REPETITION_MANDATORY_WITH_SEPARATOR)}visitRepetitionWithSeparator(e){this.checkIsTarget(e,Bi.REPETITION_WITH_SEPARATOR)}visitAlternation(e){this.checkIsTarget(e,Bi.ALTERNATION)}}function Xi(e){const t=new Array(e);for(let n=0;n<e;n++)t[n]=[];return t}function qi(e){let t=[""];for(let n=0;n<e.length;n++){const r=e[n],i=[];for(let e=0;e<t.length;e++){const n=t[e];i.push(n+"_"+r.tokenTypeIdx);for(let e=0;e<r.categoryMatches.length;e++){const t="_"+r.categoryMatches[e];i.push(n+t)}}t=i}return t}function Qi(e,t,n){for(let r=0;r<e.length;r++){if(r===n)continue;const i=e[r];for(let e=0;e<t.length;e++){if(!0===i[t[e]])return!1}}return!0}function Ji(e,t){const n=(0,Ct.A)(e,(e=>Fi([e],1))),r=Xi(n.length),i=(0,Ct.A)(n,(e=>{const t={};return(0,It.A)(e,(e=>{const n=qi(e.partialPath);(0,It.A)(n,(e=>{t[e]=!0}))})),t}));let s=n;for(let o=1;o<=t;o++){const e=s;s=Xi(e.length);for(let n=0;n<e.length;n++){const a=e[n];for(let e=0;e<a.length;e++){const c=a[e].partialPath,l=a[e].suffixDef,u=qi(c);if(Qi(i,u,n)||(0,Nt.A)(l)||c.length===t){const e=r[n];if(!1===ts(e,c)){e.push(c);for(let e=0;e<u.length;e++){const t=u[e];i[n][t]=!0}}}else{const e=Fi(l,o+1,c);s[n]=s[n].concat(e),(0,It.A)(e,(e=>{const t=qi(e.partialPath);(0,It.A)(t,(e=>{i[n][e]=!0}))}))}}}}return r}function Zi(e,t,n,r){const i=new Yi(e,Bi.ALTERNATION,r);return t.accept(i),Ji(i.result,n)}function es(e,t,n,r){const i=new Yi(e,n);t.accept(i);const s=i.result,o=new zi(t,e,n).startWalking();return Ji([new an({definition:s}),new an({definition:o})],r)}function ts(e,t){e:for(let n=0;n<e.length;n++){const r=e[n];if(r.length===t.length){for(let e=0;e<r.length;e++){const n=t[e],i=r[e];if(!1===(n===i||void 0!==i.categoryMatchesMap[n.tokenTypeIdx]))continue e}return!0}}return!1}function ns(e){return Cn(e,(e=>Cn(e,(e=>Cn(e,(e=>(0,Nt.A)(e.categoryMatches)))))))}function rs(e,t,n,r){const i=xi(e,(e=>function(e,t){const n=new os;e.accept(n);const r=n.allProductions,i=wi(r,is),s=Yt(i,(e=>e.length>1)),o=(0,Ct.A)((0,St.A)(s),(n=>{const r=or(n),i=t.buildDuplicateFoundError(e,n),s=wn(r),o={message:i,type:to.DUPLICATE_PRODUCTIONS,ruleName:e.name,dslName:s,occurrence:r.idx},a=ss(r);return a&&(o.parameter=a),o}));return o}(e,n))),s=function(e,t,n){const r=[],i=(0,Ct.A)(t,(e=>e.name));return(0,It.A)(e,(e=>{const t=e.name;if(In(i,t)){const i=n.buildNamespaceConflictError(e);r.push({message:i,type:to.CONFLICT_TOKENS_RULES_NAMESPACE,ruleName:t})}})),r}(e,t,n),o=xi(e,(e=>function(e,t){const n=new ls;e.accept(n);const r=n.alternations,i=xi(r,(n=>n.definition.length>255?[{message:t.buildTooManyAlternativesError({topLevelRule:e,alternation:n}),type:to.TOO_MANY_ALTS,ruleName:e.name,occurrence:n.idx}]:[]));return i}(e,n))),a=xi(e,(t=>function(e,t,n,r){const i=[],s=(0,Yn.A)(t,((t,n)=>n.name===e.name?t+1:t),0);if(s>1){const t=r.buildDuplicateRuleNameError({topLevelRule:e,grammarName:n});i.push({message:t,type:to.DUPLICATE_RULE_NAME,ruleName:e.name})}return i}(t,e,r,n)));return i.concat(s,o,a)}function is(e){return`${wn(e)}_#_${e.idx}_#_${ss(e)}`}function ss(e){return e instanceof pn?e.terminalType.name:e instanceof sn?e.nonTerminalName:""}class os extends gn{constructor(){super(...arguments),this.allProductions=[]}visitNonTerminal(e){this.allProductions.push(e)}visitOption(e){this.allProductions.push(e)}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}visitAlternation(e){this.allProductions.push(e)}visitTerminal(e){this.allProductions.push(e)}}function as(e,t,n,r=[]){const i=[],s=cs(t.definition);if((0,Nt.A)(s))return[];{const t=e.name;In(s,e)&&i.push({message:n.buildLeftRecursionError({topLevelRule:e,leftRecursionPath:r}),type:to.LEFT_RECURSION,ruleName:t});const o=ir(s,r.concat([e])),a=xi(o,(t=>{const i=(0,wt.A)(r);return i.push(t),as(e,t,n,i)}));return i.concat(a)}}function cs(e){let t=[];if((0,Nt.A)(e))return t;const n=or(e);if(n instanceof sn)t.push(n.referencedRule);else if(n instanceof an||n instanceof cn||n instanceof ln||n instanceof un||n instanceof hn||n instanceof dn)t=t.concat(cs(n.definition));else if(n instanceof fn)t=(0,Pn.A)((0,Ct.A)(n.definition,(e=>cs(e.definition))));else if(!(n instanceof pn))throw Error("non exhaustive match");const r=$n(n),i=e.length>1;if(r&&i){const n=_t(e);return t.concat(cs(n))}return t}class ls extends gn{constructor(){super(...arguments),this.alternations=[]}visitAlternation(e){this.alternations.push(e)}}function us(e,t,n){const r=new ls;e.accept(r);let i=r.alternations;i=Vn(i,(e=>!0===e.ignoreAmbiguities));const s=xi(i,(r=>{const i=r.idx,s=r.maxLookahead||t,o=Zi(i,e,s,r),a=function(e,t,n,r){const i=[],s=(0,Yn.A)(e,((n,r,s)=>(!0===t.definition[s].ignoreAmbiguities||(0,It.A)(r,(r=>{const o=[s];(0,It.A)(e,((e,n)=>{s!==n&&ts(e,r)&&!0!==t.definition[n].ignoreAmbiguities&&o.push(n)})),o.length>1&&!ts(i,r)&&(i.push(r),n.push({alts:o,path:r}))})),n)),[]),o=(0,Ct.A)(s,(e=>{const i=(0,Ct.A)(e.alts,(e=>e+1));return{message:r.buildAlternationAmbiguityError({topLevelRule:n,alternation:t,ambiguityIndices:i,prefixPath:e.path}),type:to.AMBIGUOUS_ALTS,ruleName:n.name,occurrence:t.idx,alternatives:e.alts}}));return o}(o,r,e,n),c=function(e,t,n,r){const i=(0,Yn.A)(e,((e,t,n)=>{const r=(0,Ct.A)(t,(e=>({idx:n,path:e})));return e.concat(r)}),[]),s=sr(xi(i,(e=>{if(!0===t.definition[e.idx].ignoreAmbiguities)return[];const s=e.idx,o=e.path,a=(0,Xn.A)(i,(e=>{return!0!==t.definition[e.idx].ignoreAmbiguities&&e.idx<s&&(n=e.path,r=o,n.length<r.length&&Cn(n,((e,t)=>{const n=r[t];return e===n||n.categoryMatchesMap[e.tokenTypeIdx]})));var n,r}));return(0,Ct.A)(a,(e=>{const i=[e.idx+1,s+1],o=0===t.idx?"":t.idx;return{message:r.buildAlternationPrefixAmbiguityError({topLevelRule:n,alternation:t,ambiguityIndices:i,prefixPath:e.path}),type:to.AMBIGUOUS_PREFIX_ALTS,ruleName:n.name,occurrence:o,alternatives:i}}))})));return s}(o,r,e,n);return a.concat(c)}));return s}class ds extends gn{constructor(){super(...arguments),this.allProductions=[]}visitRepetitionWithSeparator(e){this.allProductions.push(e)}visitRepetitionMandatory(e){this.allProductions.push(e)}visitRepetitionMandatoryWithSeparator(e){this.allProductions.push(e)}visitRepetition(e){this.allProductions.push(e)}}function hs(e){const t=(0,Gn.A)(e,{errMsgProvider:Ri}),n={};return(0,It.A)(e.rules,(e=>{n[e.name]=e})),function(e,t){const n=new ki(e,t);return n.resolveRefs(),n.errors}(n,t.errMsgProvider)}const fs="MismatchedTokenException",ps="NoViableAltException",ms="EarlyExitException",gs="NotAllInputParsedException",ys=[fs,ps,ms,gs];function As(e){return In(ys,e.name)}Object.freeze(ys);class Ts extends Error{constructor(e,t){super(e),this.token=t,this.resyncedTokens=[],Object.setPrototypeOf(this,new.target.prototype),Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class vs extends Ts{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=fs}}class Rs extends Ts{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=ps}}class Es extends Ts{constructor(e,t){super(e,t),this.name=gs}}class ks extends Ts{constructor(e,t,n){super(e,t),this.previousToken=n,this.name=ms}}const xs={},Is="InRuleRecoveryException";class Ss extends Error{constructor(e){super(e),this.name=Is}}function Ns(e,t,n,r,i,s,o){const a=this.getKeyForAutomaticLookahead(r,i);let c=this.firstAfterRepMap[a];if(void 0===c){const e=this.getCurrRuleFullName();c=new s(this.getGAstProductions()[e],i).startWalking(),this.firstAfterRepMap[a]=c}let l=c.token,u=c.occurrence;const d=c.isEndOfRule;1===this.RULE_STACK.length&&d&&void 0===l&&(l=yi,u=1),void 0!==l&&void 0!==u&&this.shouldInRepetitionRecoveryBeTried(l,u,o)&&this.tryInRepetitionRecovery(e,t,n,l)}const Cs=1024,$s=1280,ws=1536;function Ls(e,t,n){return n|t|e}class Os{constructor(e){var t;this.maxLookahead=null!==(t=null==e?void 0:e.maxLookahead)&&void 0!==t?t:Zs.maxLookahead}validate(e){const t=this.validateNoLeftRecursion(e.rules);if((0,Nt.A)(t)){const n=this.validateEmptyOrAlternatives(e.rules),r=this.validateAmbiguousAlternationAlternatives(e.rules,this.maxLookahead),i=this.validateSomeNonEmptyLookaheadPath(e.rules,this.maxLookahead);return[...t,...n,...r,...i]}return t}validateNoLeftRecursion(e){return xi(e,(e=>as(e,e,Ei)))}validateEmptyOrAlternatives(e){return xi(e,(e=>function(e,t){const n=new ls;e.accept(n);const r=n.alternations;return xi(r,(n=>{const r=Li(n.definition);return xi(r,((r,i)=>{const s=Gi([r],[],Wr,1);return(0,Nt.A)(s)?[{message:t.buildEmptyAlternationError({topLevelRule:e,alternation:n,emptyChoiceIdx:i}),type:to.NONE_LAST_EMPTY_ALT,ruleName:e.name,occurrence:n.idx,alternative:i+1}]:[]}))}))}(e,Ei)))}validateAmbiguousAlternationAlternatives(e,t){return xi(e,(e=>us(e,t,Ei)))}validateSomeNonEmptyLookaheadPath(e,t){return function(e,t,n){const r=[];return(0,It.A)(e,(e=>{const i=new ds;e.accept(i);const s=i.allProductions;(0,It.A)(s,(i=>{const s=ji(i),o=i.maxLookahead||t,a=es(i.idx,e,s,o)[0];if((0,Nt.A)((0,Pn.A)(a))){const t=n.buildEmptyRepetitionError({topLevelRule:e,repetition:i});r.push({message:t,type:to.NO_NON_EMPTY_LOOKAHEAD,ruleName:e.name})}}))})),r}(e,t,Ei)}buildLookaheadForAlternation(e){return function(e,t,n,r,i,s){const o=Zi(e,t,n);return s(o,r,ns(o)?zr:Wr,i)}(e.prodOccurrence,e.rule,e.maxLookahead,e.hasPredicates,e.dynamicTokensEnabled,Hi)}buildLookaheadForOptional(e){return function(e,t,n,r,i,s){const o=es(e,t,i,n),a=ns(o)?zr:Wr;return s(o[0],a,r)}(e.prodOccurrence,e.rule,e.maxLookahead,e.dynamicTokensEnabled,ji(e.prodType),Wi)}}const bs=new class extends gn{constructor(){super(...arguments),this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}reset(){this.dslMethods={option:[],alternation:[],repetition:[],repetitionWithSeparator:[],repetitionMandatory:[],repetitionMandatoryWithSeparator:[]}}visitOption(e){this.dslMethods.option.push(e)}visitRepetitionWithSeparator(e){this.dslMethods.repetitionWithSeparator.push(e)}visitRepetitionMandatory(e){this.dslMethods.repetitionMandatory.push(e)}visitRepetitionMandatoryWithSeparator(e){this.dslMethods.repetitionMandatoryWithSeparator.push(e)}visitRepetition(e){this.dslMethods.repetition.push(e)}visitAlternation(e){this.dslMethods.alternation.push(e)}};function _s(e,t){!0===isNaN(e.startOffset)?(e.startOffset=t.startOffset,e.endOffset=t.endOffset):e.endOffset<t.endOffset==!0&&(e.endOffset=t.endOffset)}function Ps(e,t){!0===isNaN(e.startOffset)?(e.startOffset=t.startOffset,e.startColumn=t.startColumn,e.startLine=t.startLine,e.endOffset=t.endOffset,e.endColumn=t.endColumn,e.endLine=t.endLine):e.endOffset<t.endOffset==!0&&(e.endOffset=t.endOffset,e.endColumn=t.endColumn,e.endLine=t.endLine)}const Ms="name";function Ds(e,t){Object.defineProperty(e,Ms,{enumerable:!1,configurable:!0,writable:!1,value:t})}function Us(e,t){const n=(0,Kt.A)(e),r=n.length;for(let i=0;i<r;i++){const r=e[n[i]],s=r.length;for(let e=0;e<s;e++){const n=r[e];void 0===n.tokenTypeIdx&&this[n.name](n.children,t)}}}function Fs(e,t){const n=function(){};Ds(n,e+"BaseSemantics");const r={visit:function(e,t){if((0,vn.A)(e)&&(e=e[0]),!(0,Fn.A)(e))return this[e.name](e.children,t)},validateVisitor:function(){const e=function(e,t){const n=function(e,t){const n=(0,Xn.A)(t,(t=>!1===(0,Hn.A)(e[t]))),r=(0,Ct.A)(n,(t=>({msg:`Missing visitor method: <${t}> on ${e.constructor.name} CST Visitor.`,type:Gs.MISSING_METHOD,methodName:t})));return sr(r)}(e,t);return n}(this,t);if(!(0,Nt.A)(e)){const t=(0,Ct.A)(e,(e=>e.msg));throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>:\n\t${t.join("\n\n").replace(/\n/g,"\n\t")}`)}}};return(n.prototype=r).constructor=n,n._RULE_NAMES=t,n}var Gs;!function(e){e[e.REDUNDANT_METHOD=0]="REDUNDANT_METHOD",e[e.MISSING_METHOD=1]="MISSING_METHOD"}(Gs||(Gs={}));var Ks=n(23149);const Bs={description:"This Object indicates the Parser is during Recording Phase"};Object.freeze(Bs);const js=!0,Vs=Math.pow(2,8)-1,Hs=gi({name:"RECORDING_PHASE_TOKEN",pattern:ii.NA});qr([Hs]);const Ws=Ai(Hs,"This IToken indicates the Parser is in Recording Phase\n\tSee: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details",-1,-1,-1,-1,-1,-1);Object.freeze(Ws);const zs={name:"This CSTNode indicates the Parser is in Recording Phase\n\tSee: https://chevrotain.io/docs/guide/internals.html#grammar-recording for details",children:{}};function Ys(e,t,n,r=!1){Qs(n);const i=(0,Vr.A)(this.recordingProdStack),s=(0,Hn.A)(t)?t:t.DEF,o=new e({definition:[],idx:n});return r&&(o.separator=t.SEP),(0,$t.A)(t,"MAX_LOOKAHEAD")&&(o.maxLookahead=t.MAX_LOOKAHEAD),this.recordingProdStack.push(o),s.call(this),i.definition.push(o),this.recordingProdStack.pop(),Bs}function Xs(e,t){Qs(t);const n=(0,Vr.A)(this.recordingProdStack),r=!1===(0,vn.A)(e),i=!1===r?e:e.DEF,s=new fn({definition:[],idx:t,ignoreAmbiguities:r&&!0===e.IGNORE_AMBIGUITIES});(0,$t.A)(e,"MAX_LOOKAHEAD")&&(s.maxLookahead=e.MAX_LOOKAHEAD);const o=En(i,(e=>(0,Hn.A)(e.GATE)));return s.hasPredicates=o,n.definition.push(s),(0,It.A)(i,(e=>{const t=new an({definition:[]});s.definition.push(t),(0,$t.A)(e,"IGNORE_AMBIGUITIES")?t.ignoreAmbiguities=e.IGNORE_AMBIGUITIES:(0,$t.A)(e,"GATE")&&(t.ignoreAmbiguities=!0),this.recordingProdStack.push(t),e.ALT.call(this),this.recordingProdStack.pop()})),Bs}function qs(e){return 0===e?"":`${e}`}function Qs(e){if(e<0||e>Vs){const t=new Error(`Invalid DSL Method idx value: <${e}>\n\tIdx value must be a none negative value smaller than ${Vs+1}`);throw t.KNOWN_RECORDER_ERROR=!0,t}}const Js=Ai(yi,"",NaN,NaN,NaN,NaN,NaN,NaN);Object.freeze(Js);const Zs=Object.freeze({recoveryEnabled:!1,maxLookahead:3,dynamicTokensEnabled:!1,outputCst:!0,errorMessageProvider:vi,nodeLocationTracking:"none",traceInitPerf:!1,skipValidations:!1}),eo=Object.freeze({recoveryValueFunc:()=>{},resyncEnabled:!0});var to,no,ro;function io(e=void 0){return function(){return e}}!function(e){e[e.INVALID_RULE_NAME=0]="INVALID_RULE_NAME",e[e.DUPLICATE_RULE_NAME=1]="DUPLICATE_RULE_NAME",e[e.INVALID_RULE_OVERRIDE=2]="INVALID_RULE_OVERRIDE",e[e.DUPLICATE_PRODUCTIONS=3]="DUPLICATE_PRODUCTIONS",e[e.UNRESOLVED_SUBRULE_REF=4]="UNRESOLVED_SUBRULE_REF",e[e.LEFT_RECURSION=5]="LEFT_RECURSION",e[e.NONE_LAST_EMPTY_ALT=6]="NONE_LAST_EMPTY_ALT",e[e.AMBIGUOUS_ALTS=7]="AMBIGUOUS_ALTS",e[e.CONFLICT_TOKENS_RULES_NAMESPACE=8]="CONFLICT_TOKENS_RULES_NAMESPACE",e[e.INVALID_TOKEN_NAME=9]="INVALID_TOKEN_NAME",e[e.NO_NON_EMPTY_LOOKAHEAD=10]="NO_NON_EMPTY_LOOKAHEAD",e[e.AMBIGUOUS_PREFIX_ALTS=11]="AMBIGUOUS_PREFIX_ALTS",e[e.TOO_MANY_ALTS=12]="TOO_MANY_ALTS",e[e.CUSTOM_LOOKAHEAD_VALIDATION=13]="CUSTOM_LOOKAHEAD_VALIDATION"}(to||(to={}));class so{static performSelfAnalysis(e){throw Error("The **static** `performSelfAnalysis` method has been deprecated.\t\nUse the **instance** method with the same name instead.")}performSelfAnalysis(){this.TRACE_INIT("performSelfAnalysis",(()=>{let e;this.selfAnalysisDone=!0;const t=this.className;this.TRACE_INIT("toFastProps",(()=>{Lt(this)})),this.TRACE_INIT("Grammar Recording",(()=>{try{this.enableRecording(),(0,It.A)(this.definedRulesNames,(e=>{const t=this[e].originalGrammarAction;let n;this.TRACE_INIT(`${e} Rule`,(()=>{n=this.topLevelRuleRecord(e,t)})),this.gastProductionsCache[e]=n}))}finally{this.disableRecording()}}));let n=[];if(this.TRACE_INIT("Grammar Resolving",(()=>{n=hs({rules:(0,St.A)(this.gastProductionsCache)}),this.definitionErrors=this.definitionErrors.concat(n)})),this.TRACE_INIT("Grammar Validations",(()=>{if((0,Nt.A)(n)&&!1===this.skipValidations){const n=(e={rules:(0,St.A)(this.gastProductionsCache),tokenTypes:(0,St.A)(this.tokensMap),errMsgProvider:Ei,grammarName:t},rs((e=(0,Gn.A)(e,{errMsgProvider:Ei})).rules,e.tokenTypes,e.errMsgProvider,e.grammarName)),r=function(e){const t=e.lookaheadStrategy.validate({rules:e.rules,tokenTypes:e.tokenTypes,grammarName:e.grammarName});return(0,Ct.A)(t,(e=>Object.assign({type:to.CUSTOM_LOOKAHEAD_VALIDATION},e)))}({lookaheadStrategy:this.lookaheadStrategy,rules:(0,St.A)(this.gastProductionsCache),tokenTypes:(0,St.A)(this.tokensMap),grammarName:t});this.definitionErrors=this.definitionErrors.concat(n,r)}var e})),(0,Nt.A)(this.definitionErrors)&&(this.recoveryEnabled&&this.TRACE_INIT("computeAllProdsFollows",(()=>{const e=function(e){const t={};return(0,It.A)(e,(e=>{const n=new Un(e).startWalking();jt(t,n)})),t}((0,St.A)(this.gastProductionsCache));this.resyncFollows=e})),this.TRACE_INIT("ComputeLookaheadFunctions",(()=>{var e,t;null===(t=(e=this.lookaheadStrategy).initialize)||void 0===t||t.call(e,{rules:(0,St.A)(this.gastProductionsCache)}),this.preComputeLookaheadFunctions((0,St.A)(this.gastProductionsCache))}))),!so.DEFER_DEFINITION_ERRORS_HANDLING&&!(0,Nt.A)(this.definitionErrors))throw e=(0,Ct.A)(this.definitionErrors,(e=>e.message)),new Error(`Parser Definition Errors detected:\n ${e.join("\n-------------------------------\n")}`)}))}constructor(e,t){this.definitionErrors=[],this.selfAnalysisDone=!1;const n=this;if(n.initErrorHandler(t),n.initLexerAdapter(),n.initLooksAhead(t),n.initRecognizerEngine(e,t),n.initRecoverable(t),n.initTreeBuilder(t),n.initContentAssist(),n.initGastRecorder(t),n.initPerformanceTracer(t),(0,$t.A)(t,"ignoredIssues"))throw new Error("The <ignoredIssues> IParserConfig property has been deprecated.\n\tPlease use the <IGNORE_AMBIGUITIES> flag on the relevant DSL method instead.\n\tSee: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#IGNORING_AMBIGUITIES\n\tFor further details.");this.skipValidations=(0,$t.A)(t,"skipValidations")?t.skipValidations:Zs.skipValidations}}so.DEFER_DEFINITION_ERRORS_HANDLING=!1,no=so,ro=[class{initRecoverable(e){this.firstAfterRepMap={},this.resyncFollows={},this.recoveryEnabled=(0,$t.A)(e,"recoveryEnabled")?e.recoveryEnabled:Zs.recoveryEnabled,this.recoveryEnabled&&(this.attemptInRepetitionRecovery=Ns)}getTokenToInsert(e){const t=Ai(e,"",NaN,NaN,NaN,NaN,NaN,NaN);return t.isInsertedInRecovery=!0,t}canTokenTypeBeInsertedInRecovery(e){return!0}canTokenTypeBeDeletedInRecovery(e){return!0}tryInRepetitionRecovery(e,t,n,r){const i=this.findReSyncTokenType(),s=this.exportLexerState(),o=[];let a=!1;const c=this.LA(1);let l=this.LA(1);const u=()=>{const e=this.LA(0),t=this.errorMessageProvider.buildMismatchTokenMessage({expected:r,actual:c,previous:e,ruleName:this.getCurrRuleFullName()}),n=new vs(t,c,this.LA(0));n.resyncedTokens=Li(o),this.SAVE_ERROR(n)};for(;!a;){if(this.tokenMatcher(l,r))return void u();if(n.call(this))return u(),void e.apply(this,t);this.tokenMatcher(l,i)?a=!0:(l=this.SKIP_TOKEN(),this.addToResyncTokens(l,o))}this.importLexerState(s)}shouldInRepetitionRecoveryBeTried(e,t,n){return!1!==n&&!this.tokenMatcher(this.LA(1),e)&&!this.isBackTracking()&&!this.canPerformInRuleRecovery(e,this.getFollowsForInRuleRecovery(e,t))}getFollowsForInRuleRecovery(e,t){const n=this.getCurrentGrammarPath(e,t);return this.getNextPossibleTokenTypes(n)}tryInRuleRecovery(e,t){if(this.canRecoverWithSingleTokenInsertion(e,t))return this.getTokenToInsert(e);if(this.canRecoverWithSingleTokenDeletion(e)){const e=this.SKIP_TOKEN();return this.consumeToken(),e}throw new Ss("sad sad panda")}canPerformInRuleRecovery(e,t){return this.canRecoverWithSingleTokenInsertion(e,t)||this.canRecoverWithSingleTokenDeletion(e)}canRecoverWithSingleTokenInsertion(e,t){if(!this.canTokenTypeBeInsertedInRecovery(e))return!1;if((0,Nt.A)(t))return!1;const n=this.LA(1);return void 0!==(0,ar.A)(t,(e=>this.tokenMatcher(n,e)))}canRecoverWithSingleTokenDeletion(e){return!!this.canTokenTypeBeDeletedInRecovery(e)&&this.tokenMatcher(this.LA(2),e)}isInCurrentRuleReSyncSet(e){const t=this.getCurrFollowKey(),n=this.getFollowSetFromFollowKey(t);return In(n,e)}findReSyncTokenType(){const e=this.flattenFollowSet();let t=this.LA(1),n=2;for(;;){const r=(0,ar.A)(e,(e=>Ti(t,e)));if(void 0!==r)return r;t=this.LA(n),n++}}getCurrFollowKey(){if(1===this.RULE_STACK.length)return xs;const e=this.getLastExplicitRuleShortName(),t=this.getLastExplicitRuleOccurrenceIndex(),n=this.getPreviousExplicitRuleShortName();return{ruleName:this.shortRuleNameToFullName(e),idxInCallingRule:t,inRule:this.shortRuleNameToFullName(n)}}buildFullFollowKeyStack(){const e=this.RULE_STACK,t=this.RULE_OCCURRENCE_STACK;return(0,Ct.A)(e,((n,r)=>0===r?xs:{ruleName:this.shortRuleNameToFullName(n),idxInCallingRule:t[r],inRule:this.shortRuleNameToFullName(e[r-1])}))}flattenFollowSet(){const e=(0,Ct.A)(this.buildFullFollowKeyStack(),(e=>this.getFollowSetFromFollowKey(e)));return(0,Pn.A)(e)}getFollowSetFromFollowKey(e){if(e===xs)return[yi];const t=e.ruleName+e.idxInCallingRule+Dn+e.inRule;return this.resyncFollows[t]}addToResyncTokens(e,t){return this.tokenMatcher(e,yi)||t.push(e),t}reSyncTo(e){const t=[];let n=this.LA(1);for(;!1===this.tokenMatcher(n,e);)n=this.SKIP_TOKEN(),this.addToResyncTokens(n,t);return Li(t)}attemptInRepetitionRecovery(e,t,n,r,i,s,o){}getCurrentGrammarPath(e,t){return{ruleStack:this.getHumanReadableRuleStack(),occurrenceStack:(0,wt.A)(this.RULE_OCCURRENCE_STACK),lastTok:e,lastTokOccurrence:t}}getHumanReadableRuleStack(){return(0,Ct.A)(this.RULE_STACK,(e=>this.shortRuleNameToFullName(e)))}},class{initLooksAhead(e){this.dynamicTokensEnabled=(0,$t.A)(e,"dynamicTokensEnabled")?e.dynamicTokensEnabled:Zs.dynamicTokensEnabled,this.maxLookahead=(0,$t.A)(e,"maxLookahead")?e.maxLookahead:Zs.maxLookahead,this.lookaheadStrategy=(0,$t.A)(e,"lookaheadStrategy")?e.lookaheadStrategy:new Os({maxLookahead:this.maxLookahead}),this.lookAheadFuncsCache=new Map}preComputeLookaheadFunctions(e){(0,It.A)(e,(e=>{this.TRACE_INIT(`${e.name} Rule Lookahead`,(()=>{const{alternation:t,repetition:n,option:r,repetitionMandatory:i,repetitionMandatoryWithSeparator:s,repetitionWithSeparator:o}=function(e){bs.reset(),e.accept(bs);const t=bs.dslMethods;return bs.reset(),t}(e);(0,It.A)(t,(t=>{const n=0===t.idx?"":t.idx;this.TRACE_INIT(`${wn(t)}${n}`,(()=>{const n=this.lookaheadStrategy.buildLookaheadForAlternation({prodOccurrence:t.idx,rule:e,maxLookahead:t.maxLookahead||this.maxLookahead,hasPredicates:t.hasPredicates,dynamicTokensEnabled:this.dynamicTokensEnabled}),r=Ls(this.fullRuleNameToShort[e.name],256,t.idx);this.setLaFuncCache(r,n)}))})),(0,It.A)(n,(t=>{this.computeLookaheadFunc(e,t.idx,768,"Repetition",t.maxLookahead,wn(t))})),(0,It.A)(r,(t=>{this.computeLookaheadFunc(e,t.idx,512,"Option",t.maxLookahead,wn(t))})),(0,It.A)(i,(t=>{this.computeLookaheadFunc(e,t.idx,Cs,"RepetitionMandatory",t.maxLookahead,wn(t))})),(0,It.A)(s,(t=>{this.computeLookaheadFunc(e,t.idx,ws,"RepetitionMandatoryWithSeparator",t.maxLookahead,wn(t))})),(0,It.A)(o,(t=>{this.computeLookaheadFunc(e,t.idx,$s,"RepetitionWithSeparator",t.maxLookahead,wn(t))}))}))}))}computeLookaheadFunc(e,t,n,r,i,s){this.TRACE_INIT(`${s}${0===t?"":t}`,(()=>{const s=this.lookaheadStrategy.buildLookaheadForOptional({prodOccurrence:t,rule:e,maxLookahead:i||this.maxLookahead,dynamicTokensEnabled:this.dynamicTokensEnabled,prodType:r}),o=Ls(this.fullRuleNameToShort[e.name],n,t);this.setLaFuncCache(o,s)}))}getKeyForAutomaticLookahead(e,t){return Ls(this.getLastExplicitRuleShortName(),e,t)}getLaFuncFromCache(e){return this.lookAheadFuncsCache.get(e)}setLaFuncCache(e,t){this.lookAheadFuncsCache.set(e,t)}},class{initTreeBuilder(e){if(this.CST_STACK=[],this.outputCst=e.outputCst,this.nodeLocationTracking=(0,$t.A)(e,"nodeLocationTracking")?e.nodeLocationTracking:Zs.nodeLocationTracking,this.outputCst)if(/full/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=Ps,this.setNodeLocationFromNode=Ps,this.cstPostRule=jr.A,this.setInitialNodeLocation=this.setInitialNodeLocationFullRecovery):(this.setNodeLocationFromToken=jr.A,this.setNodeLocationFromNode=jr.A,this.cstPostRule=this.cstPostRuleFull,this.setInitialNodeLocation=this.setInitialNodeLocationFullRegular);else if(/onlyOffset/i.test(this.nodeLocationTracking))this.recoveryEnabled?(this.setNodeLocationFromToken=_s,this.setNodeLocationFromNode=_s,this.cstPostRule=jr.A,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRecovery):(this.setNodeLocationFromToken=jr.A,this.setNodeLocationFromNode=jr.A,this.cstPostRule=this.cstPostRuleOnlyOffset,this.setInitialNodeLocation=this.setInitialNodeLocationOnlyOffsetRegular);else{if(!/none/i.test(this.nodeLocationTracking))throw Error(`Invalid <nodeLocationTracking> config option: "${e.nodeLocationTracking}"`);this.setNodeLocationFromToken=jr.A,this.setNodeLocationFromNode=jr.A,this.cstPostRule=jr.A,this.setInitialNodeLocation=jr.A}else this.cstInvocationStateUpdate=jr.A,this.cstFinallyStateUpdate=jr.A,this.cstPostTerminal=jr.A,this.cstPostNonTerminal=jr.A,this.cstPostRule=jr.A}setInitialNodeLocationOnlyOffsetRecovery(e){e.location={startOffset:NaN,endOffset:NaN}}setInitialNodeLocationOnlyOffsetRegular(e){e.location={startOffset:this.LA(1).startOffset,endOffset:NaN}}setInitialNodeLocationFullRecovery(e){e.location={startOffset:NaN,startLine:NaN,startColumn:NaN,endOffset:NaN,endLine:NaN,endColumn:NaN}}setInitialNodeLocationFullRegular(e){const t=this.LA(1);e.location={startOffset:t.startOffset,startLine:t.startLine,startColumn:t.startColumn,endOffset:NaN,endLine:NaN,endColumn:NaN}}cstInvocationStateUpdate(e){const t={name:e,children:Object.create(null)};this.setInitialNodeLocation(t),this.CST_STACK.push(t)}cstFinallyStateUpdate(){this.CST_STACK.pop()}cstPostRuleFull(e){const t=this.LA(0),n=e.location;n.startOffset<=t.startOffset==1?(n.endOffset=t.endOffset,n.endLine=t.endLine,n.endColumn=t.endColumn):(n.startOffset=NaN,n.startLine=NaN,n.startColumn=NaN)}cstPostRuleOnlyOffset(e){const t=this.LA(0),n=e.location;n.startOffset<=t.startOffset==1?n.endOffset=t.endOffset:n.startOffset=NaN}cstPostTerminal(e,t){const n=this.CST_STACK[this.CST_STACK.length-1];var r,i,s;i=t,s=e,void 0===(r=n).children[s]?r.children[s]=[i]:r.children[s].push(i),this.setNodeLocationFromToken(n.location,t)}cstPostNonTerminal(e,t){const n=this.CST_STACK[this.CST_STACK.length-1];!function(e,t,n){void 0===e.children[t]?e.children[t]=[n]:e.children[t].push(n)}(n,t,e),this.setNodeLocationFromNode(n.location,e.location)}getBaseCstVisitorConstructor(){if((0,Fn.A)(this.baseCstVisitorConstructor)){const e=Fs(this.className,(0,Kt.A)(this.gastProductionsCache));return this.baseCstVisitorConstructor=e,e}return this.baseCstVisitorConstructor}getBaseCstVisitorConstructorWithDefaults(){if((0,Fn.A)(this.baseCstVisitorWithDefaultsConstructor)){const e=function(e,t,n){const r=function(){};Ds(r,e+"BaseSemanticsWithDefaults");const i=Object.create(n.prototype);return(0,It.A)(t,(e=>{i[e]=Us})),(r.prototype=i).constructor=r,r}(this.className,(0,Kt.A)(this.gastProductionsCache),this.getBaseCstVisitorConstructor());return this.baseCstVisitorWithDefaultsConstructor=e,e}return this.baseCstVisitorWithDefaultsConstructor}getLastExplicitRuleShortName(){const e=this.RULE_STACK;return e[e.length-1]}getPreviousExplicitRuleShortName(){const e=this.RULE_STACK;return e[e.length-2]}getLastExplicitRuleOccurrenceIndex(){const e=this.RULE_OCCURRENCE_STACK;return e[e.length-1]}},class{initLexerAdapter(){this.tokVector=[],this.tokVectorLength=0,this.currIdx=-1}set input(e){if(!0!==this.selfAnalysisDone)throw Error("Missing <performSelfAnalysis> invocation at the end of the Parser's constructor.");this.reset(),this.tokVector=e,this.tokVectorLength=e.length}get input(){return this.tokVector}SKIP_TOKEN(){return this.currIdx<=this.tokVector.length-2?(this.consumeToken(),this.LA(1)):Js}LA(e){const t=this.currIdx+e;return t<0||this.tokVectorLength<=t?Js:this.tokVector[t]}consumeToken(){this.currIdx++}exportLexerState(){return this.currIdx}importLexerState(e){this.currIdx=e}resetLexerState(){this.currIdx=-1}moveToTerminatedState(){this.currIdx=this.tokVector.length-1}getLexerPosition(){return this.exportLexerState()}},class{initRecognizerEngine(e,t){if(this.className=this.constructor.name,this.shortRuleNameToFull={},this.fullRuleNameToShort={},this.ruleShortNameIdx=256,this.tokenMatcher=zr,this.subruleIdx=0,this.definedRulesNames=[],this.tokensMap={},this.isBackTrackingStack=[],this.RULE_STACK=[],this.RULE_OCCURRENCE_STACK=[],this.gastProductionsCache={},(0,$t.A)(t,"serializedGrammar"))throw Error("The Parser's configuration can no longer contain a <serializedGrammar> property.\n\tSee: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_6-0-0\n\tFor Further details.");if((0,vn.A)(e)){if((0,Nt.A)(e))throw Error("A Token Vocabulary cannot be empty.\n\tNote that the first argument for the parser constructor\n\tis no longer a Token vector (since v4.0).");if("number"==typeof e[0].startOffset)throw Error("The Parser constructor no longer accepts a token vector as the first argument.\n\tSee: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_4-0-0\n\tFor Further details.")}if((0,vn.A)(e))this.tokensMap=(0,Yn.A)(e,((e,t)=>(e[t.name]=t,e)),{});else if((0,$t.A)(e,"modes")&&Cn((0,Pn.A)((0,St.A)(e.modes)),ei)){const t=(0,Pn.A)((0,St.A)(e.modes)),n=_n(t);this.tokensMap=(0,Yn.A)(n,((e,t)=>(e[t.name]=t,e)),{})}else{if(!(0,Ks.A)(e))throw new Error("<tokensDictionary> argument must be An Array of Token constructors, A dictionary of Token constructors or an IMultiModeLexerDefinition");this.tokensMap=(0,wt.A)(e)}this.tokensMap.EOF=yi;const n=(0,$t.A)(e,"modes")?(0,Pn.A)((0,St.A)(e.modes)):(0,St.A)(e),r=Cn(n,(e=>(0,Nt.A)(e.categoryMatches)));this.tokenMatcher=r?zr:Wr,qr((0,St.A)(this.tokensMap))}defineRule(e,t,n){if(this.selfAnalysisDone)throw Error(`Grammar rule <${e}> may not be defined after the 'performSelfAnalysis' method has been called'\nMake sure that all grammar rule definitions are done before 'performSelfAnalysis' is called.`);const r=(0,$t.A)(n,"resyncEnabled")?n.resyncEnabled:eo.resyncEnabled,i=(0,$t.A)(n,"recoveryValueFunc")?n.recoveryValueFunc:eo.recoveryValueFunc,s=this.ruleShortNameIdx<<12;let o;return this.ruleShortNameIdx++,this.shortRuleNameToFull[s]=e,this.fullRuleNameToShort[e]=s,o=!0===this.outputCst?function(...n){try{this.ruleInvocationStateUpdate(s,e,this.subruleIdx),t.apply(this,n);const r=this.CST_STACK[this.CST_STACK.length-1];return this.cstPostRule(r),r}catch(o){return this.invokeRuleCatch(o,r,i)}finally{this.ruleFinallyStateUpdate()}}:function(...n){try{return this.ruleInvocationStateUpdate(s,e,this.subruleIdx),t.apply(this,n)}catch(o){return this.invokeRuleCatch(o,r,i)}finally{this.ruleFinallyStateUpdate()}},Object.assign(o,{ruleName:e,originalGrammarAction:t})}invokeRuleCatch(e,t,n){const r=1===this.RULE_STACK.length,i=t&&!this.isBackTracking()&&this.recoveryEnabled;if(As(e)){const t=e;if(i){const r=this.findReSyncTokenType();if(this.isInCurrentRuleReSyncSet(r)){if(t.resyncedTokens=this.reSyncTo(r),this.outputCst){const e=this.CST_STACK[this.CST_STACK.length-1];return e.recoveredNode=!0,e}return n(e)}if(this.outputCst){const e=this.CST_STACK[this.CST_STACK.length-1];e.recoveredNode=!0,t.partialCstResult=e}throw t}if(r)return this.moveToTerminatedState(),n(e);throw t}throw e}optionInternal(e,t){const n=this.getKeyForAutomaticLookahead(512,t);return this.optionInternalLogic(e,t,n)}optionInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof e){r=e.DEF;const t=e.GATE;if(void 0!==t){const e=i;i=()=>t.call(this)&&e.call(this)}}else r=e;if(!0===i.call(this))return r.call(this)}atLeastOneInternal(e,t){const n=this.getKeyForAutomaticLookahead(Cs,e);return this.atLeastOneInternalLogic(e,t,n)}atLeastOneInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof t){r=t.DEF;const e=t.GATE;if(void 0!==e){const t=i;i=()=>e.call(this)&&t.call(this)}}else r=t;if(!0!==i.call(this))throw this.raiseEarlyExitException(e,Bi.REPETITION_MANDATORY,t.ERR_MSG);{let e=this.doSingleRepetition(r);for(;!0===i.call(this)&&!0===e;)e=this.doSingleRepetition(r)}this.attemptInRepetitionRecovery(this.atLeastOneInternal,[e,t],i,Cs,e,Di)}atLeastOneSepFirstInternal(e,t){const n=this.getKeyForAutomaticLookahead(ws,e);this.atLeastOneSepFirstInternalLogic(e,t,n)}atLeastOneSepFirstInternalLogic(e,t,n){const r=t.DEF,i=t.SEP;if(!0!==this.getLaFuncFromCache(n).call(this))throw this.raiseEarlyExitException(e,Bi.REPETITION_MANDATORY_WITH_SEPARATOR,t.ERR_MSG);{r.call(this);const t=()=>this.tokenMatcher(this.LA(1),i);for(;!0===this.tokenMatcher(this.LA(1),i);)this.CONSUME(i),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,i,t,r,Ui],t,ws,e,Ui)}}manyInternal(e,t){const n=this.getKeyForAutomaticLookahead(768,e);return this.manyInternalLogic(e,t,n)}manyInternalLogic(e,t,n){let r,i=this.getLaFuncFromCache(n);if("function"!=typeof t){r=t.DEF;const e=t.GATE;if(void 0!==e){const t=i;i=()=>e.call(this)&&t.call(this)}}else r=t;let s=!0;for(;!0===i.call(this)&&!0===s;)s=this.doSingleRepetition(r);this.attemptInRepetitionRecovery(this.manyInternal,[e,t],i,768,e,Pi,s)}manySepFirstInternal(e,t){const n=this.getKeyForAutomaticLookahead($s,e);this.manySepFirstInternalLogic(e,t,n)}manySepFirstInternalLogic(e,t,n){const r=t.DEF,i=t.SEP;if(!0===this.getLaFuncFromCache(n).call(this)){r.call(this);const t=()=>this.tokenMatcher(this.LA(1),i);for(;!0===this.tokenMatcher(this.LA(1),i);)this.CONSUME(i),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,i,t,r,Mi],t,$s,e,Mi)}}repetitionSepSecondInternal(e,t,n,r,i){for(;n();)this.CONSUME(t),r.call(this);this.attemptInRepetitionRecovery(this.repetitionSepSecondInternal,[e,t,n,r,i],n,ws,e,i)}doSingleRepetition(e){const t=this.getLexerPosition();return e.call(this),this.getLexerPosition()>t}orInternal(e,t){const n=this.getKeyForAutomaticLookahead(256,t),r=(0,vn.A)(e)?e:e.DEF,i=this.getLaFuncFromCache(n).call(this,r);if(void 0!==i)return r[i].ALT.call(this);this.raiseNoAltException(t,e.ERR_MSG)}ruleFinallyStateUpdate(){if(this.RULE_STACK.pop(),this.RULE_OCCURRENCE_STACK.pop(),this.cstFinallyStateUpdate(),0===this.RULE_STACK.length&&!1===this.isAtEndOfInput()){const e=this.LA(1),t=this.errorMessageProvider.buildNotAllInputParsedMessage({firstRedundant:e,ruleName:this.getCurrRuleFullName()});this.SAVE_ERROR(new Es(t,e))}}subruleInternal(e,t,n){let r;try{const i=void 0!==n?n.ARGS:void 0;return this.subruleIdx=t,r=e.apply(this,i),this.cstPostNonTerminal(r,void 0!==n&&void 0!==n.LABEL?n.LABEL:e.ruleName),r}catch(i){throw this.subruleInternalError(i,n,e.ruleName)}}subruleInternalError(e,t,n){throw As(e)&&void 0!==e.partialCstResult&&(this.cstPostNonTerminal(e.partialCstResult,void 0!==t&&void 0!==t.LABEL?t.LABEL:n),delete e.partialCstResult),e}consumeInternal(e,t,n){let r;try{const t=this.LA(1);!0===this.tokenMatcher(t,e)?(this.consumeToken(),r=t):this.consumeInternalError(e,t,n)}catch(i){r=this.consumeInternalRecovery(e,t,i)}return this.cstPostTerminal(void 0!==n&&void 0!==n.LABEL?n.LABEL:e.name,r),r}consumeInternalError(e,t,n){let r;const i=this.LA(0);throw r=void 0!==n&&n.ERR_MSG?n.ERR_MSG:this.errorMessageProvider.buildMismatchTokenMessage({expected:e,actual:t,previous:i,ruleName:this.getCurrRuleFullName()}),this.SAVE_ERROR(new vs(r,t,i))}consumeInternalRecovery(e,t,n){if(!this.recoveryEnabled||"MismatchedTokenException"!==n.name||this.isBackTracking())throw n;{const i=this.getFollowsForInRuleRecovery(e,t);try{return this.tryInRuleRecovery(e,i)}catch(r){throw r.name===Is?n:r}}}saveRecogState(){const e=this.errors,t=(0,wt.A)(this.RULE_STACK);return{errors:e,lexerState:this.exportLexerState(),RULE_STACK:t,CST_STACK:this.CST_STACK}}reloadRecogState(e){this.errors=e.errors,this.importLexerState(e.lexerState),this.RULE_STACK=e.RULE_STACK}ruleInvocationStateUpdate(e,t,n){this.RULE_OCCURRENCE_STACK.push(n),this.RULE_STACK.push(e),this.cstInvocationStateUpdate(t)}isBackTracking(){return 0!==this.isBackTrackingStack.length}getCurrRuleFullName(){const e=this.getLastExplicitRuleShortName();return this.shortRuleNameToFull[e]}shortRuleNameToFullName(e){return this.shortRuleNameToFull[e]}isAtEndOfInput(){return this.tokenMatcher(this.LA(1),yi)}reset(){this.resetLexerState(),this.subruleIdx=0,this.isBackTrackingStack=[],this.errors=[],this.RULE_STACK=[],this.CST_STACK=[],this.RULE_OCCURRENCE_STACK=[]}},class{ACTION(e){return e.call(this)}consume(e,t,n){return this.consumeInternal(t,e,n)}subrule(e,t,n){return this.subruleInternal(t,e,n)}option(e,t){return this.optionInternal(t,e)}or(e,t){return this.orInternal(t,e)}many(e,t){return this.manyInternal(e,t)}atLeastOne(e,t){return this.atLeastOneInternal(e,t)}CONSUME(e,t){return this.consumeInternal(e,0,t)}CONSUME1(e,t){return this.consumeInternal(e,1,t)}CONSUME2(e,t){return this.consumeInternal(e,2,t)}CONSUME3(e,t){return this.consumeInternal(e,3,t)}CONSUME4(e,t){return this.consumeInternal(e,4,t)}CONSUME5(e,t){return this.consumeInternal(e,5,t)}CONSUME6(e,t){return this.consumeInternal(e,6,t)}CONSUME7(e,t){return this.consumeInternal(e,7,t)}CONSUME8(e,t){return this.consumeInternal(e,8,t)}CONSUME9(e,t){return this.consumeInternal(e,9,t)}SUBRULE(e,t){return this.subruleInternal(e,0,t)}SUBRULE1(e,t){return this.subruleInternal(e,1,t)}SUBRULE2(e,t){return this.subruleInternal(e,2,t)}SUBRULE3(e,t){return this.subruleInternal(e,3,t)}SUBRULE4(e,t){return this.subruleInternal(e,4,t)}SUBRULE5(e,t){return this.subruleInternal(e,5,t)}SUBRULE6(e,t){return this.subruleInternal(e,6,t)}SUBRULE7(e,t){return this.subruleInternal(e,7,t)}SUBRULE8(e,t){return this.subruleInternal(e,8,t)}SUBRULE9(e,t){return this.subruleInternal(e,9,t)}OPTION(e){return this.optionInternal(e,0)}OPTION1(e){return this.optionInternal(e,1)}OPTION2(e){return this.optionInternal(e,2)}OPTION3(e){return this.optionInternal(e,3)}OPTION4(e){return this.optionInternal(e,4)}OPTION5(e){return this.optionInternal(e,5)}OPTION6(e){return this.optionInternal(e,6)}OPTION7(e){return this.optionInternal(e,7)}OPTION8(e){return this.optionInternal(e,8)}OPTION9(e){return this.optionInternal(e,9)}OR(e){return this.orInternal(e,0)}OR1(e){return this.orInternal(e,1)}OR2(e){return this.orInternal(e,2)}OR3(e){return this.orInternal(e,3)}OR4(e){return this.orInternal(e,4)}OR5(e){return this.orInternal(e,5)}OR6(e){return this.orInternal(e,6)}OR7(e){return this.orInternal(e,7)}OR8(e){return this.orInternal(e,8)}OR9(e){return this.orInternal(e,9)}MANY(e){this.manyInternal(0,e)}MANY1(e){this.manyInternal(1,e)}MANY2(e){this.manyInternal(2,e)}MANY3(e){this.manyInternal(3,e)}MANY4(e){this.manyInternal(4,e)}MANY5(e){this.manyInternal(5,e)}MANY6(e){this.manyInternal(6,e)}MANY7(e){this.manyInternal(7,e)}MANY8(e){this.manyInternal(8,e)}MANY9(e){this.manyInternal(9,e)}MANY_SEP(e){this.manySepFirstInternal(0,e)}MANY_SEP1(e){this.manySepFirstInternal(1,e)}MANY_SEP2(e){this.manySepFirstInternal(2,e)}MANY_SEP3(e){this.manySepFirstInternal(3,e)}MANY_SEP4(e){this.manySepFirstInternal(4,e)}MANY_SEP5(e){this.manySepFirstInternal(5,e)}MANY_SEP6(e){this.manySepFirstInternal(6,e)}MANY_SEP7(e){this.manySepFirstInternal(7,e)}MANY_SEP8(e){this.manySepFirstInternal(8,e)}MANY_SEP9(e){this.manySepFirstInternal(9,e)}AT_LEAST_ONE(e){this.atLeastOneInternal(0,e)}AT_LEAST_ONE1(e){return this.atLeastOneInternal(1,e)}AT_LEAST_ONE2(e){this.atLeastOneInternal(2,e)}AT_LEAST_ONE3(e){this.atLeastOneInternal(3,e)}AT_LEAST_ONE4(e){this.atLeastOneInternal(4,e)}AT_LEAST_ONE5(e){this.atLeastOneInternal(5,e)}AT_LEAST_ONE6(e){this.atLeastOneInternal(6,e)}AT_LEAST_ONE7(e){this.atLeastOneInternal(7,e)}AT_LEAST_ONE8(e){this.atLeastOneInternal(8,e)}AT_LEAST_ONE9(e){this.atLeastOneInternal(9,e)}AT_LEAST_ONE_SEP(e){this.atLeastOneSepFirstInternal(0,e)}AT_LEAST_ONE_SEP1(e){this.atLeastOneSepFirstInternal(1,e)}AT_LEAST_ONE_SEP2(e){this.atLeastOneSepFirstInternal(2,e)}AT_LEAST_ONE_SEP3(e){this.atLeastOneSepFirstInternal(3,e)}AT_LEAST_ONE_SEP4(e){this.atLeastOneSepFirstInternal(4,e)}AT_LEAST_ONE_SEP5(e){this.atLeastOneSepFirstInternal(5,e)}AT_LEAST_ONE_SEP6(e){this.atLeastOneSepFirstInternal(6,e)}AT_LEAST_ONE_SEP7(e){this.atLeastOneSepFirstInternal(7,e)}AT_LEAST_ONE_SEP8(e){this.atLeastOneSepFirstInternal(8,e)}AT_LEAST_ONE_SEP9(e){this.atLeastOneSepFirstInternal(9,e)}RULE(e,t,n=eo){if(In(this.definedRulesNames,e)){const t={message:Ei.buildDuplicateRuleNameError({topLevelRule:e,grammarName:this.className}),type:to.DUPLICATE_RULE_NAME,ruleName:e};this.definitionErrors.push(t)}this.definedRulesNames.push(e);const r=this.defineRule(e,t,n);return this[e]=r,r}OVERRIDE_RULE(e,t,n=eo){const r=function(e,t,n){const r=[];let i;return In(t,e)||(i=`Invalid rule override, rule: ->${e}<- cannot be overridden in the grammar: ->${n}<-as it is not defined in any of the super grammars `,r.push({message:i,type:to.INVALID_RULE_OVERRIDE,ruleName:e})),r}(e,this.definedRulesNames,this.className);this.definitionErrors=this.definitionErrors.concat(r);const i=this.defineRule(e,t,n);return this[e]=i,i}BACKTRACK(e,t){return function(){this.isBackTrackingStack.push(1);const n=this.saveRecogState();try{return e.apply(this,t),!0}catch(r){if(As(r))return!1;throw r}finally{this.reloadRecogState(n),this.isBackTrackingStack.pop()}}}getGAstProductions(){return this.gastProductionsCache}getSerializedGastProductions(){return e=(0,St.A)(this.gastProductionsCache),(0,Ct.A)(e,mn);var e}},class{initErrorHandler(e){this._errors=[],this.errorMessageProvider=(0,$t.A)(e,"errorMessageProvider")?e.errorMessageProvider:Zs.errorMessageProvider}SAVE_ERROR(e){if(As(e))return e.context={ruleStack:this.getHumanReadableRuleStack(),ruleOccurrenceStack:(0,wt.A)(this.RULE_OCCURRENCE_STACK)},this._errors.push(e),e;throw Error("Trying to save an Error which is not a RecognitionException")}get errors(){return(0,wt.A)(this._errors)}set errors(e){this._errors=e}raiseEarlyExitException(e,t,n){const r=this.getCurrRuleFullName(),i=es(e,this.getGAstProductions()[r],t,this.maxLookahead)[0],s=[];for(let a=1;a<=this.maxLookahead;a++)s.push(this.LA(a));const o=this.errorMessageProvider.buildEarlyExitMessage({expectedIterationPaths:i,actual:s,previous:this.LA(0),customUserDescription:n,ruleName:r});throw this.SAVE_ERROR(new ks(o,this.LA(1),this.LA(0)))}raiseNoAltException(e,t){const n=this.getCurrRuleFullName(),r=Zi(e,this.getGAstProductions()[n],this.maxLookahead),i=[];for(let a=1;a<=this.maxLookahead;a++)i.push(this.LA(a));const s=this.LA(0),o=this.errorMessageProvider.buildNoViableAltMessage({expectedPathsPerAlt:r,actual:i,previous:s,customUserDescription:t,ruleName:this.getCurrRuleFullName()});throw this.SAVE_ERROR(new Rs(o,this.LA(1),s))}},class{initContentAssist(){}computeContentAssist(e,t){const n=this.gastProductionsCache[e];if((0,Fn.A)(n))throw Error(`Rule ->${e}<- does not exist in this grammar.`);return Gi([n],t,this.tokenMatcher,this.maxLookahead)}getNextPossibleTokenTypes(e){const t=or(e.ruleStack),n=this.getGAstProductions()[t];return new bi(n,e).startWalking()}},class{initGastRecorder(e){this.recordingProdStack=[],this.RECORDING_PHASE=!1}enableRecording(){this.RECORDING_PHASE=!0,this.TRACE_INIT("Enable Recording",(()=>{for(let e=0;e<10;e++){const t=e>0?e:"";this[`CONSUME${t}`]=function(t,n){return this.consumeInternalRecord(t,e,n)},this[`SUBRULE${t}`]=function(t,n){return this.subruleInternalRecord(t,e,n)},this[`OPTION${t}`]=function(t){return this.optionInternalRecord(t,e)},this[`OR${t}`]=function(t){return this.orInternalRecord(t,e)},this[`MANY${t}`]=function(t){this.manyInternalRecord(e,t)},this[`MANY_SEP${t}`]=function(t){this.manySepFirstInternalRecord(e,t)},this[`AT_LEAST_ONE${t}`]=function(t){this.atLeastOneInternalRecord(e,t)},this[`AT_LEAST_ONE_SEP${t}`]=function(t){this.atLeastOneSepFirstInternalRecord(e,t)}}this.consume=function(e,t,n){return this.consumeInternalRecord(t,e,n)},this.subrule=function(e,t,n){return this.subruleInternalRecord(t,e,n)},this.option=function(e,t){return this.optionInternalRecord(t,e)},this.or=function(e,t){return this.orInternalRecord(t,e)},this.many=function(e,t){this.manyInternalRecord(e,t)},this.atLeastOne=function(e,t){this.atLeastOneInternalRecord(e,t)},this.ACTION=this.ACTION_RECORD,this.BACKTRACK=this.BACKTRACK_RECORD,this.LA=this.LA_RECORD}))}disableRecording(){this.RECORDING_PHASE=!1,this.TRACE_INIT("Deleting Recording methods",(()=>{const e=this;for(let t=0;t<10;t++){const n=t>0?t:"";delete e[`CONSUME${n}`],delete e[`SUBRULE${n}`],delete e[`OPTION${n}`],delete e[`OR${n}`],delete e[`MANY${n}`],delete e[`MANY_SEP${n}`],delete e[`AT_LEAST_ONE${n}`],delete e[`AT_LEAST_ONE_SEP${n}`]}delete e.consume,delete e.subrule,delete e.option,delete e.or,delete e.many,delete e.atLeastOne,delete e.ACTION,delete e.BACKTRACK,delete e.LA}))}ACTION_RECORD(e){}BACKTRACK_RECORD(e,t){return()=>!0}LA_RECORD(e){return Js}topLevelRuleRecord(e,t){try{const n=new on({definition:[],name:e});return n.name=e,this.recordingProdStack.push(n),t.call(this),this.recordingProdStack.pop(),n}catch(n){if(!0!==n.KNOWN_RECORDER_ERROR)try{n.message=n.message+'\n\t This error was thrown during the "grammar recording phase" For more info see:\n\thttps://chevrotain.io/docs/guide/internals.html#grammar-recording'}catch(r){throw n}throw n}}optionInternalRecord(e,t){return Ys.call(this,cn,e,t)}atLeastOneInternalRecord(e,t){Ys.call(this,ln,t,e)}atLeastOneSepFirstInternalRecord(e,t){Ys.call(this,un,t,e,js)}manyInternalRecord(e,t){Ys.call(this,dn,t,e)}manySepFirstInternalRecord(e,t){Ys.call(this,hn,t,e,js)}orInternalRecord(e,t){return Xs.call(this,e,t)}subruleInternalRecord(e,t,n){if(Qs(t),!e||!1===(0,$t.A)(e,"ruleName")){const n=new Error(`<SUBRULE${qs(t)}> argument is invalid expecting a Parser method reference but got: <${JSON.stringify(e)}>\n inside top level rule: <${this.recordingProdStack[0].name}>`);throw n.KNOWN_RECORDER_ERROR=!0,n}const r=(0,Vr.A)(this.recordingProdStack),i=e.ruleName,s=new sn({idx:t,nonTerminalName:i,label:null==n?void 0:n.LABEL,referencedRule:void 0});return r.definition.push(s),this.outputCst?zs:Bs}consumeInternalRecord(e,t,n){if(Qs(t),!Jr(e)){const n=new Error(`<CONSUME${qs(t)}> argument is invalid expecting a TokenType reference but got: <${JSON.stringify(e)}>\n inside top level rule: <${this.recordingProdStack[0].name}>`);throw n.KNOWN_RECORDER_ERROR=!0,n}const r=(0,Vr.A)(this.recordingProdStack),i=new pn({idx:t,terminalType:e,label:null==n?void 0:n.LABEL});return r.definition.push(i),Ws}},class{initPerformanceTracer(e){if((0,$t.A)(e,"traceInitPerf")){const t=e.traceInitPerf,n="number"==typeof t;this.traceInitMaxIdent=n?t:1/0,this.traceInitPerf=n?t>0:t}else this.traceInitMaxIdent=0,this.traceInitPerf=Zs.traceInitPerf;this.traceInitIndent=-1}TRACE_INIT(e,t){if(!0===this.traceInitPerf){this.traceInitIndent++;const n=new Array(this.traceInitIndent+1).join("\t");this.traceInitIndent<this.traceInitMaxIdent&&console.log(`${n}--\x3e <${e}>`);const{time:r,value:i}=Hr(t),s=r>10?console.warn:console.log;return this.traceInitIndent<this.traceInitMaxIdent&&s(`${n}<-- <${e}> time: ${r}ms`),this.traceInitIndent--,i}return t()}}],ro.forEach((e=>{const t=e.prototype;Object.getOwnPropertyNames(t).forEach((n=>{if("constructor"===n)return;const r=Object.getOwnPropertyDescriptor(t,n);r&&(r.get||r.set)?Object.defineProperty(no.prototype,n,r):no.prototype[n]=e.prototype[n]}))}));class oo extends so{constructor(e,t=Zs){const n=(0,wt.A)(t);n.outputCst=!1,super(e,n)}}function ao(e,t,n){return`${e.name}_${t}_${n}`}const co=1,lo=2,uo=4,ho=5,fo=7,po=8,mo=9,go=10,yo=11,Ao=12;class To{constructor(e){this.target=e}isEpsilon(){return!1}}class vo extends To{constructor(e,t){super(e),this.tokenType=t}}class Ro extends To{constructor(e){super(e)}isEpsilon(){return!0}}class Eo extends To{constructor(e,t,n){super(e),this.rule=t,this.followState=n}isEpsilon(){return!0}}function ko(e){const t={decisionMap:{},decisionStates:[],ruleToStartState:new Map,ruleToStopState:new Map,states:[]};!function(e,t){const n=t.length;for(let r=0;r<n;r++){const n=t[r],i=bo(e,n,void 0,{type:lo}),s=bo(e,n,void 0,{type:fo});i.stop=s,e.ruleToStartState.set(n,i),e.ruleToStopState.set(n,s)}}(t,e);const n=e.length;for(let r=0;r<n;r++){const n=e[r],i=Io(t,n,n);void 0!==i&&Lo(t,n,i)}return t}function xo(e,t,n){return n instanceof pn?wo(e,t,n.terminalType,n):n instanceof sn?function(e,t,n){const r=n.referencedRule,i=e.ruleToStartState.get(r),s=bo(e,t,n,{type:co}),o=bo(e,t,n,{type:co}),a=new Eo(i,r,o);return _o(s,a),{left:s,right:o}}(e,t,n):n instanceof fn?function(e,t,n){const r=bo(e,t,n,{type:co});Co(e,r);const i=(0,Ct.A)(n.definition,(n=>xo(e,t,n))),s=$o(e,t,r,n,...i);return s}(e,t,n):n instanceof cn?function(e,t,n){const r=bo(e,t,n,{type:co});Co(e,r);const i=$o(e,t,r,n,Io(e,t,n));return function(e,t,n,r){const i=r.left,s=r.right;return Oo(i,s),e.decisionMap[ao(t,"Option",n.idx)]=i,r}(e,t,n,i)}(e,t,n):n instanceof dn?function(e,t,n){const r=bo(e,t,n,{type:ho});Co(e,r);const i=$o(e,t,r,n,Io(e,t,n));return No(e,t,n,i)}(e,t,n):n instanceof hn?function(e,t,n){const r=bo(e,t,n,{type:ho});Co(e,r);const i=$o(e,t,r,n,Io(e,t,n)),s=wo(e,t,n.separator,n);return No(e,t,n,i,s)}(e,t,n):n instanceof ln?function(e,t,n){const r=bo(e,t,n,{type:uo});Co(e,r);const i=$o(e,t,r,n,Io(e,t,n));return So(e,t,n,i)}(e,t,n):n instanceof un?function(e,t,n){const r=bo(e,t,n,{type:uo});Co(e,r);const i=$o(e,t,r,n,Io(e,t,n)),s=wo(e,t,n.separator,n);return So(e,t,n,i,s)}(e,t,n):Io(e,t,n)}function Io(e,t,n){const r=(0,Xn.A)((0,Ct.A)(n.definition,(n=>xo(e,t,n))),(e=>void 0!==e));return 1===r.length?r[0]:0===r.length?void 0:function(e,t){const n=t.length;for(let s=0;s<n-1;s++){const n=t[s];let r;1===n.left.transitions.length&&(r=n.left.transitions[0]);const i=r instanceof Eo,o=r,a=t[s+1].left;n.left.type===co&&n.right.type===co&&void 0!==r&&(i&&o.followState===n.right||r.target===n.right)?(i?o.followState=a:r.target=a,Po(e,n.right)):Oo(n.right,a)}const r=t[0],i=t[n-1];return{left:r.left,right:i.right}}(e,r)}function So(e,t,n,r,i){const s=r.left,o=r.right,a=bo(e,t,n,{type:yo});Co(e,a);const c=bo(e,t,n,{type:Ao});return s.loopback=a,c.loopback=a,e.decisionMap[ao(t,i?"RepetitionMandatoryWithSeparator":"RepetitionMandatory",n.idx)]=a,Oo(o,a),void 0===i?(Oo(a,s),Oo(a,c)):(Oo(a,c),Oo(a,i.left),Oo(i.right,s)),{left:s,right:c}}function No(e,t,n,r,i){const s=r.left,o=r.right,a=bo(e,t,n,{type:go});Co(e,a);const c=bo(e,t,n,{type:Ao}),l=bo(e,t,n,{type:mo});return a.loopback=l,c.loopback=l,Oo(a,s),Oo(a,c),Oo(o,l),void 0!==i?(Oo(l,c),Oo(l,i.left),Oo(i.right,s)):Oo(l,a),e.decisionMap[ao(t,i?"RepetitionWithSeparator":"Repetition",n.idx)]=a,{left:a,right:c}}function Co(e,t){return e.decisionStates.push(t),t.decision=e.decisionStates.length-1,t.decision}function $o(e,t,n,r,...i){const s=bo(e,t,r,{type:po,start:n});n.end=s;for(const a of i)void 0!==a?(Oo(n,a.left),Oo(a.right,s)):Oo(n,s);const o={left:n,right:s};return e.decisionMap[ao(t,function(e){if(e instanceof fn)return"Alternation";if(e instanceof cn)return"Option";if(e instanceof dn)return"Repetition";if(e instanceof hn)return"RepetitionWithSeparator";if(e instanceof ln)return"RepetitionMandatory";if(e instanceof un)return"RepetitionMandatoryWithSeparator";throw new Error("Invalid production type encountered")}(r),r.idx)]=n,o}function wo(e,t,n,r){const i=bo(e,t,r,{type:co}),s=bo(e,t,r,{type:co});return _o(i,new vo(s,n)),{left:i,right:s}}function Lo(e,t,n){const r=e.ruleToStartState.get(t);Oo(r,n.left);const i=e.ruleToStopState.get(t);Oo(n.right,i);return{left:r,right:i}}function Oo(e,t){_o(e,new Ro(t))}function bo(e,t,n,r){const i=Object.assign({atn:e,production:n,epsilonOnlyTransitions:!1,rule:t,transitions:[],nextTokenWithinRule:[],stateNumber:e.states.length},r);return e.states.push(i),i}function _o(e,t){0===e.transitions.length&&(e.epsilonOnlyTransitions=t.isEpsilon()),e.transitions.push(t)}function Po(e,t){e.states.splice(e.states.indexOf(t),1)}const Mo={};class Do{constructor(){this.map={},this.configs=[]}get size(){return this.configs.length}finalize(){this.map={}}add(e){const t=Uo(e);t in this.map||(this.map[t]=this.configs.length,this.configs.push(e))}get elements(){return this.configs}get alts(){return(0,Ct.A)(this.configs,(e=>e.alt))}get key(){let e="";for(const t in this.map)e+=t+":";return e}}function Uo(e,t=!0){return`${t?`a${e.alt}`:""}s${e.state.stateNumber}:${e.stack.map((e=>e.stateNumber.toString())).join("_")}`}var Fo=n(86452);const Go=function(e,t){return e&&e.length?(0,bn.A)(e,(0,Ht.A)(t,2)):[]};function Ko(e,t){const n={};return r=>{const i=r.toString();let s=n[i];return void 0!==s||(s={atnStartState:e,decision:t,states:{}},n[i]=s),s}}class Bo{constructor(){this.predicates=[]}is(e){return e>=this.predicates.length||this.predicates[e]}set(e,t){this.predicates[e]=t}toString(){let e="";const t=this.predicates.length;for(let n=0;n<t;n++)e+=!0===this.predicates[n]?"1":"0";return e}}const jo=new Bo;class Vo extends Os{constructor(e){var t;super(),this.logging=null!==(t=null==e?void 0:e.logging)&&void 0!==t?t:e=>console.log(e)}initialize(e){this.atn=ko(e.rules),this.dfas=function(e){const t=e.decisionStates.length,n=Array(t);for(let r=0;r<t;r++)n[r]=Ko(e.decisionStates[r],r);return n}(this.atn)}validateAmbiguousAlternationAlternatives(){return[]}validateEmptyOrAlternatives(){return[]}buildLookaheadForAlternation(e){const{prodOccurrence:t,rule:n,hasPredicates:r,dynamicTokensEnabled:i}=e,s=this.dfas,o=this.logging,a=ao(n,"Alternation",t),c=this.atn.decisionMap[a].decision,l=(0,Ct.A)(Vi({maxLookahead:1,occurrence:t,prodType:"Alternation",rule:n}),(e=>(0,Ct.A)(e,(e=>e[0]))));if(Ho(l,!1)&&!i){const e=(0,Yn.A)(l,((e,t,n)=>((0,It.A)(t,(t=>{t&&(e[t.tokenTypeIdx]=n,(0,It.A)(t.categoryMatches,(t=>{e[t]=n})))})),e)),{});return r?function(t){var n;const r=this.LA(1),i=e[r.tokenTypeIdx];if(void 0!==t&&void 0!==i){const e=null===(n=t[i])||void 0===n?void 0:n.GATE;if(void 0!==e&&!1===e.call(this))return}return i}:function(){const t=this.LA(1);return e[t.tokenTypeIdx]}}return r?function(e){const t=new Bo,n=void 0===e?0:e.length;for(let i=0;i<n;i++){const n=null==e?void 0:e[i].GATE;t.set(i,void 0===n||n.call(this))}const r=Wo.call(this,s,c,t,o);return"number"==typeof r?r:void 0}:function(){const e=Wo.call(this,s,c,jo,o);return"number"==typeof e?e:void 0}}buildLookaheadForOptional(e){const{prodOccurrence:t,rule:n,prodType:r,dynamicTokensEnabled:i}=e,s=this.dfas,o=this.logging,a=ao(n,r,t),c=this.atn.decisionMap[a].decision,l=(0,Ct.A)(Vi({maxLookahead:1,occurrence:t,prodType:r,rule:n}),(e=>(0,Ct.A)(e,(e=>e[0]))));if(Ho(l)&&l[0][0]&&!i){const e=l[0],t=(0,Pn.A)(e);if(1===t.length&&(0,Nt.A)(t[0].categoryMatches)){const e=t[0].tokenTypeIdx;return function(){return this.LA(1).tokenTypeIdx===e}}{const e=(0,Yn.A)(t,((e,t)=>(void 0!==t&&(e[t.tokenTypeIdx]=!0,(0,It.A)(t.categoryMatches,(t=>{e[t]=!0}))),e)),{});return function(){const t=this.LA(1);return!0===e[t.tokenTypeIdx]}}}return function(){const e=Wo.call(this,s,c,jo,o);return"object"!=typeof e&&0===e}}}function Ho(e,t=!0){const n=new Set;for(const r of e){const e=new Set;for(const i of r){if(void 0===i){if(t)break;return!1}const r=[i.tokenTypeIdx].concat(i.categoryMatches);for(const t of r)if(n.has(t)){if(!e.has(t))return!1}else n.add(t),e.add(t)}}return!0}function Wo(e,t,n,r){const i=e[t](n);let s=i.start;if(void 0===s){s=ea(i,Jo(ta(i.atnStartState))),i.start=s}return zo.apply(this,[i,s,n,r])}function zo(e,t,n,r){let i=t,s=1;const o=[];let a=this.LA(s++);for(;;){let t=(c=a,i.edges[c.tokenTypeIdx]);if(void 0===t&&(t=Yo.apply(this,[e,i,a,s,n,r])),t===Mo)return qo(o,i,a);if(!0===t.isAcceptState)return t.prediction;i=t,o.push(a),a=this.LA(s++)}var c}function Yo(e,t,n,r,i,s){const o=function(e,t,n){const r=new Do,i=[];for(const o of e.elements){if(!1===n.is(o.alt))continue;if(o.state.type===fo){i.push(o);continue}const e=o.state.transitions.length;for(let n=0;n<e;n++){const e=Qo(o.state.transitions[n],t);void 0!==e&&r.add({state:e,alt:o.alt,stack:o.stack})}}let s;0===i.length&&1===r.size&&(s=r);if(void 0===s){s=new Do;for(const e of r.elements)na(e,s)}if(i.length>0&&!function(e){for(const t of e.elements)if(t.state.type===fo)return!0;return!1}(s))for(const o of i)s.add(o);return s}(t.configs,n,i);if(0===o.size)return Zo(e,t,n,Mo),Mo;let a=Jo(o);const c=function(e,t){let n;for(const r of e.elements)if(!0===t.is(r.alt))if(void 0===n)n=r.alt;else if(n!==r.alt)return;return n}(o,i);if(void 0!==c)a.isAcceptState=!0,a.prediction=c,a.configs.uniqueAlt=c;else if(function(e){if(function(e){for(const t of e.elements)if(t.state.type!==fo)return!1;return!0}(e))return!0;const t=function(e){const t=new Map;for(const n of e){const e=Uo(n,!1);let r=t.get(e);void 0===r&&(r={},t.set(e,r)),r[n.alt]=!0}return t}(e.elements);return function(e){for(const t of Array.from(e.values()))if(Object.keys(t).length>1)return!0;return!1}(t)&&!function(e){for(const t of Array.from(e.values()))if(1===Object.keys(t).length)return!0;return!1}(t)}(o)){const t=(0,Fo.A)(o.alts);a.isAcceptState=!0,a.prediction=t,a.configs.uniqueAlt=t,Xo.apply(this,[e,r,o.alts,s])}return a=Zo(e,t,n,a),a}function Xo(e,t,n,r){const i=[];for(let o=1;o<=t;o++)i.push(this.LA(o).tokenType);const s=e.atnStartState;r(function(e){const t=(0,Ct.A)(e.prefixPath,(e=>si(e))).join(", "),n=0===e.production.idx?"":e.production.idx;let r=`Ambiguous Alternatives Detected: <${e.ambiguityIndices.join(", ")}> in <${function(e){if(e instanceof sn)return"SUBRULE";if(e instanceof cn)return"OPTION";if(e instanceof fn)return"OR";if(e instanceof ln)return"AT_LEAST_ONE";if(e instanceof un)return"AT_LEAST_ONE_SEP";if(e instanceof hn)return"MANY_SEP";if(e instanceof dn)return"MANY";if(e instanceof pn)return"CONSUME";throw Error("non exhaustive match")}(e.production)}${n}> inside <${e.topLevelRule.name}> Rule,\n<${t}> may appears as a prefix path in all these alternatives.\n`;return r+="See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\nFor Further details.",r}({topLevelRule:s.rule,ambiguityIndices:n,production:s.production,prefixPath:i}))}function qo(e,t,n){const r=xi(t.configs.elements,(e=>e.state.transitions));return{actualToken:n,possibleTokenTypes:Go(r.filter((e=>e instanceof vo)).map((e=>e.tokenType)),(e=>e.tokenTypeIdx)),tokenPath:e}}function Qo(e,t){if(e instanceof vo&&Ti(t,e.tokenType))return e.target}function Jo(e){return{configs:e,edges:{},isAcceptState:!1,prediction:-1}}function Zo(e,t,n,r){return r=ea(e,r),t.edges[n.tokenTypeIdx]=r,r}function ea(e,t){if(t===Mo)return t;const n=t.configs.key,r=e.states[n];return void 0!==r?r:(t.configs.finalize(),e.states[n]=t,t)}function ta(e){const t=new Do,n=e.transitions.length;for(let r=0;r<n;r++){na({state:e.transitions[r].target,alt:r,stack:[]},t)}return t}function na(e,t){const n=e.state;if(n.type===fo){if(e.stack.length>0){const n=[...e.stack];na({state:n.pop(),alt:e.alt,stack:n},t)}else t.add(e);return}n.epsilonOnlyTransitions||t.add(e);const r=n.transitions.length;for(let i=0;i<r;i++){const r=ra(e,n.transitions[i]);void 0!==r&&na(r,t)}}function ra(e,t){if(t instanceof Ro)return{state:t.target,alt:e.alt,stack:e.stack};if(t instanceof Eo){const n=[...e.stack,t.followState];return{state:t.target,alt:e.alt,stack:n}}}var ia,sa,oa,aa,ca,la,ua,da,ha,fa,pa,ma,ga,ya,Aa,Ta,va,Ra,Ea,ka,xa,Ia,Sa,Na,Ca,$a,wa,La,Oa,ba,_a,Pa,Ma,Da,Ua,Fa,Ga,Ka,Ba,ja,Va,Ha,Wa,za,Ya,Xa,qa,Qa,Ja,Za,ec,tc,nc,rc,ic,sc,oc,ac,cc,lc,uc,dc,hc,fc,pc,mc,gc,yc,Ac,Tc,vc,Rc,Ec,kc,xc,Ic,Sc,Nc;!function(e){e.is=function(e){return"string"==typeof e}}(ia||(ia={})),function(e){e.is=function(e){return"string"==typeof e}}(sa||(sa={})),function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647,e.is=function(t){return"number"==typeof t&&e.MIN_VALUE<=t&&t<=e.MAX_VALUE}}(oa||(oa={})),function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647,e.is=function(t){return"number"==typeof t&&e.MIN_VALUE<=t&&t<=e.MAX_VALUE}}(aa||(aa={})),function(e){e.create=function(e,t){return e===Number.MAX_VALUE&&(e=aa.MAX_VALUE),t===Number.MAX_VALUE&&(t=aa.MAX_VALUE),{line:e,character:t}},e.is=function(e){let t=e;return $c.objectLiteral(t)&&$c.uinteger(t.line)&&$c.uinteger(t.character)}}(ca||(ca={})),function(e){e.create=function(e,t,n,r){if($c.uinteger(e)&&$c.uinteger(t)&&$c.uinteger(n)&&$c.uinteger(r))return{start:ca.create(e,t),end:ca.create(n,r)};if(ca.is(e)&&ca.is(t))return{start:e,end:t};throw new Error(`Range#create called with invalid arguments[${e}, ${t}, ${n}, ${r}]`)},e.is=function(e){let t=e;return $c.objectLiteral(t)&&ca.is(t.start)&&ca.is(t.end)}}(la||(la={})),function(e){e.create=function(e,t){return{uri:e,range:t}},e.is=function(e){let t=e;return $c.objectLiteral(t)&&la.is(t.range)&&($c.string(t.uri)||$c.undefined(t.uri))}}(ua||(ua={})),function(e){e.create=function(e,t,n,r){return{targetUri:e,targetRange:t,targetSelectionRange:n,originSelectionRange:r}},e.is=function(e){let t=e;return $c.objectLiteral(t)&&la.is(t.targetRange)&&$c.string(t.targetUri)&&la.is(t.targetSelectionRange)&&(la.is(t.originSelectionRange)||$c.undefined(t.originSelectionRange))}}(da||(da={})),function(e){e.create=function(e,t,n,r){return{red:e,green:t,blue:n,alpha:r}},e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.numberRange(t.red,0,1)&&$c.numberRange(t.green,0,1)&&$c.numberRange(t.blue,0,1)&&$c.numberRange(t.alpha,0,1)}}(ha||(ha={})),function(e){e.create=function(e,t){return{range:e,color:t}},e.is=function(e){const t=e;return $c.objectLiteral(t)&&la.is(t.range)&&ha.is(t.color)}}(fa||(fa={})),function(e){e.create=function(e,t,n){return{label:e,textEdit:t,additionalTextEdits:n}},e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.string(t.label)&&($c.undefined(t.textEdit)||ka.is(t))&&($c.undefined(t.additionalTextEdits)||$c.typedArray(t.additionalTextEdits,ka.is))}}(pa||(pa={})),function(e){e.Comment="comment",e.Imports="imports",e.Region="region"}(ma||(ma={})),function(e){e.create=function(e,t,n,r,i,s){const o={startLine:e,endLine:t};return $c.defined(n)&&(o.startCharacter=n),$c.defined(r)&&(o.endCharacter=r),$c.defined(i)&&(o.kind=i),$c.defined(s)&&(o.collapsedText=s),o},e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.uinteger(t.startLine)&&$c.uinteger(t.startLine)&&($c.undefined(t.startCharacter)||$c.uinteger(t.startCharacter))&&($c.undefined(t.endCharacter)||$c.uinteger(t.endCharacter))&&($c.undefined(t.kind)||$c.string(t.kind))}}(ga||(ga={})),function(e){e.create=function(e,t){return{location:e,message:t}},e.is=function(e){let t=e;return $c.defined(t)&&ua.is(t.location)&&$c.string(t.message)}}(ya||(ya={})),function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4}(Aa||(Aa={})),function(e){e.Unnecessary=1,e.Deprecated=2}(Ta||(Ta={})),function(e){e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.string(t.href)}}(va||(va={})),function(e){e.create=function(e,t,n,r,i,s){let o={range:e,message:t};return $c.defined(n)&&(o.severity=n),$c.defined(r)&&(o.code=r),$c.defined(i)&&(o.source=i),$c.defined(s)&&(o.relatedInformation=s),o},e.is=function(e){var t;let n=e;return $c.defined(n)&&la.is(n.range)&&$c.string(n.message)&&($c.number(n.severity)||$c.undefined(n.severity))&&($c.integer(n.code)||$c.string(n.code)||$c.undefined(n.code))&&($c.undefined(n.codeDescription)||$c.string(null===(t=n.codeDescription)||void 0===t?void 0:t.href))&&($c.string(n.source)||$c.undefined(n.source))&&($c.undefined(n.relatedInformation)||$c.typedArray(n.relatedInformation,ya.is))}}(Ra||(Ra={})),function(e){e.create=function(e,t,...n){let r={title:e,command:t};return $c.defined(n)&&n.length>0&&(r.arguments=n),r},e.is=function(e){let t=e;return $c.defined(t)&&$c.string(t.title)&&$c.string(t.command)}}(Ea||(Ea={})),function(e){e.replace=function(e,t){return{range:e,newText:t}},e.insert=function(e,t){return{range:{start:e,end:e},newText:t}},e.del=function(e){return{range:e,newText:""}},e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.string(t.newText)&&la.is(t.range)}}(ka||(ka={})),function(e){e.create=function(e,t,n){const r={label:e};return void 0!==t&&(r.needsConfirmation=t),void 0!==n&&(r.description=n),r},e.is=function(e){const t=e;return $c.objectLiteral(t)&&$c.string(t.label)&&($c.boolean(t.needsConfirmation)||void 0===t.needsConfirmation)&&($c.string(t.description)||void 0===t.description)}}(xa||(xa={})),function(e){e.is=function(e){const t=e;return $c.string(t)}}(Ia||(Ia={})),function(e){e.replace=function(e,t,n){return{range:e,newText:t,annotationId:n}},e.insert=function(e,t,n){return{range:{start:e,end:e},newText:t,annotationId:n}},e.del=function(e,t){return{range:e,newText:"",annotationId:t}},e.is=function(e){const t=e;return ka.is(t)&&(xa.is(t.annotationId)||Ia.is(t.annotationId))}}(Sa||(Sa={})),function(e){e.create=function(e,t){return{textDocument:e,edits:t}},e.is=function(e){let t=e;return $c.defined(t)&&_a.is(t.textDocument)&&Array.isArray(t.edits)}}(Na||(Na={})),function(e){e.create=function(e,t,n){let r={kind:"create",uri:e};return void 0===t||void 0===t.overwrite&&void 0===t.ignoreIfExists||(r.options=t),void 0!==n&&(r.annotationId=n),r},e.is=function(e){let t=e;return t&&"create"===t.kind&&$c.string(t.uri)&&(void 0===t.options||(void 0===t.options.overwrite||$c.boolean(t.options.overwrite))&&(void 0===t.options.ignoreIfExists||$c.boolean(t.options.ignoreIfExists)))&&(void 0===t.annotationId||Ia.is(t.annotationId))}}(Ca||(Ca={})),function(e){e.create=function(e,t,n,r){let i={kind:"rename",oldUri:e,newUri:t};return void 0===n||void 0===n.overwrite&&void 0===n.ignoreIfExists||(i.options=n),void 0!==r&&(i.annotationId=r),i},e.is=function(e){let t=e;return t&&"rename"===t.kind&&$c.string(t.oldUri)&&$c.string(t.newUri)&&(void 0===t.options||(void 0===t.options.overwrite||$c.boolean(t.options.overwrite))&&(void 0===t.options.ignoreIfExists||$c.boolean(t.options.ignoreIfExists)))&&(void 0===t.annotationId||Ia.is(t.annotationId))}}($a||($a={})),function(e){e.create=function(e,t,n){let r={kind:"delete",uri:e};return void 0===t||void 0===t.recursive&&void 0===t.ignoreIfNotExists||(r.options=t),void 0!==n&&(r.annotationId=n),r},e.is=function(e){let t=e;return t&&"delete"===t.kind&&$c.string(t.uri)&&(void 0===t.options||(void 0===t.options.recursive||$c.boolean(t.options.recursive))&&(void 0===t.options.ignoreIfNotExists||$c.boolean(t.options.ignoreIfNotExists)))&&(void 0===t.annotationId||Ia.is(t.annotationId))}}(wa||(wa={})),function(e){e.is=function(e){let t=e;return t&&(void 0!==t.changes||void 0!==t.documentChanges)&&(void 0===t.documentChanges||t.documentChanges.every((e=>$c.string(e.kind)?Ca.is(e)||$a.is(e)||wa.is(e):Na.is(e))))}}(La||(La={}));!function(e){e.create=function(e){return{uri:e}},e.is=function(e){let t=e;return $c.defined(t)&&$c.string(t.uri)}}(Oa||(Oa={})),function(e){e.create=function(e,t){return{uri:e,version:t}},e.is=function(e){let t=e;return $c.defined(t)&&$c.string(t.uri)&&$c.integer(t.version)}}(ba||(ba={})),function(e){e.create=function(e,t){return{uri:e,version:t}},e.is=function(e){let t=e;return $c.defined(t)&&$c.string(t.uri)&&(null===t.version||$c.integer(t.version))}}(_a||(_a={})),function(e){e.create=function(e,t,n,r){return{uri:e,languageId:t,version:n,text:r}},e.is=function(e){let t=e;return $c.defined(t)&&$c.string(t.uri)&&$c.string(t.languageId)&&$c.integer(t.version)&&$c.string(t.text)}}(Pa||(Pa={})),function(e){e.PlainText="plaintext",e.Markdown="markdown",e.is=function(t){const n=t;return n===e.PlainText||n===e.Markdown}}(Ma||(Ma={})),function(e){e.is=function(e){const t=e;return $c.objectLiteral(e)&&Ma.is(t.kind)&&$c.string(t.value)}}(Da||(Da={})),function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25}(Ua||(Ua={})),function(e){e.PlainText=1,e.Snippet=2}(Fa||(Fa={})),function(e){e.Deprecated=1}(Ga||(Ga={})),function(e){e.create=function(e,t,n){return{newText:e,insert:t,replace:n}},e.is=function(e){const t=e;return t&&$c.string(t.newText)&&la.is(t.insert)&&la.is(t.replace)}}(Ka||(Ka={})),function(e){e.asIs=1,e.adjustIndentation=2}(Ba||(Ba={})),function(e){e.is=function(e){const t=e;return t&&($c.string(t.detail)||void 0===t.detail)&&($c.string(t.description)||void 0===t.description)}}(ja||(ja={})),function(e){e.create=function(e){return{label:e}}}(Va||(Va={})),function(e){e.create=function(e,t){return{items:e||[],isIncomplete:!!t}}}(Ha||(Ha={})),function(e){e.fromPlainText=function(e){return e.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")},e.is=function(e){const t=e;return $c.string(t)||$c.objectLiteral(t)&&$c.string(t.language)&&$c.string(t.value)}}(Wa||(Wa={})),function(e){e.is=function(e){let t=e;return!!t&&$c.objectLiteral(t)&&(Da.is(t.contents)||Wa.is(t.contents)||$c.typedArray(t.contents,Wa.is))&&(void 0===e.range||la.is(e.range))}}(za||(za={})),function(e){e.create=function(e,t){return t?{label:e,documentation:t}:{label:e}}}(Ya||(Ya={})),function(e){e.create=function(e,t,...n){let r={label:e};return $c.defined(t)&&(r.documentation=t),$c.defined(n)?r.parameters=n:r.parameters=[],r}}(Xa||(Xa={})),function(e){e.Text=1,e.Read=2,e.Write=3}(qa||(qa={})),function(e){e.create=function(e,t){let n={range:e};return $c.number(t)&&(n.kind=t),n}}(Qa||(Qa={})),function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26}(Ja||(Ja={})),function(e){e.Deprecated=1}(Za||(Za={})),function(e){e.create=function(e,t,n,r,i){let s={name:e,kind:t,location:{uri:r,range:n}};return i&&(s.containerName=i),s}}(ec||(ec={})),function(e){e.create=function(e,t,n,r){return void 0!==r?{name:e,kind:t,location:{uri:n,range:r}}:{name:e,kind:t,location:{uri:n}}}}(tc||(tc={})),function(e){e.create=function(e,t,n,r,i,s){let o={name:e,detail:t,kind:n,range:r,selectionRange:i};return void 0!==s&&(o.children=s),o},e.is=function(e){let t=e;return t&&$c.string(t.name)&&$c.number(t.kind)&&la.is(t.range)&&la.is(t.selectionRange)&&(void 0===t.detail||$c.string(t.detail))&&(void 0===t.deprecated||$c.boolean(t.deprecated))&&(void 0===t.children||Array.isArray(t.children))&&(void 0===t.tags||Array.isArray(t.tags))}}(nc||(nc={})),function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"}(rc||(rc={})),function(e){e.Invoked=1,e.Automatic=2}(ic||(ic={})),function(e){e.create=function(e,t,n){let r={diagnostics:e};return null!=t&&(r.only=t),null!=n&&(r.triggerKind=n),r},e.is=function(e){let t=e;return $c.defined(t)&&$c.typedArray(t.diagnostics,Ra.is)&&(void 0===t.only||$c.typedArray(t.only,$c.string))&&(void 0===t.triggerKind||t.triggerKind===ic.Invoked||t.triggerKind===ic.Automatic)}}(sc||(sc={})),function(e){e.create=function(e,t,n){let r={title:e},i=!0;return"string"==typeof t?(i=!1,r.kind=t):Ea.is(t)?r.command=t:r.edit=t,i&&void 0!==n&&(r.kind=n),r},e.is=function(e){let t=e;return t&&$c.string(t.title)&&(void 0===t.diagnostics||$c.typedArray(t.diagnostics,Ra.is))&&(void 0===t.kind||$c.string(t.kind))&&(void 0!==t.edit||void 0!==t.command)&&(void 0===t.command||Ea.is(t.command))&&(void 0===t.isPreferred||$c.boolean(t.isPreferred))&&(void 0===t.edit||La.is(t.edit))}}(oc||(oc={})),function(e){e.create=function(e,t){let n={range:e};return $c.defined(t)&&(n.data=t),n},e.is=function(e){let t=e;return $c.defined(t)&&la.is(t.range)&&($c.undefined(t.command)||Ea.is(t.command))}}(ac||(ac={})),function(e){e.create=function(e,t){return{tabSize:e,insertSpaces:t}},e.is=function(e){let t=e;return $c.defined(t)&&$c.uinteger(t.tabSize)&&$c.boolean(t.insertSpaces)}}(cc||(cc={})),function(e){e.create=function(e,t,n){return{range:e,target:t,data:n}},e.is=function(e){let t=e;return $c.defined(t)&&la.is(t.range)&&($c.undefined(t.target)||$c.string(t.target))}}(lc||(lc={})),function(e){e.create=function(e,t){return{range:e,parent:t}},e.is=function(t){let n=t;return $c.objectLiteral(n)&&la.is(n.range)&&(void 0===n.parent||e.is(n.parent))}}(uc||(uc={})),function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"}(dc||(dc={})),function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"}(hc||(hc={})),function(e){e.is=function(e){const t=e;return $c.objectLiteral(t)&&(void 0===t.resultId||"string"==typeof t.resultId)&&Array.isArray(t.data)&&(0===t.data.length||"number"==typeof t.data[0])}}(fc||(fc={})),function(e){e.create=function(e,t){return{range:e,text:t}},e.is=function(e){const t=e;return null!=t&&la.is(t.range)&&$c.string(t.text)}}(pc||(pc={})),function(e){e.create=function(e,t,n){return{range:e,variableName:t,caseSensitiveLookup:n}},e.is=function(e){const t=e;return null!=t&&la.is(t.range)&&$c.boolean(t.caseSensitiveLookup)&&($c.string(t.variableName)||void 0===t.variableName)}}(mc||(mc={})),function(e){e.create=function(e,t){return{range:e,expression:t}},e.is=function(e){const t=e;return null!=t&&la.is(t.range)&&($c.string(t.expression)||void 0===t.expression)}}(gc||(gc={})),function(e){e.create=function(e,t){return{frameId:e,stoppedLocation:t}},e.is=function(e){const t=e;return $c.defined(t)&&la.is(e.stoppedLocation)}}(yc||(yc={})),function(e){e.Type=1,e.Parameter=2,e.is=function(e){return 1===e||2===e}}(Ac||(Ac={})),function(e){e.create=function(e){return{value:e}},e.is=function(e){const t=e;return $c.objectLiteral(t)&&(void 0===t.tooltip||$c.string(t.tooltip)||Da.is(t.tooltip))&&(void 0===t.location||ua.is(t.location))&&(void 0===t.command||Ea.is(t.command))}}(Tc||(Tc={})),function(e){e.create=function(e,t,n){const r={position:e,label:t};return void 0!==n&&(r.kind=n),r},e.is=function(e){const t=e;return $c.objectLiteral(t)&&ca.is(t.position)&&($c.string(t.label)||$c.typedArray(t.label,Tc.is))&&(void 0===t.kind||Ac.is(t.kind))&&void 0===t.textEdits||$c.typedArray(t.textEdits,ka.is)&&(void 0===t.tooltip||$c.string(t.tooltip)||Da.is(t.tooltip))&&(void 0===t.paddingLeft||$c.boolean(t.paddingLeft))&&(void 0===t.paddingRight||$c.boolean(t.paddingRight))}}(vc||(vc={})),function(e){e.createSnippet=function(e){return{kind:"snippet",value:e}}}(Rc||(Rc={})),function(e){e.create=function(e,t,n,r){return{insertText:e,filterText:t,range:n,command:r}}}(Ec||(Ec={})),function(e){e.create=function(e){return{items:e}}}(kc||(kc={})),function(e){e.Invoked=0,e.Automatic=1}(xc||(xc={})),function(e){e.create=function(e,t){return{range:e,text:t}}}(Ic||(Ic={})),function(e){e.create=function(e,t){return{triggerKind:e,selectedCompletionInfo:t}}}(Sc||(Sc={})),function(e){e.is=function(e){const t=e;return $c.objectLiteral(t)&&sa.is(t.uri)&&$c.string(t.name)}}(Nc||(Nc={}));var Cc,$c;!function(e){function t(e,n){if(e.length<=1)return e;const r=e.length/2|0,i=e.slice(0,r),s=e.slice(r);t(i,n),t(s,n);let o=0,a=0,c=0;for(;o<i.length&&a<s.length;){let t=n(i[o],s[a]);e[c++]=t<=0?i[o++]:s[a++]}for(;o<i.length;)e[c++]=i[o++];for(;a<s.length;)e[c++]=s[a++];return e}e.create=function(e,t,n,r){return new wc(e,t,n,r)},e.is=function(e){let t=e;return!!($c.defined(t)&&$c.string(t.uri)&&($c.undefined(t.languageId)||$c.string(t.languageId))&&$c.uinteger(t.lineCount)&&$c.func(t.getText)&&$c.func(t.positionAt)&&$c.func(t.offsetAt))},e.applyEdits=function(e,n){let r=e.getText(),i=t(n,((e,t)=>{let n=e.range.start.line-t.range.start.line;return 0===n?e.range.start.character-t.range.start.character:n})),s=r.length;for(let t=i.length-1;t>=0;t--){let n=i[t],o=e.offsetAt(n.range.start),a=e.offsetAt(n.range.end);if(!(a<=s))throw new Error("Overlapping edit");r=r.substring(0,o)+n.newText+r.substring(a,r.length),s=o}return r}}(Cc||(Cc={}));class wc{constructor(e,t,n,r){this._uri=e,this._languageId=t,this._version=n,this._content=r,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let t=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(t,n)}return this._content}update(e,t){this._content=e.text,this._version=t,this._lineOffsets=void 0}getLineOffsets(){if(void 0===this._lineOffsets){let e=[],t=this._content,n=!0;for(let r=0;r<t.length;r++){n&&(e.push(r),n=!1);let i=t.charAt(r);n="\r"===i||"\n"===i,"\r"===i&&r+1<t.length&&"\n"===t.charAt(r+1)&&r++}n&&t.length>0&&e.push(t.length),this._lineOffsets=e}return this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);let t=this.getLineOffsets(),n=0,r=t.length;if(0===r)return ca.create(0,e);for(;n<r;){let i=Math.floor((n+r)/2);t[i]>e?r=i:n=i+1}let i=n-1;return ca.create(i,e-t[i])}offsetAt(e){let t=this.getLineOffsets();if(e.line>=t.length)return this._content.length;if(e.line<0)return 0;let n=t[e.line],r=e.line+1<t.length?t[e.line+1]:this._content.length;return Math.max(Math.min(n+e.character,r),n)}get lineCount(){return this.getLineOffsets().length}}!function(e){const t=Object.prototype.toString;e.defined=function(e){return void 0!==e},e.undefined=function(e){return void 0===e},e.boolean=function(e){return!0===e||!1===e},e.string=function(e){return"[object String]"===t.call(e)},e.number=function(e){return"[object Number]"===t.call(e)},e.numberRange=function(e,n,r){return"[object Number]"===t.call(e)&&n<=e&&e<=r},e.integer=function(e){return"[object Number]"===t.call(e)&&-2147483648<=e&&e<=2147483647},e.uinteger=function(e){return"[object Number]"===t.call(e)&&0<=e&&e<=2147483647},e.func=function(e){return"[object Function]"===t.call(e)},e.objectLiteral=function(e){return null!==e&&"object"==typeof e},e.typedArray=function(e,t){return Array.isArray(e)&&e.every(t)}}($c||($c={}));class Lc{constructor(){this.nodeStack=[]}get current(){return this.nodeStack[this.nodeStack.length-1]}buildRootNode(e){return this.rootNode=new Mc(e),this.rootNode.root=this.rootNode,this.nodeStack=[this.rootNode],this.rootNode}buildCompositeNode(e){const t=new _c;return t.grammarSource=e,t.root=this.rootNode,this.current.content.push(t),this.nodeStack.push(t),t}buildLeafNode(e,t){const n=new bc(e.startOffset,e.image.length,v(e),e.tokenType,!1);return n.grammarSource=t,n.root=this.rootNode,this.current.content.push(n),n}removeNode(e){const t=e.container;if(t){const n=t.content.indexOf(e);n>=0&&t.content.splice(n,1)}}construct(e){const t=this.current;"string"==typeof e.$type&&(this.current.astNode=e),e.$cstNode=t;const n=this.nodeStack.pop();0===(null==n?void 0:n.content.length)&&this.removeNode(n)}addHiddenTokens(e){for(const t of e){const e=new bc(t.startOffset,t.image.length,v(t),t.tokenType,!0);e.root=this.rootNode,this.addHiddenToken(this.rootNode,e)}}addHiddenToken(e,t){const{offset:n,end:r}=t;for(let i=0;i<e.content.length;i++){const s=e.content[i],{offset:o,end:c}=s;if(a(s)&&n>o&&r<c)return void this.addHiddenToken(s,t);if(r<=o)return void e.content.splice(i,0,t)}e.content.push(t)}}class Oc{get parent(){return this.container}get feature(){return this.grammarSource}get hidden(){return!1}get astNode(){var e,t;const n="string"==typeof(null===(e=this._astNode)||void 0===e?void 0:e.$type)?this._astNode:null===(t=this.container)||void 0===t?void 0:t.astNode;if(!n)throw new Error("This node has no associated AST element");return n}set astNode(e){this._astNode=e}get element(){return this.astNode}get text(){return this.root.fullText.substring(this.offset,this.end)}}class bc extends Oc{get offset(){return this._offset}get length(){return this._length}get end(){return this._offset+this._length}get hidden(){return this._hidden}get tokenType(){return this._tokenType}get range(){return this._range}constructor(e,t,n,r,i=!1){super(),this._hidden=i,this._offset=e,this._tokenType=r,this._length=t,this._range=n}}class _c extends Oc{constructor(){super(...arguments),this.content=new Pc(this)}get children(){return this.content}get offset(){var e,t;return null!==(t=null===(e=this.firstNonHiddenNode)||void 0===e?void 0:e.offset)&&void 0!==t?t:0}get length(){return this.end-this.offset}get end(){var e,t;return null!==(t=null===(e=this.lastNonHiddenNode)||void 0===e?void 0:e.end)&&void 0!==t?t:0}get range(){const e=this.firstNonHiddenNode,t=this.lastNonHiddenNode;if(e&&t){if(void 0===this._rangeCache){const{range:n}=e,{range:r}=t;this._rangeCache={start:n.start,end:r.end.line<n.start.line?n.start:r.end}}return this._rangeCache}return{start:ca.create(0,0),end:ca.create(0,0)}}get firstNonHiddenNode(){for(const e of this.content)if(!e.hidden)return e;return this.content[0]}get lastNonHiddenNode(){for(let e=this.content.length-1;e>=0;e--){const t=this.content[e];if(!t.hidden)return t}return this.content[this.content.length-1]}}class Pc extends Array{constructor(e){super(),this.parent=e,Object.setPrototypeOf(this,Pc.prototype)}push(...e){return this.addParents(e),super.push(...e)}unshift(...e){return this.addParents(e),super.unshift(...e)}splice(e,t,...n){return this.addParents(n),super.splice(e,t,...n)}addParents(e){for(const t of e)t.container=this.parent}}class Mc extends _c{get text(){return this._text.substring(this.offset,this.end)}get fullText(){return this._text}constructor(e){super(),this._text="",this._text=null!=e?e:""}}const Dc=Symbol("Datatype");function Uc(e){return e.$type===Dc}const Fc=e=>e.endsWith("\u200b")?e:e+"\u200b";class Gc{constructor(e){this._unorderedGroups=new Map,this.lexer=e.parser.Lexer;const t=this.lexer.definition;this.wrapper=new Wc(t,Object.assign(Object.assign({},e.parser.ParserConfig),{errorMessageProvider:e.parser.ParserErrorMessageProvider}))}alternatives(e,t){this.wrapper.wrapOr(e,t)}optional(e,t){this.wrapper.wrapOption(e,t)}many(e,t){this.wrapper.wrapMany(e,t)}atLeastOne(e,t){this.wrapper.wrapAtLeastOne(e,t)}isRecording(){return this.wrapper.IS_RECORDING}get unorderedGroups(){return this._unorderedGroups}getRuleStack(){return this.wrapper.RULE_STACK}finalize(){this.wrapper.wrapSelfAnalysis()}}class Kc extends Gc{get current(){return this.stack[this.stack.length-1]}constructor(e){super(e),this.nodeBuilder=new Lc,this.stack=[],this.assignmentMap=new Map,this.linker=e.references.Linker,this.converter=e.parser.ValueConverter,this.astReflection=e.shared.AstReflection}rule(e,t){const n=e.fragment?void 0:gt(e)?Dc:Tt(e),r=this.wrapper.DEFINE_RULE(Fc(e.name),this.startImplementation(n,t).bind(this));return e.entry&&(this.mainRule=r),r}parse(e){this.nodeBuilder.buildRootNode(e);const t=this.lexer.tokenize(e);this.wrapper.input=t.tokens;const n=this.mainRule.call(this.wrapper,{});return this.nodeBuilder.addHiddenTokens(t.hidden),this.unorderedGroups.clear(),{value:n,lexerErrors:t.errors,parserErrors:this.wrapper.errors}}startImplementation(e,t){return n=>{if(!this.isRecording()){const t={$type:e};this.stack.push(t),e===Dc&&(t.value="")}let r;try{r=t(n)}catch(i){r=void 0}return this.isRecording()||void 0!==r||(r=this.construct()),r}}consume(e,t,n){const r=this.wrapper.wrapConsume(e,t);if(!this.isRecording()&&this.isValidToken(r)){const e=this.nodeBuilder.buildLeafNode(r,n),{assignment:t,isCrossRef:i}=this.getAssignment(n),s=this.current;if(t){const s=Ae(n)?r.image:this.converter.convert(r.image,e);this.assign(t.operator,t.feature,s,e,i)}else if(Uc(s)){let t=r.image;Ae(n)||(t=this.converter.convert(t,e).toString()),s.value+=t}}}isValidToken(e){return!e.isInsertedInRecovery&&!isNaN(e.startOffset)&&"number"==typeof e.endOffset&&!isNaN(e.endOffset)}subrule(e,t,n,r){let i;this.isRecording()||(i=this.nodeBuilder.buildCompositeNode(n));const s=this.wrapper.wrapSubrule(e,t,r);!this.isRecording()&&i&&i.length>0&&this.performSubruleAssignment(s,n,i)}performSubruleAssignment(e,t,n){const{assignment:r,isCrossRef:i}=this.getAssignment(t);if(r)this.assign(r.operator,r.feature,e,n,i);else if(!r){const t=this.current;if(Uc(t))t.value+=e.toString();else if("object"==typeof e&&e){const n=e.$type,r=this.assignWithoutOverride(e,t);n&&(r.$type=n);const i=r;this.stack.pop(),this.stack.push(i)}}}action(e,t){if(!this.isRecording()){let n=this.current;if(!n.$cstNode&&t.feature&&t.operator){n=this.construct(!1);const e=n.$cstNode.feature;this.nodeBuilder.buildCompositeNode(e)}const r={$type:e};this.stack.pop(),this.stack.push(r),t.feature&&t.operator&&this.assign(t.operator,t.feature,n,n.$cstNode,!1)}}construct(e=!0){if(this.isRecording())return;const t=this.current;return be(t),this.nodeBuilder.construct(t),e&&this.stack.pop(),Uc(t)?this.converter.convert(t.value,t.$cstNode):(function(e,t){const n=e.getTypeMetaData(t.$type),r=t;for(const i of n.properties)void 0!==i.defaultValue&&void 0===r[i.name]&&(r[i.name]=Ke(i.defaultValue))}(this.astReflection,t),t)}getAssignment(e){if(!this.assignmentMap.has(e)){const t=_e(e,ue);this.assignmentMap.set(e,{assignment:t,isCrossRef:!!t&&fe(t.terminal)})}return this.assignmentMap.get(e)}assign(e,t,n,r,i){const s=this.current;let o;switch(o=i&&"string"==typeof n?this.linker.buildReference(s,t,r,n):n,e){case"=":s[t]=o;break;case"?=":s[t]=!0;break;case"+=":Array.isArray(s[t])||(s[t]=[]),s[t].push(o)}}assignWithoutOverride(e,t){for(const[n,r]of Object.entries(t)){const t=e[n];void 0===t?e[n]=r:Array.isArray(t)&&Array.isArray(r)&&(r.push(...t),e[n]=r)}return e}get definitionErrors(){return this.wrapper.definitionErrors}}class Bc{buildMismatchTokenMessage(e){return vi.buildMismatchTokenMessage(e)}buildNotAllInputParsedMessage(e){return vi.buildNotAllInputParsedMessage(e)}buildNoViableAltMessage(e){return vi.buildNoViableAltMessage(e)}buildEarlyExitMessage(e){return vi.buildEarlyExitMessage(e)}}class jc extends Bc{buildMismatchTokenMessage({expected:e,actual:t}){return`Expecting ${e.LABEL?"`"+e.LABEL+"`":e.name.endsWith(":KW")?`keyword '${e.name.substring(0,e.name.length-3)}'`:`token of type '${e.name}'`} but found \`${t.image}\`.`}buildNotAllInputParsedMessage({firstRedundant:e}){return`Expecting end of file but found \`${e.image}\`.`}}class Vc extends Gc{constructor(){super(...arguments),this.tokens=[],this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}action(){}construct(){}parse(e){this.resetState();const t=this.lexer.tokenize(e);return this.tokens=t.tokens,this.wrapper.input=[...this.tokens],this.mainRule.call(this.wrapper,{}),this.unorderedGroups.clear(),{tokens:this.tokens,elementStack:[...this.lastElementStack],tokenIndex:this.nextTokenIndex}}rule(e,t){const n=this.wrapper.DEFINE_RULE(Fc(e.name),this.startImplementation(t).bind(this));return e.entry&&(this.mainRule=n),n}resetState(){this.elementStack=[],this.lastElementStack=[],this.nextTokenIndex=0,this.stackSize=0}startImplementation(e){return t=>{const n=this.keepStackSize();try{e(t)}finally{this.resetStackSize(n)}}}removeUnexpectedElements(){this.elementStack.splice(this.stackSize)}keepStackSize(){const e=this.elementStack.length;return this.stackSize=e,e}resetStackSize(e){this.removeUnexpectedElements(),this.stackSize=e}consume(e,t,n){this.wrapper.wrapConsume(e,t),this.isRecording()||(this.lastElementStack=[...this.elementStack,n],this.nextTokenIndex=this.currIdx+1)}subrule(e,t,n,r){this.before(n),this.wrapper.wrapSubrule(e,t,r),this.after(n)}before(e){this.isRecording()||this.elementStack.push(e)}after(e){if(!this.isRecording()){const t=this.elementStack.lastIndexOf(e);t>=0&&this.elementStack.splice(t)}}get currIdx(){return this.wrapper.currIdx}}const Hc={recoveryEnabled:!0,nodeLocationTracking:"full",skipValidations:!0,errorMessageProvider:new jc};class Wc extends oo{constructor(e,t){const n=t&&"maxLookahead"in t;super(e,Object.assign(Object.assign(Object.assign({},Hc),{lookaheadStrategy:n?new Os({maxLookahead:t.maxLookahead}):new Vo}),t))}get IS_RECORDING(){return this.RECORDING_PHASE}DEFINE_RULE(e,t){return this.RULE(e,t)}wrapSelfAnalysis(){this.performSelfAnalysis()}wrapConsume(e,t){return this.consume(e,t)}wrapSubrule(e,t,n){return this.subrule(e,t,{ARGS:[n]})}wrapOr(e,t){this.or(e,t)}wrapOption(e,t){this.option(e,t)}wrapMany(e,t){this.many(e,t)}wrapAtLeastOne(e,t){this.atLeastOne(e,t)}}function zc(e,t,n){return function(e,t){const n=lt(t,!1),r=m(t.rules).filter(X).filter((e=>n.has(e)));for(const i of r){const t=Object.assign(Object.assign({},e),{consume:1,optional:1,subrule:1,many:1,or:1});t.rules.set(i.name,e.parser.rule(i,Yc(t,i.definition)))}}({parser:t,tokens:n,rules:new Map,ruleNames:new Map},e),t}function Yc(e,t,n=!1){let r;if(Ae(t))r=function(e,t){const n=e.consume++,r=e.tokens[t.value];if(!r)throw new Error("Could not find token for keyword: "+t.value);return()=>e.parser.consume(n,r,t)}(e,t);else if(oe(t))r=function(e,t){const n=Tt(t);return()=>e.parser.action(n,t)}(e,t);else if(ue(t))r=Yc(e,t.terminal);else if(fe(t))r=Qc(e,t);else if(Ee(t))r=function(e,t){const n=t.rule.ref;if(X(n)){const r=e.subrule++,i=t.arguments.length>0?function(e,t){const n=t.map((e=>Xc(e.value)));return t=>{const r={};for(let i=0;i<n.length;i++){const s=e.parameters[i],o=n[i];r[s.name]=o(t)}return r}}(n,t.arguments):()=>({});return s=>e.parser.subrule(r,Zc(e,n),t,i(s))}if(te(n)){const r=e.consume++,i=el(e,n.name);return()=>e.parser.consume(r,i,t)}if(!n)throw new S(t.$cstNode,`Undefined rule type: ${t.$type}`);N()}(e,t);else if(ce(t))r=function(e,t){if(1===t.elements.length)return Yc(e,t.elements[0]);{const n=[];for(const i of t.elements){const t={ALT:Yc(e,i,!0)},r=qc(i);r&&(t.GATE=Xc(r)),n.push(t)}const r=e.or++;return t=>e.parser.alternatives(r,n.map((e=>{const n={ALT:()=>e.ALT(t)},r=e.GATE;return r&&(n.GATE=()=>r(t)),n})))}}(e,t);else if(Ce(t))r=function(e,t){if(1===t.elements.length)return Yc(e,t.elements[0]);const n=[];for(const a of t.elements){const t={ALT:Yc(e,a,!0)},r=qc(a);r&&(t.GATE=Xc(r)),n.push(t)}const r=e.or++,i=(e,t)=>`uGroup_${e}_${t.getRuleStack().join("-")}`,s=t=>e.parser.alternatives(r,n.map(((n,s)=>{const o={ALT:()=>!0},a=e.parser;o.ALT=()=>{if(n.ALT(t),!a.isRecording()){const e=i(r,a);a.unorderedGroups.get(e)||a.unorderedGroups.set(e,[]);const t=a.unorderedGroups.get(e);void 0===(null==t?void 0:t[s])&&(t[s]=!0)}};const c=n.GATE;return o.GATE=c?()=>c(t):()=>{const e=a.unorderedGroups.get(i(r,a));return!(null==e?void 0:e[s])},o}))),o=Jc(e,qc(t),s,"*");return t=>{o(t),e.parser.isRecording()||e.parser.unorderedGroups.delete(i(r,e.parser))}}(e,t);else if(ge(t))r=function(e,t){const n=t.elements.map((t=>Yc(e,t)));return e=>n.forEach((t=>t(e)))}(e,t);else{if(i=t,!Oe.isInstance(i,pe))throw new S(t.$cstNode,`Unexpected element type: ${t.$type}`);{const n=e.consume++;r=()=>e.parser.consume(n,yi,t)}}var i;return Jc(e,n?void 0:qc(t),r,t.cardinality)}function Xc(e){if(t=e,Oe.isInstance(t,U)){const t=Xc(e.left),n=Xc(e.right);return e=>t(e)||n(e)}if(function(e){return Oe.isInstance(e,D)}(e)){const t=Xc(e.left),n=Xc(e.right);return e=>t(e)&&n(e)}if(function(e){return Oe.isInstance(e,V)}(e)){const t=Xc(e.value);return e=>!t(e)}if(function(e){return Oe.isInstance(e,z)}(e)){const t=e.parameter.ref.name;return e=>void 0!==e&&!0===e[t]}if(function(e){return Oe.isInstance(e,M)}(e)){const t=Boolean(e.true);return()=>t}var t;N()}function qc(e){if(ge(e))return e.guardCondition}function Qc(e,t,n=t.terminal){if(n){if(Ee(n)&&X(n.rule.ref)){const r=e.subrule++;return i=>e.parser.subrule(r,Zc(e,n.rule.ref),t,i)}if(Ee(n)&&te(n.rule.ref)){const r=e.consume++,i=el(e,n.rule.ref.name);return()=>e.parser.consume(r,i,t)}if(Ae(n)){const r=e.consume++,i=el(e,n.value);return()=>e.parser.consume(r,i,t)}throw new Error("Could not build cross reference parser")}{if(!t.type.ref)throw new Error("Could not resolve reference to type: "+t.type.$refText);const n=pt(t.type.ref),r=null==n?void 0:n.terminal;if(!r)throw new Error("Could not find name assignment for type: "+Tt(t.type.ref));return Qc(e,t,r)}}function Jc(e,t,n,r){const i=t&&Xc(t);if(!r){if(i){const t=e.or++;return r=>e.parser.alternatives(t,[{ALT:()=>n(r),GATE:()=>i(r)},{ALT:io(),GATE:()=>!i(r)}])}return n}if("*"===r){const t=e.many++;return r=>e.parser.many(t,{DEF:()=>n(r),GATE:i?()=>i(r):void 0})}if("+"===r){const t=e.many++;if(i){const r=e.or++;return s=>e.parser.alternatives(r,[{ALT:()=>e.parser.atLeastOne(t,{DEF:()=>n(s)}),GATE:()=>i(s)},{ALT:io(),GATE:()=>!i(s)}])}return r=>e.parser.atLeastOne(t,{DEF:()=>n(r)})}if("?"===r){const t=e.optional++;return r=>e.parser.optional(t,{DEF:()=>n(r),GATE:i?()=>i(r):void 0})}N()}function Zc(e,t){const n=function(e,t){if(X(t))return t.name;if(e.ruleNames.has(t))return e.ruleNames.get(t);{let n=t,r=n.$container,i=t.$type;for(;!X(r);){if(ge(r)||ce(r)||Ce(r)){i=r.elements.indexOf(n).toString()+":"+i}n=r,r=r.$container}return i=r.name+":"+i,e.ruleNames.set(t,i),i}}(e,t),r=e.rules.get(n);if(!r)throw new Error(`Rule "${n}" not found."`);return r}function el(e,t){const n=e.tokens[t];if(!n)throw new Error(`Token "${t}" not found."`);return n}function tl(e){const t=function(e){const t=e.Grammar,n=e.parser.Lexer,r=new Kc(e);return zc(t,r,n.definition)}(e);return t.finalize(),t}class nl{buildTokens(e,t){const n=m(lt(e,!1)),r=this.buildTerminalTokens(n),i=this.buildKeywordTokens(n,r,t);return r.forEach((e=>{const t=e.PATTERN;"object"==typeof t&&t&&"test"in t&&ot(t)?i.unshift(e):i.push(e)})),i}buildTerminalTokens(e){return e.filter(te).filter((e=>!e.fragment)).map((e=>this.buildTerminalToken(e))).toArray()}buildTerminalToken(e){const t=vt(e),n=this.requiresCustomPattern(t)?this.regexPatternFunction(t):t,r={name:e.name,PATTERN:n,LINE_BREAKS:!0};return e.hidden&&(r.GROUP=ot(t)?ii.SKIPPED:"hidden"),r}requiresCustomPattern(e){return!!e.flags.includes("u")||!(!e.source.includes("?<=")&&!e.source.includes("?<!"))}regexPatternFunction(e){const t=new RegExp(e,e.flags+"y");return(e,n)=>{t.lastIndex=n;return t.exec(e)}}buildKeywordTokens(e,t,n){return e.filter(X).flatMap((e=>De(e).filter(Ae))).distinct((e=>e.value)).toArray().sort(((e,t)=>t.value.length-e.value.length)).map((e=>this.buildKeywordToken(e,t,Boolean(null==n?void 0:n.caseInsensitive))))}buildKeywordToken(e,t,n){return{name:e.value,PATTERN:this.buildKeywordPattern(e,n),LONGER_ALT:this.findLongerAlt(e,t)}}buildKeywordPattern(e,t){return t?new RegExp(function(e){return Array.prototype.map.call(e,(e=>/\w/.test(e)?`[${e.toLowerCase()}${e.toUpperCase()}]`:at(e))).join("")}(e.value)):e.value}findLongerAlt(e,t){return t.reduce(((t,n)=>{const r=null==n?void 0:n.PATTERN;return(null==r?void 0:r.source)&&ct("^"+r.source+"$",e.value)&&t.push(n),t}),[])}}class rl{convert(e,t){let n=t.grammarSource;if(fe(n)&&(n=function(e){if(e.terminal)return e.terminal;if(e.type.ref){const t=pt(e.type.ref);return null==t?void 0:t.terminal}}(n)),Ee(n)){const r=n.rule.ref;if(!r)throw new Error("This cst node was not parsed by a rule.");return this.runConverter(r,e,t)}return e}runConverter(e,t,n){var r;switch(e.name.toUpperCase()){case"INT":return il.convertInt(t);case"STRING":return il.convertString(t);case"ID":return il.convertID(t)}switch(null===(r=function(e){var t,n,r;return te(e)?null!==(n=null===(t=e.type)||void 0===t?void 0:t.name)&&void 0!==n?n:"string":gt(e)?e.name:null!==(r=At(e))&&void 0!==r?r:e.name}(e))||void 0===r?void 0:r.toLowerCase()){case"number":return il.convertNumber(t);case"boolean":return il.convertBoolean(t);case"bigint":return il.convertBigint(t);case"date":return il.convertDate(t);default:return t}}}var il;!function(e){function t(e){switch(e){case"b":return"\b";case"f":return"\f";case"n":return"\n";case"r":return"\r";case"t":return"\t";case"v":return"\v";case"0":return"\0";default:return e}}e.convertString=function(e){let n="";for(let r=1;r<e.length-1;r++){const i=e.charAt(r);if("\\"===i){n+=t(e.charAt(++r))}else n+=i}return n},e.convertID=function(e){return"^"===e.charAt(0)?e.substring(1):e},e.convertInt=function(e){return parseInt(e)},e.convertBigint=function(e){return BigInt(e)},e.convertDate=function(e){return new Date(e)},e.convertNumber=function(e){return Number(e)},e.convertBoolean=function(e){return"true"===e.toLowerCase()}}(il||(il={}));var sl=n(59850);let ol=0,al=10;const cl=Symbol("OperationCancelled");function ll(e){return e===cl}async function ul(e){if(e===sl.XO.None)return;const t=Date.now();if(t-ol>=al&&(ol=t,await new Promise((e=>{"undefined"==typeof setImmediate?setTimeout(e,0):setImmediate(e)}))),e.isCancellationRequested)throw cl}class dl{constructor(){this.promise=new Promise(((e,t)=>{this.resolve=t=>(e(t),this),this.reject=e=>(t(e),this)}))}}class hl{constructor(e,t,n,r){this._uri=e,this._languageId=t,this._version=n,this._content=r,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){const t=this.offsetAt(e.start),n=this.offsetAt(e.end);return this._content.substring(t,n)}return this._content}update(e,t){for(const n of e)if(hl.isIncremental(n)){const e=Al(n.range),t=this.offsetAt(e.start),r=this.offsetAt(e.end);this._content=this._content.substring(0,t)+n.text+this._content.substring(r,this._content.length);const i=Math.max(e.start.line,0),s=Math.max(e.end.line,0);let o=this._lineOffsets;const a=gl(n.text,!1,t);if(s-i===a.length)for(let n=0,l=a.length;n<l;n++)o[n+i+1]=a[n];else a.length<1e4?o.splice(i+1,s-i,...a):this._lineOffsets=o=o.slice(0,i+1).concat(a,o.slice(s+1));const c=n.text.length-(r-t);if(0!==c)for(let n=i+1+a.length,l=o.length;n<l;n++)o[n]=o[n]+c}else{if(!hl.isFull(n))throw new Error("Unknown change event received");this._content=n.text,this._lineOffsets=void 0}this._version=t}getLineOffsets(){return void 0===this._lineOffsets&&(this._lineOffsets=gl(this._content,!0)),this._lineOffsets}positionAt(e){e=Math.max(Math.min(e,this._content.length),0);const t=this.getLineOffsets();let n=0,r=t.length;if(0===r)return{line:0,character:e};for(;n<r;){const i=Math.floor((n+r)/2);t[i]>e?r=i:n=i+1}const i=n-1;return{line:i,character:(e=this.ensureBeforeEOL(e,t[i]))-t[i]}}offsetAt(e){const t=this.getLineOffsets();if(e.line>=t.length)return this._content.length;if(e.line<0)return 0;const n=t[e.line];if(e.character<=0)return n;const r=e.line+1<t.length?t[e.line+1]:this._content.length,i=Math.min(n+e.character,r);return this.ensureBeforeEOL(i,n)}ensureBeforeEOL(e,t){for(;e>t&&yl(this._content.charCodeAt(e-1));)e--;return e}get lineCount(){return this.getLineOffsets().length}static isIncremental(e){const t=e;return null!=t&&"string"==typeof t.text&&void 0!==t.range&&(void 0===t.rangeLength||"number"==typeof t.rangeLength)}static isFull(e){const t=e;return null!=t&&"string"==typeof t.text&&void 0===t.range&&void 0===t.rangeLength}}var fl,pl;function ml(e,t){if(e.length<=1)return e;const n=e.length/2|0,r=e.slice(0,n),i=e.slice(n);ml(r,t),ml(i,t);let s=0,o=0,a=0;for(;s<r.length&&o<i.length;){const n=t(r[s],i[o]);e[a++]=n<=0?r[s++]:i[o++]}for(;s<r.length;)e[a++]=r[s++];for(;o<i.length;)e[a++]=i[o++];return e}function gl(e,t,n=0){const r=t?[n]:[];for(let i=0;i<e.length;i++){const t=e.charCodeAt(i);yl(t)&&(13===t&&i+1<e.length&&10===e.charCodeAt(i+1)&&i++,r.push(n+i+1))}return r}function yl(e){return 13===e||10===e}function Al(e){const t=e.start,n=e.end;return t.line>n.line||t.line===n.line&&t.character>n.character?{start:n,end:t}:e}function Tl(e){const t=Al(e.range);return t!==e.range?{newText:e.newText,range:t}:e}!function(e){e.create=function(e,t,n,r){return new hl(e,t,n,r)},e.update=function(e,t,n){if(e instanceof hl)return e.update(t,n),e;throw new Error("TextDocument.update: document must be created by TextDocument.create")},e.applyEdits=function(e,t){const n=e.getText(),r=ml(t.map(Tl),((e,t)=>{const n=e.range.start.line-t.range.start.line;return 0===n?e.range.start.character-t.range.start.character:n}));let i=0;const s=[];for(const o of r){const t=e.offsetAt(o.range.start);if(t<i)throw new Error("Overlapping edit");t>i&&s.push(n.substring(i,t)),o.newText.length&&s.push(o.newText),i=e.offsetAt(o.range.end)}return s.push(n.substr(i)),s.join("")}}(fl||(fl={})),(()=>{var e={470:e=>{function t(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function n(e,t){for(var n,r="",i=0,s=-1,o=0,a=0;a<=e.length;++a){if(a<e.length)n=e.charCodeAt(a);else{if(47===n)break;n=47}if(47===n){if(s===a-1||1===o);else if(s!==a-1&&2===o){if(r.length<2||2!==i||46!==r.charCodeAt(r.length-1)||46!==r.charCodeAt(r.length-2))if(r.length>2){var c=r.lastIndexOf("/");if(c!==r.length-1){-1===c?(r="",i=0):i=(r=r.slice(0,c)).length-1-r.lastIndexOf("/"),s=a,o=0;continue}}else if(2===r.length||1===r.length){r="",i=0,s=a,o=0;continue}t&&(r.length>0?r+="/..":r="..",i=2)}else r.length>0?r+="/"+e.slice(s+1,a):r=e.slice(s+1,a),i=a-s-1;s=a,o=0}else 46===n&&-1!==o?++o:o=-1}return r}var r={resolve:function(){for(var e,r="",i=!1,s=arguments.length-1;s>=-1&&!i;s--){var o;s>=0?o=arguments[s]:(void 0===e&&(e=process.cwd()),o=e),t(o),0!==o.length&&(r=o+"/"+r,i=47===o.charCodeAt(0))}return r=n(r,!i),i?r.length>0?"/"+r:"/":r.length>0?r:"."},normalize:function(e){if(t(e),0===e.length)return".";var r=47===e.charCodeAt(0),i=47===e.charCodeAt(e.length-1);return 0!==(e=n(e,!r)).length||r||(e="."),e.length>0&&i&&(e+="/"),r?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,n=0;n<arguments.length;++n){var i=arguments[n];t(i),i.length>0&&(void 0===e?e=i:e+="/"+i)}return void 0===e?".":r.normalize(e)},relative:function(e,n){if(t(e),t(n),e===n)return"";if((e=r.resolve(e))===(n=r.resolve(n)))return"";for(var i=1;i<e.length&&47===e.charCodeAt(i);++i);for(var s=e.length,o=s-i,a=1;a<n.length&&47===n.charCodeAt(a);++a);for(var c=n.length-a,l=o<c?o:c,u=-1,d=0;d<=l;++d){if(d===l){if(c>l){if(47===n.charCodeAt(a+d))return n.slice(a+d+1);if(0===d)return n.slice(a+d)}else o>l&&(47===e.charCodeAt(i+d)?u=d:0===d&&(u=0));break}var h=e.charCodeAt(i+d);if(h!==n.charCodeAt(a+d))break;47===h&&(u=d)}var f="";for(d=i+u+1;d<=s;++d)d!==s&&47!==e.charCodeAt(d)||(0===f.length?f+="..":f+="/..");return f.length>0?f+n.slice(a+u):(a+=u,47===n.charCodeAt(a)&&++a,n.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var n=e.charCodeAt(0),r=47===n,i=-1,s=!0,o=e.length-1;o>=1;--o)if(47===(n=e.charCodeAt(o))){if(!s){i=o;break}}else s=!1;return-1===i?r?"/":".":r&&1===i?"//":e.slice(0,i)},basename:function(e,n){if(void 0!==n&&"string"!=typeof n)throw new TypeError('"ext" argument must be a string');t(e);var r,i=0,s=-1,o=!0;if(void 0!==n&&n.length>0&&n.length<=e.length){if(n.length===e.length&&n===e)return"";var a=n.length-1,c=-1;for(r=e.length-1;r>=0;--r){var l=e.charCodeAt(r);if(47===l){if(!o){i=r+1;break}}else-1===c&&(o=!1,c=r+1),a>=0&&(l===n.charCodeAt(a)?-1==--a&&(s=r):(a=-1,s=c))}return i===s?s=c:-1===s&&(s=e.length),e.slice(i,s)}for(r=e.length-1;r>=0;--r)if(47===e.charCodeAt(r)){if(!o){i=r+1;break}}else-1===s&&(o=!1,s=r+1);return-1===s?"":e.slice(i,s)},extname:function(e){t(e);for(var n=-1,r=0,i=-1,s=!0,o=0,a=e.length-1;a>=0;--a){var c=e.charCodeAt(a);if(47!==c)-1===i&&(s=!1,i=a+1),46===c?-1===n?n=a:1!==o&&(o=1):-1!==n&&(o=-1);else if(!s){r=a+1;break}}return-1===n||-1===i||0===o||1===o&&n===i-1&&n===r+1?"":e.slice(n,i)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var n=t.dir||t.root,r=t.base||(t.name||"")+(t.ext||"");return n?n===t.root?n+r:n+"/"+r:r}(0,e)},parse:function(e){t(e);var n={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return n;var r,i=e.charCodeAt(0),s=47===i;s?(n.root="/",r=1):r=0;for(var o=-1,a=0,c=-1,l=!0,u=e.length-1,d=0;u>=r;--u)if(47!==(i=e.charCodeAt(u)))-1===c&&(l=!1,c=u+1),46===i?-1===o?o=u:1!==d&&(d=1):-1!==o&&(d=-1);else if(!l){a=u+1;break}return-1===o||-1===c||0===d||1===d&&o===c-1&&o===a+1?-1!==c&&(n.base=n.name=0===a&&s?e.slice(1,c):e.slice(a,c)):(0===a&&s?(n.name=e.slice(1,o),n.base=e.slice(1,c)):(n.name=e.slice(a,o),n.base=e.slice(a,c)),n.ext=e.slice(o,c)),a>0?n.dir=e.slice(0,a-1):s&&(n.dir="/"),n},sep:"/",delimiter:":",win32:null,posix:null};r.posix=r,e.exports=r}},t={};function n(r){var i=t[r];if(void 0!==i)return i.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};(()=>{let e;if(n.r(r),n.d(r,{URI:()=>u,Utils:()=>x}),"object"==typeof process)e="win32"===process.platform;else if("object"==typeof navigator){let t=navigator.userAgent;e=t.indexOf("Windows")>=0}const t=/^\w[\w\d+.-]*$/,i=/^\//,s=/^\/\//;function o(e,n){if(!e.scheme&&n)throw new Error(`[UriError]: Scheme is missing: {scheme: "", authority: "${e.authority}", path: "${e.path}", query: "${e.query}", fragment: "${e.fragment}"}`);if(e.scheme&&!t.test(e.scheme))throw new Error("[UriError]: Scheme contains illegal characters.");if(e.path)if(e.authority){if(!i.test(e.path))throw new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash ("/") character')}else if(s.test(e.path))throw new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters ("//")')}const a="",c="/",l=/^(([^:/?#]+?):)?(\/\/([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/;class u{static isUri(e){return e instanceof u||!!e&&"string"==typeof e.authority&&"string"==typeof e.fragment&&"string"==typeof e.path&&"string"==typeof e.query&&"string"==typeof e.scheme&&"string"==typeof e.fsPath&&"function"==typeof e.with&&"function"==typeof e.toString}scheme;authority;path;query;fragment;constructor(e,t,n,r,i,s=!1){"object"==typeof e?(this.scheme=e.scheme||a,this.authority=e.authority||a,this.path=e.path||a,this.query=e.query||a,this.fragment=e.fragment||a):(this.scheme=function(e,t){return e||t?e:"file"}(e,s),this.authority=t||a,this.path=function(e,t){switch(e){case"https":case"http":case"file":t?t[0]!==c&&(t=c+t):t=c}return t}(this.scheme,n||a),this.query=r||a,this.fragment=i||a,o(this,s))}get fsPath(){return g(this,!1)}with(e){if(!e)return this;let{scheme:t,authority:n,path:r,query:i,fragment:s}=e;return void 0===t?t=this.scheme:null===t&&(t=a),void 0===n?n=this.authority:null===n&&(n=a),void 0===r?r=this.path:null===r&&(r=a),void 0===i?i=this.query:null===i&&(i=a),void 0===s?s=this.fragment:null===s&&(s=a),t===this.scheme&&n===this.authority&&r===this.path&&i===this.query&&s===this.fragment?this:new h(t,n,r,i,s)}static parse(e,t=!1){const n=l.exec(e);return n?new h(n[2]||a,v(n[4]||a),v(n[5]||a),v(n[7]||a),v(n[9]||a),t):new h(a,a,a,a,a)}static file(t){let n=a;if(e&&(t=t.replace(/\\/g,c)),t[0]===c&&t[1]===c){const e=t.indexOf(c,2);-1===e?(n=t.substring(2),t=c):(n=t.substring(2,e),t=t.substring(e)||c)}return new h("file",n,t,a,a)}static from(e){const t=new h(e.scheme,e.authority,e.path,e.query,e.fragment);return o(t,!0),t}toString(e=!1){return y(this,e)}toJSON(){return this}static revive(e){if(e){if(e instanceof u)return e;{const t=new h(e);return t._formatted=e.external,t._fsPath=e._sep===d?e.fsPath:null,t}}return e}}const d=e?1:void 0;class h extends u{_formatted=null;_fsPath=null;get fsPath(){return this._fsPath||(this._fsPath=g(this,!1)),this._fsPath}toString(e=!1){return e?y(this,!0):(this._formatted||(this._formatted=y(this,!1)),this._formatted)}toJSON(){const e={$mid:1};return this._fsPath&&(e.fsPath=this._fsPath,e._sep=d),this._formatted&&(e.external=this._formatted),this.path&&(e.path=this.path),this.scheme&&(e.scheme=this.scheme),this.authority&&(e.authority=this.authority),this.query&&(e.query=this.query),this.fragment&&(e.fragment=this.fragment),e}}const f={58:"%3A",47:"%2F",63:"%3F",35:"%23",91:"%5B",93:"%5D",64:"%40",33:"%21",36:"%24",38:"%26",39:"%27",40:"%28",41:"%29",42:"%2A",43:"%2B",44:"%2C",59:"%3B",61:"%3D",32:"%20"};function p(e,t,n){let r,i=-1;for(let s=0;s<e.length;s++){const o=e.charCodeAt(s);if(o>=97&&o<=122||o>=65&&o<=90||o>=48&&o<=57||45===o||46===o||95===o||126===o||t&&47===o||n&&91===o||n&&93===o||n&&58===o)-1!==i&&(r+=encodeURIComponent(e.substring(i,s)),i=-1),void 0!==r&&(r+=e.charAt(s));else{void 0===r&&(r=e.substr(0,s));const t=f[o];void 0!==t?(-1!==i&&(r+=encodeURIComponent(e.substring(i,s)),i=-1),r+=t):-1===i&&(i=s)}}return-1!==i&&(r+=encodeURIComponent(e.substring(i))),void 0!==r?r:e}function m(e){let t;for(let n=0;n<e.length;n++){const r=e.charCodeAt(n);35===r||63===r?(void 0===t&&(t=e.substr(0,n)),t+=f[r]):void 0!==t&&(t+=e[n])}return void 0!==t?t:e}function g(t,n){let r;return r=t.authority&&t.path.length>1&&"file"===t.scheme?`//${t.authority}${t.path}`:47===t.path.charCodeAt(0)&&(t.path.charCodeAt(1)>=65&&t.path.charCodeAt(1)<=90||t.path.charCodeAt(1)>=97&&t.path.charCodeAt(1)<=122)&&58===t.path.charCodeAt(2)?n?t.path.substr(1):t.path[1].toLowerCase()+t.path.substr(2):t.path,e&&(r=r.replace(/\//g,"\\")),r}function y(e,t){const n=t?m:p;let r="",{scheme:i,authority:s,path:o,query:a,fragment:l}=e;if(i&&(r+=i,r+=":"),(s||"file"===i)&&(r+=c,r+=c),s){let e=s.indexOf("@");if(-1!==e){const t=s.substr(0,e);s=s.substr(e+1),e=t.lastIndexOf(":"),-1===e?r+=n(t,!1,!1):(r+=n(t.substr(0,e),!1,!1),r+=":",r+=n(t.substr(e+1),!1,!0)),r+="@"}s=s.toLowerCase(),e=s.lastIndexOf(":"),-1===e?r+=n(s,!1,!0):(r+=n(s.substr(0,e),!1,!0),r+=s.substr(e))}if(o){if(o.length>=3&&47===o.charCodeAt(0)&&58===o.charCodeAt(2)){const e=o.charCodeAt(1);e>=65&&e<=90&&(o=`/${String.fromCharCode(e+32)}:${o.substr(3)}`)}else if(o.length>=2&&58===o.charCodeAt(1)){const e=o.charCodeAt(0);e>=65&&e<=90&&(o=`${String.fromCharCode(e+32)}:${o.substr(2)}`)}r+=n(o,!0,!1)}return a&&(r+="?",r+=n(a,!1,!1)),l&&(r+="#",r+=t?l:p(l,!1,!1)),r}function A(e){try{return decodeURIComponent(e)}catch{return e.length>3?e.substr(0,3)+A(e.substr(3)):e}}const T=/(%[0-9A-Za-z][0-9A-Za-z])+/g;function v(e){return e.match(T)?e.replace(T,(e=>A(e))):e}var R=n(470);const E=R.posix||R,k="/";var x;!function(e){e.joinPath=function(e,...t){return e.with({path:E.join(e.path,...t)})},e.resolvePath=function(e,...t){let n=e.path,r=!1;n[0]!==k&&(n=k+n,r=!0);let i=E.resolve(n,...t);return r&&i[0]===k&&!e.authority&&(i=i.substring(1)),e.with({path:i})},e.dirname=function(e){if(0===e.path.length||e.path===k)return e;let t=E.dirname(e.path);return 1===t.length&&46===t.charCodeAt(0)&&(t=""),e.with({path:t})},e.basename=function(e){return E.basename(e.path)},e.extname=function(e){return E.extname(e.path)}}(x||(x={}))})(),pl=r})();const{URI:vl,Utils:Rl}=pl;var El,kl;!function(e){e.basename=Rl.basename,e.dirname=Rl.dirname,e.extname=Rl.extname,e.joinPath=Rl.joinPath,e.resolvePath=Rl.resolvePath,e.equals=function(e,t){return(null==e?void 0:e.toString())===(null==t?void 0:t.toString())},e.relative=function(e,t){const n="string"==typeof e?e:e.path,r="string"==typeof t?t:t.path,i=n.split("/").filter((e=>e.length>0)),s=r.split("/").filter((e=>e.length>0));let o=0;for(;o<i.length&&i[o]===s[o];o++);return"../".repeat(i.length-o)+s.slice(o).join("/")}}(El||(El={})),function(e){e[e.Changed=0]="Changed",e[e.Parsed=1]="Parsed",e[e.IndexedContent=2]="IndexedContent",e[e.ComputedScopes=3]="ComputedScopes",e[e.Linked=4]="Linked",e[e.IndexedReferences=5]="IndexedReferences",e[e.Validated=6]="Validated"}(kl||(kl={}));class xl{constructor(e){this.serviceRegistry=e.ServiceRegistry,this.textDocuments=e.workspace.TextDocuments,this.fileSystemProvider=e.workspace.FileSystemProvider}async fromUri(e,t=sl.XO.None){const n=await this.fileSystemProvider.readFile(e);return this.createAsync(e,n,t)}fromTextDocument(e,t,n){return t=null!=t?t:vl.parse(e.uri),n?this.createAsync(t,e,n):this.create(t,e)}fromString(e,t,n){return n?this.createAsync(t,e,n):this.create(t,e)}fromModel(e,t){return this.create(t,{$model:e})}create(e,t){if("string"==typeof t){const n=this.parse(e,t);return this.createLangiumDocument(n,e,void 0,t)}if("$model"in t){const n={value:t.$model,parserErrors:[],lexerErrors:[]};return this.createLangiumDocument(n,e)}{const n=this.parse(e,t.getText());return this.createLangiumDocument(n,e,t)}}async createAsync(e,t,n){if("string"==typeof t){const r=await this.parseAsync(e,t,n);return this.createLangiumDocument(r,e,void 0,t)}{const r=await this.parseAsync(e,t.getText(),n);return this.createLangiumDocument(r,e,t)}}createLangiumDocument(e,t,n,r){let i;if(n)i={parseResult:e,uri:t,state:kl.Parsed,references:[],textDocument:n};else{const n=this.createTextDocumentGetter(t,r);i={parseResult:e,uri:t,state:kl.Parsed,references:[],get textDocument(){return n()}}}return e.value.$document=i,i}async update(e,t){var n,r;const i=null===(n=e.parseResult.value.$cstNode)||void 0===n?void 0:n.root.fullText,s=null===(r=this.textDocuments)||void 0===r?void 0:r.get(e.uri.toString()),o=s?s.getText():await this.fileSystemProvider.readFile(e.uri);if(s)Object.defineProperty(e,"textDocument",{value:s});else{const t=this.createTextDocumentGetter(e.uri,o);Object.defineProperty(e,"textDocument",{get:t})}return i!==o&&(e.parseResult=await this.parseAsync(e.uri,o,t),e.parseResult.value.$document=e),e.state=kl.Parsed,e}parse(e,t){return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(t)}parseAsync(e,t,n){return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(t,n)}createTextDocumentGetter(e,t){const n=this.serviceRegistry;let r;return()=>null!=r?r:r=fl.create(e.toString(),n.getServices(e).LanguageMetaData.languageId,0,null!=t?t:"")}}class Il{constructor(e){this.documentMap=new Map,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory}get all(){return m(this.documentMap.values())}addDocument(e){const t=e.uri.toString();if(this.documentMap.has(t))throw new Error(`A document with the URI '${t}' is already present.`);this.documentMap.set(t,e)}getDocument(e){const t=e.toString();return this.documentMap.get(t)}async getOrCreateDocument(e,t){let n=this.getDocument(e);return n||(n=await this.langiumDocumentFactory.fromUri(e,t),this.addDocument(n),n)}createDocument(e,t,n){if(n)return this.langiumDocumentFactory.fromString(t,e,n).then((e=>(this.addDocument(e),e)));{const n=this.langiumDocumentFactory.fromString(t,e);return this.addDocument(n),n}}hasDocument(e){return this.documentMap.has(e.toString())}invalidateDocument(e){const t=e.toString(),n=this.documentMap.get(t);return n&&(n.state=kl.Changed,n.precomputedScopes=void 0,n.references=[],n.diagnostics=void 0),n}deleteDocument(e){const t=e.toString(),n=this.documentMap.get(t);return n&&(n.state=kl.Changed,this.documentMap.delete(t)),n}}class Sl{constructor(e){this.reflection=e.shared.AstReflection,this.langiumDocuments=()=>e.shared.workspace.LangiumDocuments,this.scopeProvider=e.references.ScopeProvider,this.astNodeLocator=e.workspace.AstNodeLocator}async link(e,t=sl.XO.None){for(const n of Ue(e.parseResult.value))await ul(t),Ge(n).forEach((t=>this.doLink(t,e)))}doLink(e,t){const n=e.reference;if(void 0===n._ref)try{const t=this.getCandidate(e);if(s(t))n._ref=t;else if(n._nodeDescription=t,this.langiumDocuments().hasDocument(t.documentUri)){const r=this.loadAstNode(t);n._ref=null!=r?r:this.createLinkingError(e,t)}}catch(r){n._ref=Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${n.$refText}': ${r}`})}t.references.push(n)}unlink(e){for(const t of e.references)delete t._ref,delete t._nodeDescription;e.references=[]}getCandidate(e){const t=this.scopeProvider.getScope(e).getElement(e.reference.$refText);return null!=t?t:this.createLinkingError(e)}buildReference(e,t,n,i){const o=this,a={$refNode:n,$refText:i,get ref(){var n,i;if(r(this._ref))return this._ref;if("object"==typeof(i=this._nodeDescription)&&null!==i&&"string"==typeof i.name&&"string"==typeof i.type&&"string"==typeof i.path){const n=o.loadAstNode(this._nodeDescription);this._ref=null!=n?n:o.createLinkingError({reference:a,container:e,property:t},this._nodeDescription)}else if(void 0===this._ref){const r=o.getLinkedNode({reference:a,container:e,property:t});if(r.error&&Pe(e).state<kl.ComputedScopes)return;this._ref=null!==(n=r.node)&&void 0!==n?n:r.error,this._nodeDescription=r.descr}return r(this._ref)?this._ref:void 0},get $nodeDescription(){return this._nodeDescription},get error(){return s(this._ref)?this._ref:void 0}};return a}getLinkedNode(e){try{const t=this.getCandidate(e);if(s(t))return{error:t};const n=this.loadAstNode(t);return n?{node:n,descr:t}:{descr:t,error:this.createLinkingError(e,t)}}catch(t){return{error:Object.assign(Object.assign({},e),{message:`An error occurred while resolving reference to '${e.reference.$refText}': ${t}`})}}}loadAstNode(e){if(e.node)return e.node;const t=this.langiumDocuments().getDocument(e.documentUri);return t?this.astNodeLocator.getAstNode(t.parseResult.value,e.path):void 0}createLinkingError(e,t){const n=Pe(e.container);n.state<kl.ComputedScopes&&console.warn(`Attempted reference resolution before document reached ComputedScopes state (${n.uri}).`);const r=this.reflection.getReferenceType(e);return Object.assign(Object.assign({},e),{message:`Could not resolve reference to ${r} named '${e.reference.$refText}'.`,targetDescription:t})}}class Nl{getName(e){if(function(e){return"string"==typeof e.name}(e))return e.name}getNameNode(e){return dt(e.$cstNode,"name")}}class Cl{constructor(e){this.nameProvider=e.references.NameProvider,this.index=e.shared.workspace.IndexManager,this.nodeLocator=e.workspace.AstNodeLocator}findDeclaration(e){if(e){const t=function(e){var t;const n=e.astNode;for(;n===(null===(t=e.container)||void 0===t?void 0:t.astNode);){const t=_e(e.grammarSource,ue);if(t)return t;e=e.container}}(e),n=e.astNode;if(t&&n){const r=n[t.feature];if(i(r))return r.ref;if(Array.isArray(r))for(const t of r)if(i(t)&&t.$refNode&&t.$refNode.offset<=e.offset&&t.$refNode.end>=e.end)return t.ref}if(n){const t=this.nameProvider.getNameNode(n);if(t&&(t===e||function(e,t){for(;e.container;)if((e=e.container)===t)return!0;return!1}(e,t)))return n}}}findDeclarationNode(e){const t=this.findDeclaration(e);if(null==t?void 0:t.$cstNode){const e=this.nameProvider.getNameNode(t);return null!=e?e:t.$cstNode}}findReferences(e,t){const n=[];if(t.includeDeclaration){const t=this.getReferenceToSelf(e);t&&n.push(t)}let r=this.index.findAllReferences(e,this.nodeLocator.getAstNodePath(e));return t.documentUri&&(r=r.filter((e=>El.equals(e.sourceUri,t.documentUri)))),n.push(...r),m(n)}getReferenceToSelf(e){const t=this.nameProvider.getNameNode(e);if(t){const n=Pe(e),r=this.nodeLocator.getAstNodePath(e);return{sourceUri:n.uri,sourcePath:r,targetUri:n.uri,targetPath:r,segment:R(t),local:!0}}}}class $l{constructor(e){if(this.map=new Map,e)for(const[t,n]of e)this.add(t,n)}get size(){return y.sum(m(this.map.values()).map((e=>e.length)))}clear(){this.map.clear()}delete(e,t){if(void 0===t)return this.map.delete(e);{const n=this.map.get(e);if(n){const r=n.indexOf(t);if(r>=0)return 1===n.length?this.map.delete(e):n.splice(r,1),!0}return!1}}get(e){var t;return null!==(t=this.map.get(e))&&void 0!==t?t:[]}has(e,t){if(void 0===t)return this.map.has(e);{const n=this.map.get(e);return!!n&&n.indexOf(t)>=0}}add(e,t){return this.map.has(e)?this.map.get(e).push(t):this.map.set(e,[t]),this}addAll(e,t){return this.map.has(e)?this.map.get(e).push(...t):this.map.set(e,Array.from(t)),this}forEach(e){this.map.forEach(((t,n)=>t.forEach((t=>e(t,n,this)))))}[Symbol.iterator](){return this.entries().iterator()}entries(){return m(this.map.entries()).flatMap((([e,t])=>t.map((t=>[e,t]))))}keys(){return m(this.map.keys())}values(){return m(this.map.values()).flat()}entriesGroupedByKey(){return m(this.map.entries())}}class wl{get size(){return this.map.size}constructor(e){if(this.map=new Map,this.inverse=new Map,e)for(const[t,n]of e)this.set(t,n)}clear(){this.map.clear(),this.inverse.clear()}set(e,t){return this.map.set(e,t),this.inverse.set(t,e),this}get(e){return this.map.get(e)}getKey(e){return this.inverse.get(e)}delete(e){const t=this.map.get(e);return void 0!==t&&(this.map.delete(e),this.inverse.delete(t),!0)}}class Ll{constructor(e){this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider}async computeExports(e,t=sl.XO.None){return this.computeExportsForNode(e.parseResult.value,e,void 0,t)}async computeExportsForNode(e,t,n=Me,r=sl.XO.None){const i=[];this.exportNode(e,i,t);for(const s of n(e))await ul(r),this.exportNode(s,i,t);return i}exportNode(e,t,n){const r=this.nameProvider.getName(e);r&&t.push(this.descriptions.createDescription(e,r,n))}async computeLocalScopes(e,t=sl.XO.None){const n=e.parseResult.value,r=new $l;for(const i of De(n))await ul(t),this.processNode(i,e,r);return r}processNode(e,t,n){const r=e.$container;if(r){const i=this.nameProvider.getName(e);i&&n.add(r,this.descriptions.createDescription(e,i,t))}}}class Ol{constructor(e,t,n){var r;this.elements=e,this.outerScope=t,this.caseInsensitive=null!==(r=null==n?void 0:n.caseInsensitive)&&void 0!==r&&r}getAllElements(){return this.outerScope?this.elements.concat(this.outerScope.getAllElements()):this.elements}getElement(e){const t=this.caseInsensitive?this.elements.find((t=>t.name.toLowerCase()===e.toLowerCase())):this.elements.find((t=>t.name===e));return t||(this.outerScope?this.outerScope.getElement(e):void 0)}}class bl{constructor(e,t,n){var r;this.elements=new Map,this.caseInsensitive=null!==(r=null==n?void 0:n.caseInsensitive)&&void 0!==r&&r;for(const i of e){const e=this.caseInsensitive?i.name.toLowerCase():i.name;this.elements.set(e,i)}this.outerScope=t}getElement(e){const t=this.caseInsensitive?e.toLowerCase():e,n=this.elements.get(t);return n||(this.outerScope?this.outerScope.getElement(e):void 0)}getAllElements(){let e=m(this.elements.values());return this.outerScope&&(e=e.concat(this.outerScope.getAllElements())),e}}class _l{constructor(){this.toDispose=[],this.isDisposed=!1}onDispose(e){this.toDispose.push(e)}dispose(){this.throwIfDisposed(),this.clear(),this.isDisposed=!0,this.toDispose.forEach((e=>e.dispose()))}throwIfDisposed(){if(this.isDisposed)throw new Error("This cache has already been disposed")}}class Pl extends _l{constructor(){super(...arguments),this.cache=new Map}has(e){return this.throwIfDisposed(),this.cache.has(e)}set(e,t){this.throwIfDisposed(),this.cache.set(e,t)}get(e,t){if(this.throwIfDisposed(),this.cache.has(e))return this.cache.get(e);if(t){const n=t();return this.cache.set(e,n),n}}delete(e){return this.throwIfDisposed(),this.cache.delete(e)}clear(){this.throwIfDisposed(),this.cache.clear()}}class Ml extends _l{constructor(e){super(),this.cache=new Map,this.converter=null!=e?e:e=>e}has(e,t){return this.throwIfDisposed(),this.cacheForContext(e).has(t)}set(e,t,n){this.throwIfDisposed(),this.cacheForContext(e).set(t,n)}get(e,t,n){this.throwIfDisposed();const r=this.cacheForContext(e);if(r.has(t))return r.get(t);if(n){const e=n();return r.set(t,e),e}}delete(e,t){return this.throwIfDisposed(),this.cacheForContext(e).delete(t)}clear(e){if(this.throwIfDisposed(),e){const t=this.converter(e);this.cache.delete(t)}else this.cache.clear()}cacheForContext(e){const t=this.converter(e);let n=this.cache.get(t);return n||(n=new Map,this.cache.set(t,n)),n}}class Dl extends Pl{constructor(e){super(),this.onDispose(e.workspace.DocumentBuilder.onUpdate((()=>{this.clear()})))}}class Ul{constructor(e){this.reflection=e.shared.AstReflection,this.nameProvider=e.references.NameProvider,this.descriptions=e.workspace.AstNodeDescriptionProvider,this.indexManager=e.shared.workspace.IndexManager,this.globalScopeCache=new Dl(e.shared)}getScope(e){const t=[],n=this.reflection.getReferenceType(e),r=Pe(e.container).precomputedScopes;if(r){let i=e.container;do{const e=r.get(i);e.length>0&&t.push(m(e).filter((e=>this.reflection.isSubtype(e.type,n)))),i=i.$container}while(i)}let i=this.getGlobalScope(n,e);for(let s=t.length-1;s>=0;s--)i=this.createScope(t[s],i);return i}createScope(e,t,n){return new Ol(m(e),t,n)}createScopeForNodes(e,t,n){const r=m(e).map((e=>{const t=this.nameProvider.getName(e);if(t)return this.descriptions.createDescription(e,t)})).nonNullable();return new Ol(r,t,n)}getGlobalScope(e,t){return this.globalScopeCache.get(e,(()=>new bl(this.indexManager.allElements(e))))}}function Fl(e){return"object"==typeof e&&!!e&&("$ref"in e||"$error"in e)}class Gl{constructor(e){this.ignoreProperties=new Set(["$container","$containerProperty","$containerIndex","$document","$cstNode"]),this.langiumDocuments=e.shared.workspace.LangiumDocuments,this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider,this.commentProvider=e.documentation.CommentProvider}serialize(e,t={}){const n=null==t?void 0:t.replacer,r=(e,n)=>this.replacer(e,n,t),i=n?(e,t)=>n(e,t,r):r;try{return this.currentDocument=Pe(e),JSON.stringify(e,i,null==t?void 0:t.space)}finally{this.currentDocument=void 0}}deserialize(e,t={}){const n=JSON.parse(e);return this.linkNode(n,n,t),n}replacer(e,t,{refText:n,sourceText:s,textRegions:o,comments:a,uriConverter:c}){var l,u,d,h;if(!this.ignoreProperties.has(e)){if(i(t)){const e=t.ref,r=n?t.$refText:void 0;if(e){const n=Pe(e);let i="";this.currentDocument&&this.currentDocument!==n&&(i=c?c(n.uri,t):n.uri.toString());return{$ref:`${i}#${this.astNodeLocator.getAstNodePath(e)}`,$refText:r}}return{$error:null!==(u=null===(l=t.error)||void 0===l?void 0:l.message)&&void 0!==u?u:"Could not resolve reference",$refText:r}}if(r(t)){let n;if(o&&(n=this.addAstNodeRegionWithAssignmentsTo(Object.assign({},t)),e&&!t.$document||!(null==n?void 0:n.$textRegion)||(n.$textRegion.documentURI=null===(d=this.currentDocument)||void 0===d?void 0:d.uri.toString())),s&&!e&&(null!=n||(n=Object.assign({},t)),n.$sourceText=null===(h=t.$cstNode)||void 0===h?void 0:h.text),a){null!=n||(n=Object.assign({},t));const e=this.commentProvider.getComment(t);e&&(n.$comment=e.replace(/\r/g,""))}return null!=n?n:t}return t}}addAstNodeRegionWithAssignmentsTo(e){const t=e=>({offset:e.offset,end:e.end,length:e.length,range:e.range});if(e.$cstNode){const n=(e.$textRegion=t(e.$cstNode)).assignments={};return Object.keys(e).filter((e=>!e.startsWith("$"))).forEach((r=>{const i=function(e,t){return e&&t?ht(e,t,e.astNode,!0):[]}(e.$cstNode,r).map(t);0!==i.length&&(n[r]=i)})),e}}linkNode(e,t,n,i,s,o){for(const[c,l]of Object.entries(e))if(Array.isArray(l))for(let i=0;i<l.length;i++){const s=l[i];Fl(s)?l[i]=this.reviveReference(e,c,t,s,n):r(s)&&this.linkNode(s,t,n,e,c,i)}else Fl(l)?e[c]=this.reviveReference(e,c,t,l,n):r(l)&&this.linkNode(l,t,n,e,c);const a=e;a.$container=i,a.$containerProperty=s,a.$containerIndex=o}reviveReference(e,t,n,i,s){let o=i.$refText,a=i.$error;if(i.$ref){const e=this.getRefNode(n,i.$ref,s.uriConverter);if(r(e))return o||(o=this.nameProvider.getName(e)),{$refText:null!=o?o:"",ref:e};a=e}if(a){const n={$refText:null!=o?o:""};return n.error={container:e,property:t,message:a,reference:n},n}}getRefNode(e,t,n){try{const r=t.indexOf("#");if(0===r){const n=this.astNodeLocator.getAstNode(e,t.substring(1));return n||"Could not resolve path: "+t}if(r<0){const e=n?n(t):vl.parse(t),r=this.langiumDocuments.getDocument(e);return r?r.parseResult.value:"Could not find document for URI: "+t}const i=n?n(t.substring(0,r)):vl.parse(t.substring(0,r)),s=this.langiumDocuments.getDocument(i);if(!s)return"Could not find document for URI: "+t;if(r===t.length-1)return s.parseResult.value;const o=this.astNodeLocator.getAstNode(s.parseResult.value,t.substring(r+1));return o||"Could not resolve URI: "+t}catch(r){return String(r)}}}class Kl{register(e){if(this.singleton||this.map){if(!this.map&&(this.map={},this.singleton)){for(const e of this.singleton.LanguageMetaData.fileExtensions)this.map[e]=this.singleton;this.singleton=void 0}for(const t of e.LanguageMetaData.fileExtensions)void 0!==this.map[t]&&this.map[t]!==e&&console.warn(`The file extension ${t} is used by multiple languages. It is now assigned to '${e.LanguageMetaData.languageId}'.`),this.map[t]=e}else this.singleton=e}getServices(e){if(void 0!==this.singleton)return this.singleton;if(void 0===this.map)throw new Error("The service registry is empty. Use `register` to register the services of a language.");const t=El.extname(e),n=this.map[t];if(!n)throw new Error(`The service registry contains no services for the extension '${t}'.`);return n}get all(){return void 0!==this.singleton?[this.singleton]:void 0!==this.map?Object.values(this.map):[]}}function Bl(e){return{code:e}}var jl,Vl,Hl;!function(e){e.all=["fast","slow","built-in"]}(jl||(jl={}));class Wl{constructor(e){this.entries=new $l,this.reflection=e.shared.AstReflection}register(e,t=this,n="fast"){if("built-in"===n)throw new Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");for(const[r,i]of Object.entries(e)){const e=i;if(Array.isArray(e))for(const i of e){const e={check:this.wrapValidationException(i,t),category:n};this.addEntry(r,e)}else if("function"==typeof e){const i={check:this.wrapValidationException(e,t),category:n};this.addEntry(r,i)}}}wrapValidationException(e,t){return async(n,r,i)=>{try{await e.call(t,n,r,i)}catch(s){if(ll(s))throw s;console.error("An error occurred during validation:",s);const e=s instanceof Error?s.message:String(s);s instanceof Error&&s.stack&&console.error(s.stack),r("error","An error occurred during validation: "+e,{node:n})}}}addEntry(e,t){if("AstNode"!==e)for(const n of this.reflection.getAllSubTypes(e))this.entries.add(n,t);else this.entries.add("AstNode",t)}getChecks(e,t){let n=m(this.entries.get(e)).concat(this.entries.get("AstNode"));return t&&(n=n.filter((e=>t.includes(e.category)))),n.map((e=>e.check))}}class zl{constructor(e){this.validationRegistry=e.validation.ValidationRegistry,this.metadata=e.LanguageMetaData}async validateDocument(e,t={},n=sl.XO.None){const r=e.parseResult,i=[];if(await ul(n),!t.categories||t.categories.includes("built-in")){if(this.processLexingErrors(r,i,t),t.stopAfterLexingErrors&&i.some((e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===Vl.LexingError})))return i;if(this.processParsingErrors(r,i,t),t.stopAfterParsingErrors&&i.some((e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===Vl.ParsingError})))return i;if(this.processLinkingErrors(e,i,t),t.stopAfterLinkingErrors&&i.some((e=>{var t;return(null===(t=e.data)||void 0===t?void 0:t.code)===Vl.LinkingError})))return i}try{i.push(...await this.validateAst(r.value,t,n))}catch(s){if(ll(s))throw s;console.error("An error occurred during validation:",s)}return await ul(n),i}processLexingErrors(e,t,n){for(const r of e.lexerErrors){const e={severity:Xl("error"),range:{start:{line:r.line-1,character:r.column-1},end:{line:r.line-1,character:r.column+r.length-1}},message:r.message,data:Bl(Vl.LexingError),source:this.getSource()};t.push(e)}}processParsingErrors(e,t,n){for(const r of e.parserErrors){let e;if(isNaN(r.token.startOffset)){if("previousToken"in r){const t=r.previousToken;if(isNaN(t.startOffset)){const t={line:0,character:0};e={start:t,end:t}}else{const n={line:t.endLine-1,character:t.endColumn};e={start:n,end:n}}}}else e=v(r.token);if(e){const n={severity:Xl("error"),range:e,message:r.message,data:Bl(Vl.ParsingError),source:this.getSource()};t.push(n)}}}processLinkingErrors(e,t,n){for(const r of e.references){const e=r.error;if(e){const n={node:e.container,property:e.property,index:e.index,data:{code:Vl.LinkingError,containerType:e.container.$type,property:e.property,refText:e.reference.$refText}};t.push(this.toDiagnostic("error",e.message,n))}}}async validateAst(e,t,n=sl.XO.None){const r=[],i=(e,t,n)=>{r.push(this.toDiagnostic(e,t,n))};return await Promise.all(Ue(e).map((async e=>{await ul(n);const r=this.validationRegistry.getChecks(e.$type,t.categories);for(const t of r)await t(e,i,n)}))),r}toDiagnostic(e,t,n){return{message:t,range:Yl(n),severity:Xl(e),code:n.code,codeDescription:n.codeDescription,tags:n.tags,relatedInformation:n.relatedInformation,data:n.data,source:this.getSource()}}getSource(){return this.metadata.languageId}}function Yl(e){if(e.range)return e.range;let t;return"string"==typeof e.property?t=dt(e.node.$cstNode,e.property,e.index):"string"==typeof e.keyword&&(t=function(e,t,n){if(!e)return;const r=ft(e,t,null==e?void 0:e.astNode);return 0!==r.length?r[n=void 0!==n?Math.max(0,Math.min(n,r.length-1)):0]:void 0}(e.node.$cstNode,e.keyword,e.index)),null!=t||(t=e.node.$cstNode),t?t.range:{start:{line:0,character:0},end:{line:0,character:0}}}function Xl(e){switch(e){case"error":return 1;case"warning":return 2;case"info":return 3;case"hint":return 4;default:throw new Error("Invalid diagnostic severity: "+e)}}!function(e){e.LexingError="lexing-error",e.ParsingError="parsing-error",e.LinkingError="linking-error"}(Vl||(Vl={}));class ql{constructor(e){this.astNodeLocator=e.workspace.AstNodeLocator,this.nameProvider=e.references.NameProvider}createDescription(e,t,n=Pe(e)){null!=t||(t=this.nameProvider.getName(e));const r=this.astNodeLocator.getAstNodePath(e);if(!t)throw new Error(`Node at path ${r} has no name.`);let i;const s=()=>{var t;return null!=i?i:i=R(null!==(t=this.nameProvider.getNameNode(e))&&void 0!==t?t:e.$cstNode)};return{node:e,name:t,get nameSegment(){return s()},selectionSegment:R(e.$cstNode),type:e.$type,documentUri:n.uri,path:r}}}class Ql{constructor(e){this.nodeLocator=e.workspace.AstNodeLocator}async createDescriptions(e,t=sl.XO.None){const n=[],r=e.parseResult.value;for(const i of Ue(r))await ul(t),Ge(i).filter((e=>!s(e))).forEach((e=>{const t=this.createDescription(e);t&&n.push(t)}));return n}createDescription(e){const t=e.reference.$nodeDescription,n=e.reference.$refNode;if(!t||!n)return;const r=Pe(e.container).uri;return{sourceUri:r,sourcePath:this.nodeLocator.getAstNodePath(e.container),targetUri:t.documentUri,targetPath:t.path,segment:R(n),local:El.equals(t.documentUri,r)}}}class Jl{constructor(){this.segmentSeparator="/",this.indexSeparator="@"}getAstNodePath(e){if(e.$container){const t=this.getAstNodePath(e.$container),n=this.getPathSegment(e);return t+this.segmentSeparator+n}return""}getPathSegment({$containerProperty:e,$containerIndex:t}){if(!e)throw new Error("Missing '$containerProperty' in AST node.");return void 0!==t?e+this.indexSeparator+t:e}getAstNode(e,t){return t.split(this.segmentSeparator).reduce(((e,t)=>{if(!e||0===t.length)return e;const n=t.indexOf(this.indexSeparator);if(n>0){const r=t.substring(0,n),i=parseInt(t.substring(n+1)),s=e[r];return null==s?void 0:s[i]}return e[t]}),e)}}class Zl{constructor(e){this._ready=new dl,this.settings={},this.workspaceConfig=!1,this.serviceRegistry=e.ServiceRegistry}get ready(){return this._ready.promise}initialize(e){var t,n;this.workspaceConfig=null!==(n=null===(t=e.capabilities.workspace)||void 0===t?void 0:t.configuration)&&void 0!==n&&n}async initialized(e){if(this.workspaceConfig){if(e.register){const t=this.serviceRegistry.all;e.register({section:t.map((e=>this.toSectionName(e.LanguageMetaData.languageId)))})}if(e.fetchConfiguration){const t=this.serviceRegistry.all.map((e=>({section:this.toSectionName(e.LanguageMetaData.languageId)}))),n=await e.fetchConfiguration(t);t.forEach(((e,t)=>{this.updateSectionConfiguration(e.section,n[t])}))}}this._ready.resolve()}updateConfiguration(e){e.settings&&Object.keys(e.settings).forEach((t=>{this.updateSectionConfiguration(t,e.settings[t])}))}updateSectionConfiguration(e,t){this.settings[e]=t}async getConfiguration(e,t){await this.ready;const n=this.toSectionName(e);if(this.settings[n])return this.settings[n][t]}toSectionName(e){return`${e}`}}!function(e){e.create=function(e){return{dispose:async()=>await e()}}}(Hl||(Hl={}));class eu{constructor(e){this.updateBuildOptions={validation:{categories:["built-in","fast"]}},this.updateListeners=[],this.buildPhaseListeners=new $l,this.buildState=new Map,this.documentBuildWaiters=new Map,this.currentState=kl.Changed,this.langiumDocuments=e.workspace.LangiumDocuments,this.langiumDocumentFactory=e.workspace.LangiumDocumentFactory,this.indexManager=e.workspace.IndexManager,this.serviceRegistry=e.ServiceRegistry}async build(e,t={},n=sl.XO.None){var r,i;for(const s of e){const e=s.uri.toString();if(s.state===kl.Validated){if("boolean"==typeof t.validation&&t.validation)s.state=kl.IndexedReferences,s.diagnostics=void 0,this.buildState.delete(e);else if("object"==typeof t.validation){const n=this.buildState.get(e),o=null===(r=null==n?void 0:n.result)||void 0===r?void 0:r.validationChecks;if(o){const r=(null!==(i=t.validation.categories)&&void 0!==i?i:jl.all).filter((e=>!o.includes(e)));r.length>0&&(this.buildState.set(e,{completed:!1,options:{validation:Object.assign(Object.assign({},t.validation),{categories:r})},result:n.result}),s.state=kl.IndexedReferences)}}}else this.buildState.delete(e)}this.currentState=kl.Changed,await this.emitUpdate(e.map((e=>e.uri)),[]),await this.buildDocuments(e,t,n)}async update(e,t,n=sl.XO.None){this.currentState=kl.Changed;for(const s of t)this.langiumDocuments.deleteDocument(s),this.buildState.delete(s.toString()),this.indexManager.remove(s);for(const s of e){if(!this.langiumDocuments.invalidateDocument(s)){const e=this.langiumDocumentFactory.fromModel({$type:"INVALID"},s);e.state=kl.Changed,this.langiumDocuments.addDocument(e)}this.buildState.delete(s.toString())}const r=m(e).concat(t).map((e=>e.toString())).toSet();this.langiumDocuments.all.filter((e=>!r.has(e.uri.toString())&&this.shouldRelink(e,r))).forEach((e=>{this.serviceRegistry.getServices(e.uri).references.Linker.unlink(e),e.state=Math.min(e.state,kl.ComputedScopes),e.diagnostics=void 0})),await this.emitUpdate(e,t),await ul(n);const i=this.langiumDocuments.all.filter((e=>{var t;return e.state<kl.Linked||!(null===(t=this.buildState.get(e.uri.toString()))||void 0===t?void 0:t.completed)})).toArray();await this.buildDocuments(i,this.updateBuildOptions,n)}async emitUpdate(e,t){await Promise.all(this.updateListeners.map((n=>n(e,t))))}shouldRelink(e,t){return!!e.references.some((e=>void 0!==e.error))||this.indexManager.isAffected(e,t)}onUpdate(e){return this.updateListeners.push(e),Hl.create((()=>{const t=this.updateListeners.indexOf(e);t>=0&&this.updateListeners.splice(t,1)}))}async buildDocuments(e,t,n){this.prepareBuild(e,t),await this.runCancelable(e,kl.Parsed,n,(e=>this.langiumDocumentFactory.update(e,n))),await this.runCancelable(e,kl.IndexedContent,n,(e=>this.indexManager.updateContent(e,n))),await this.runCancelable(e,kl.ComputedScopes,n,(async e=>{const t=this.serviceRegistry.getServices(e.uri).references.ScopeComputation;e.precomputedScopes=await t.computeLocalScopes(e,n)})),await this.runCancelable(e,kl.Linked,n,(e=>this.serviceRegistry.getServices(e.uri).references.Linker.link(e,n))),await this.runCancelable(e,kl.IndexedReferences,n,(e=>this.indexManager.updateReferences(e,n)));const r=e.filter((e=>this.shouldValidate(e)));await this.runCancelable(r,kl.Validated,n,(e=>this.validate(e,n)));for(const i of e){const e=this.buildState.get(i.uri.toString());e&&(e.completed=!0)}}prepareBuild(e,t){for(const n of e){const e=n.uri.toString(),r=this.buildState.get(e);r&&!r.completed||this.buildState.set(e,{completed:!1,options:t,result:null==r?void 0:r.result})}}async runCancelable(e,t,n,r){const i=e.filter((e=>e.state<t));for(const s of i)await ul(n),await r(s),s.state=t;await this.notifyBuildPhase(i,t,n),this.currentState=t}onBuildPhase(e,t){return this.buildPhaseListeners.add(e,t),Hl.create((()=>{this.buildPhaseListeners.delete(e,t)}))}waitUntil(e,t,n){let r;if(t&&"path"in t?r=t:n=t,null!=n||(n=sl.XO.None),r){const t=this.langiumDocuments.getDocument(r);if(t&&t.state>e)return Promise.resolve(r)}return this.currentState>=e?Promise.resolve(void 0):n.isCancellationRequested?Promise.reject(cl):new Promise(((t,i)=>{const s=this.onBuildPhase(e,(()=>{if(s.dispose(),o.dispose(),r){const e=this.langiumDocuments.getDocument(r);t(null==e?void 0:e.uri)}else t(void 0)})),o=n.onCancellationRequested((()=>{s.dispose(),o.dispose(),i(cl)}))}))}async notifyBuildPhase(e,t,n){if(0===e.length)return;const r=this.buildPhaseListeners.get(t);for(const i of r)await ul(n),await i(e,n)}shouldValidate(e){return Boolean(this.getBuildOptions(e).validation)}async validate(e,t){var n,r;const i=this.serviceRegistry.getServices(e.uri).validation.DocumentValidator,s=this.getBuildOptions(e).validation,o="object"==typeof s?s:void 0,a=await i.validateDocument(e,o,t);e.diagnostics?e.diagnostics.push(...a):e.diagnostics=a;const c=this.buildState.get(e.uri.toString());if(c){null!==(n=c.result)&&void 0!==n||(c.result={});const e=null!==(r=null==o?void 0:o.categories)&&void 0!==r?r:jl.all;c.result.validationChecks?c.result.validationChecks.push(...e):c.result.validationChecks=[...e]}}getBuildOptions(e){var t,n;return null!==(n=null===(t=this.buildState.get(e.uri.toString()))||void 0===t?void 0:t.options)&&void 0!==n?n:{}}}class tu{constructor(e){this.symbolIndex=new Map,this.symbolByTypeIndex=new Ml,this.referenceIndex=new Map,this.documents=e.workspace.LangiumDocuments,this.serviceRegistry=e.ServiceRegistry,this.astReflection=e.AstReflection}findAllReferences(e,t){const n=Pe(e).uri,r=[];return this.referenceIndex.forEach((e=>{e.forEach((e=>{El.equals(e.targetUri,n)&&e.targetPath===t&&r.push(e)}))})),m(r)}allElements(e,t){let n=m(this.symbolIndex.keys());return t&&(n=n.filter((e=>!t||t.has(e)))),n.map((t=>this.getFileDescriptions(t,e))).flat()}getFileDescriptions(e,t){var n;if(!t)return null!==(n=this.symbolIndex.get(e))&&void 0!==n?n:[];const r=this.symbolByTypeIndex.get(e,t,(()=>{var n;return(null!==(n=this.symbolIndex.get(e))&&void 0!==n?n:[]).filter((e=>this.astReflection.isSubtype(e.type,t)))}));return r}remove(e){const t=e.toString();this.symbolIndex.delete(t),this.symbolByTypeIndex.clear(t),this.referenceIndex.delete(t)}async updateContent(e,t=sl.XO.None){const n=this.serviceRegistry.getServices(e.uri),r=await n.references.ScopeComputation.computeExports(e,t),i=e.uri.toString();this.symbolIndex.set(i,r),this.symbolByTypeIndex.clear(i)}async updateReferences(e,t=sl.XO.None){const n=this.serviceRegistry.getServices(e.uri),r=await n.workspace.ReferenceDescriptionProvider.createDescriptions(e,t);this.referenceIndex.set(e.uri.toString(),r)}isAffected(e,t){const n=this.referenceIndex.get(e.uri.toString());return!!n&&n.some((e=>!e.local&&t.has(e.targetUri.toString())))}}class nu{constructor(e){this.initialBuildOptions={},this._ready=new dl,this.serviceRegistry=e.ServiceRegistry,this.langiumDocuments=e.workspace.LangiumDocuments,this.documentBuilder=e.workspace.DocumentBuilder,this.fileSystemProvider=e.workspace.FileSystemProvider,this.mutex=e.workspace.WorkspaceLock}get ready(){return this._ready.promise}initialize(e){var t;this.folders=null!==(t=e.workspaceFolders)&&void 0!==t?t:void 0}initialized(e){return this.mutex.write((e=>{var t;return this.initializeWorkspace(null!==(t=this.folders)&&void 0!==t?t:[],e)}))}async initializeWorkspace(e,t=sl.XO.None){const n=await this.performStartup(e);await ul(t),await this.documentBuilder.build(n,this.initialBuildOptions,t)}async performStartup(e){const t=this.serviceRegistry.all.flatMap((e=>e.LanguageMetaData.fileExtensions)),n=[],r=e=>{n.push(e),this.langiumDocuments.hasDocument(e.uri)||this.langiumDocuments.addDocument(e)};return await this.loadAdditionalDocuments(e,r),await Promise.all(e.map((e=>[e,this.getRootFolder(e)])).map((async e=>this.traverseFolder(...e,t,r)))),this._ready.resolve(),n}loadAdditionalDocuments(e,t){return Promise.resolve()}getRootFolder(e){return vl.parse(e.uri)}async traverseFolder(e,t,n,r){const i=await this.fileSystemProvider.readDirectory(t);await Promise.all(i.map((async t=>{if(this.includeEntry(e,t,n))if(t.isDirectory)await this.traverseFolder(e,t.uri,n,r);else if(t.isFile){const e=await this.langiumDocuments.getOrCreateDocument(t.uri);r(e)}})))}includeEntry(e,t,n){const r=El.basename(t.uri);if(r.startsWith("."))return!1;if(t.isDirectory)return"node_modules"!==r&&"out"!==r;if(t.isFile){const e=El.extname(t.uri);return n.includes(e)}return!1}}class ru{constructor(e){const t=e.parser.TokenBuilder.buildTokens(e.Grammar,{caseInsensitive:e.LanguageMetaData.caseInsensitive});this.tokenTypes=this.toTokenTypeDictionary(t);const n=su(t)?Object.values(t):t;this.chevrotainLexer=new ii(n,{positionTracking:"full"})}get definition(){return this.tokenTypes}tokenize(e){var t;const n=this.chevrotainLexer.tokenize(e);return{tokens:n.tokens,errors:n.errors,hidden:null!==(t=n.groups.hidden)&&void 0!==t?t:[]}}toTokenTypeDictionary(e){if(su(e))return e;const t=iu(e)?Object.values(e.modes).flat():e,n={};return t.forEach((e=>n[e.name]=e)),n}}function iu(e){return e&&"modes"in e&&"defaultMode"in e}function su(e){return!function(e){return Array.isArray(e)&&(0===e.length||"name"in e[0])}(e)&&!iu(e)}function ou(e,t,n){let r,i;"string"==typeof e?(i=t,r=n):(i=e.range.start,r=t),i||(i=ca.create(0,0));const s=function(e){var t,n,r;const i=[];let s=e.position.line,o=e.position.character;for(let a=0;a<e.lines.length;a++){const c=0===a,l=a===e.lines.length-1;let u=e.lines[a],d=0;if(c&&e.options.start){const n=null===(t=e.options.start)||void 0===t?void 0:t.exec(u);n&&(d=n.index+n[0].length)}else{const t=null===(n=e.options.line)||void 0===n?void 0:n.exec(u);t&&(d=t.index+t[0].length)}if(l){const t=null===(r=e.options.end)||void 0===r?void 0:r.exec(u);t&&(u=u.substring(0,t.index))}u=u.substring(0,pu(u));if(fu(u,d)>=u.length){if(i.length>0){const e=ca.create(s,o);i.push({type:"break",content:"",range:la.create(e,e)})}}else{cu.lastIndex=d;const e=cu.exec(u);if(e){const t=e[0],n=e[1],r=ca.create(s,o+d),a=ca.create(s,o+d+t.length);i.push({type:"tag",content:n,range:la.create(r,a)}),d+=t.length,d=fu(u,d)}if(d<u.length){const e=u.substring(d),t=Array.from(e.matchAll(lu));i.push(...uu(t,e,s,o+d))}}s++,o=0}if(i.length>0&&"break"===i[i.length-1].type)return i.slice(0,-1);return i}({lines:au(e),position:i,options:vu(r)});return function(e){var t,n,r,i;const s=ca.create(e.position.line,e.position.character);if(0===e.tokens.length)return new Eu([],la.create(s,s));const o=[];for(;e.index<e.tokens.length;){const t=mu(e,o[o.length-1]);t&&o.push(t)}const a=null!==(n=null===(t=o[0])||void 0===t?void 0:t.range.start)&&void 0!==n?n:s,c=null!==(i=null===(r=o[o.length-1])||void 0===r?void 0:r.range.end)&&void 0!==i?i:s;return new Eu(o,la.create(a,c))}({index:0,tokens:s,position:i})}function au(e){let t="";t="string"==typeof e?e:e.text;return t.split(nt)}const cu=/\s*(@([\p{L}][\p{L}\p{N}]*)?)/uy,lu=/\{(@[\p{L}][\p{L}\p{N}]*)(\s*)([^\r\n}]+)?\}/gu;function uu(e,t,n,r){const i=[];if(0===e.length){const e=ca.create(n,r),s=ca.create(n,r+t.length);i.push({type:"text",content:t,range:la.create(e,s)})}else{let s=0;for(const a of e){const e=a.index,o=t.substring(s,e);o.length>0&&i.push({type:"text",content:t.substring(s,e),range:la.create(ca.create(n,s+r),ca.create(n,e+r))});let c=o.length+1;const l=a[1];if(i.push({type:"inline-tag",content:l,range:la.create(ca.create(n,s+c+r),ca.create(n,s+c+l.length+r))}),c+=l.length,4===a.length){c+=a[2].length;const e=a[3];i.push({type:"text",content:e,range:la.create(ca.create(n,s+c+r),ca.create(n,s+c+e.length+r))})}else i.push({type:"text",content:"",range:la.create(ca.create(n,s+c+r),ca.create(n,s+c+r))});s=e+a[0].length}const o=t.substring(s);o.length>0&&i.push({type:"text",content:o,range:la.create(ca.create(n,s+r),ca.create(n,s+r+o.length))})}return i}const du=/\S/,hu=/\s*$/;function fu(e,t){const n=e.substring(t).match(du);return n?t+n.index:e.length}function pu(e){const t=e.match(hu);if(t&&"number"==typeof t.index)return t.index}function mu(e,t){const n=e.tokens[e.index];return"tag"===n.type?Au(e,!1):"text"===n.type||"inline-tag"===n.type?gu(e):(function(e,t){if(t){const n=new Iu("",e.range);"inlines"in t?t.inlines.push(n):t.content.inlines.push(n)}}(n,t),void e.index++)}function gu(e){let t=e.tokens[e.index];const n=t;let r=t;const i=[];for(;t&&"break"!==t.type&&"tag"!==t.type;)i.push(yu(e)),r=t,t=e.tokens[e.index];return new xu(i,la.create(n.range.start,r.range.end))}function yu(e){return"inline-tag"===e.tokens[e.index].type?Au(e,!0):Tu(e)}function Au(e,t){const n=e.tokens[e.index++],r=n.content.substring(1),i=e.tokens[e.index];if("text"===(null==i?void 0:i.type)){if(t){const i=Tu(e);return new ku(r,new xu([i],i.range),t,la.create(n.range.start,i.range.end))}{const i=gu(e);return new ku(r,i,t,la.create(n.range.start,i.range.end))}}{const e=n.range;return new ku(r,new xu([],e),t,e)}}function Tu(e){const t=e.tokens[e.index++];return new Iu(t.content,t.range)}function vu(e){if(!e)return vu({start:"/**",end:"*/",line:"*"});const{start:t,end:n,line:r}=e;return{start:Ru(t,!0),end:Ru(n,!1),line:Ru(r,!0)}}function Ru(e,t){if("string"==typeof e||"object"==typeof e){const n="string"==typeof e?at(e):e.source;return t?new RegExp(`^\\s*${n}`):new RegExp(`\\s*${n}\\s*$`)}return e}class Eu{constructor(e,t){this.elements=e,this.range=t}getTag(e){return this.getAllTags().find((t=>t.name===e))}getTags(e){return this.getAllTags().filter((t=>t.name===e))}getAllTags(){return this.elements.filter((e=>"name"in e))}toString(){let e="";for(const t of this.elements)if(0===e.length)e=t.toString();else{const n=t.toString();e+=Su(e)+n}return e.trim()}toMarkdown(e){let t="";for(const n of this.elements)if(0===t.length)t=n.toMarkdown(e);else{const r=n.toMarkdown(e);t+=Su(t)+r}return t.trim()}}class ku{constructor(e,t,n,r){this.name=e,this.content=t,this.inline=n,this.range=r}toString(){let e=`@${this.name}`;const t=this.content.toString();return 1===this.content.inlines.length?e=`${e} ${t}`:this.content.inlines.length>1&&(e=`${e}\n${t}`),this.inline?`{${e}}`:e}toMarkdown(e){var t,n;return null!==(n=null===(t=null==e?void 0:e.renderTag)||void 0===t?void 0:t.call(e,this))&&void 0!==n?n:this.toMarkdownDefault(e)}toMarkdownDefault(e){const t=this.content.toMarkdown(e);if(this.inline){const n=function(e,t,n){var r,i;if("linkplain"===e||"linkcode"===e||"link"===e){const s=t.indexOf(" ");let o=t;if(s>0){const e=fu(t,s);o=t.substring(e),t=t.substring(0,s)}("linkcode"===e||"link"===e&&"code"===n.link)&&(o=`\`${o}\``);const a=null!==(i=null===(r=n.renderLink)||void 0===r?void 0:r.call(n,t,o))&&void 0!==i?i:function(e,t){try{return vl.parse(e,!0),`[${t}](${e})`}catch(r){return e}}(t,o);return a}return}(this.name,t,null!=e?e:{});if("string"==typeof n)return n}let n="";"italic"===(null==e?void 0:e.tag)||void 0===(null==e?void 0:e.tag)?n="*":"bold"===(null==e?void 0:e.tag)?n="**":"bold-italic"===(null==e?void 0:e.tag)&&(n="***");let r=`${n}@${this.name}${n}`;return 1===this.content.inlines.length?r=`${r} \u2014 ${t}`:this.content.inlines.length>1&&(r=`${r}\n${t}`),this.inline?`{${r}}`:r}}class xu{constructor(e,t){this.inlines=e,this.range=t}toString(){let e="";for(let t=0;t<this.inlines.length;t++){const n=this.inlines[t],r=this.inlines[t+1];e+=n.toString(),r&&r.range.start.line>n.range.start.line&&(e+="\n")}return e}toMarkdown(e){let t="";for(let n=0;n<this.inlines.length;n++){const r=this.inlines[n],i=this.inlines[n+1];t+=r.toMarkdown(e),i&&i.range.start.line>r.range.start.line&&(t+="\n")}return t}}class Iu{constructor(e,t){this.text=e,this.range=t}toString(){return this.text}toMarkdown(){return this.text}}function Su(e){return e.endsWith("\n")?"\n":"\n\n"}class Nu{constructor(e){this.indexManager=e.shared.workspace.IndexManager,this.commentProvider=e.documentation.CommentProvider}getDocumentation(e){const t=this.commentProvider.getComment(e);if(t&&function(e,t){const n=vu(t),r=au(e);if(0===r.length)return!1;const i=r[0],s=r[r.length-1],o=n.start,a=n.end;return Boolean(null==o?void 0:o.exec(i))&&Boolean(null==a?void 0:a.exec(s))}(t)){return ou(t).toMarkdown({renderLink:(t,n)=>this.documentationLinkRenderer(e,t,n),renderTag:t=>this.documentationTagRenderer(e,t)})}}documentationLinkRenderer(e,t,n){var r;const i=null!==(r=this.findNameInPrecomputedScopes(e,t))&&void 0!==r?r:this.findNameInGlobalScope(e,t);if(i&&i.nameSegment){const e=i.nameSegment.range.start.line+1,t=i.nameSegment.range.start.character+1;return`[${n}](${i.documentUri.with({fragment:`L${e},${t}`}).toString()})`}}documentationTagRenderer(e,t){}findNameInPrecomputedScopes(e,t){const n=Pe(e).precomputedScopes;if(!n)return;let r=e;do{const e=n.get(r).find((e=>e.name===t));if(e)return e;r=r.$container}while(r)}findNameInGlobalScope(e,t){return this.indexManager.allElements().find((e=>e.name===t))}}class Cu{constructor(e){this.grammarConfig=()=>e.parser.GrammarConfig}getComment(e){var t;return function(e){return"string"==typeof e.$comment}(e)?e.$comment:null===(t=x(e.$cstNode,this.grammarConfig().multilineCommentRules))||void 0===t?void 0:t.text}}var $u;n(62676);class wu{constructor(e){this.syncParser=e.parser.LangiumParser}parse(e){return Promise.resolve(this.syncParser.parse(e))}}class Lu{constructor(){this.previousTokenSource=new sl.Qi,this.writeQueue=[],this.readQueue=[],this.done=!0}write(e){this.cancelWrite();const t=new sl.Qi;return this.previousTokenSource=t,this.enqueue(this.writeQueue,e,t.token)}read(e){return this.enqueue(this.readQueue,e)}enqueue(e,t,n){const r=new dl,i={action:t,deferred:r,cancellationToken:null!=n?n:sl.XO.None};return e.push(i),this.performNextOperation(),r.promise}async performNextOperation(){if(!this.done)return;const e=[];if(this.writeQueue.length>0)e.push(this.writeQueue.shift());else{if(!(this.readQueue.length>0))return;e.push(...this.readQueue.splice(0,this.readQueue.length))}this.done=!1,await Promise.all(e.map((async({action:e,deferred:t,cancellationToken:n})=>{try{const r=await Promise.resolve().then((()=>e(n)));t.resolve(r)}catch(r){ll(r)?t.resolve(void 0):t.reject(r)}}))),this.done=!0,this.performNextOperation()}cancelWrite(){this.previousTokenSource.cancel()}}class Ou{constructor(e){this.grammarElementIdMap=new wl,this.tokenTypeIdMap=new wl,this.grammar=e.Grammar,this.lexer=e.parser.Lexer,this.linker=e.references.Linker}dehydrate(e){return{lexerErrors:e.lexerErrors.map((e=>Object.assign({},e))),parserErrors:e.parserErrors.map((e=>Object.assign({},e))),value:this.dehydrateAstNode(e.value,this.createDehyrationContext(e.value))}}createDehyrationContext(e){const t=new Map,n=new Map;for(const r of Ue(e))t.set(r,{});if(e.$cstNode)for(const r of T(e.$cstNode))n.set(r,{});return{astNodes:t,cstNodes:n}}dehydrateAstNode(e,t){const n=t.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,void 0!==e.$cstNode&&(n.$cstNode=this.dehydrateCstNode(e.$cstNode,t));for(const[s,o]of Object.entries(e))if(!s.startsWith("$"))if(Array.isArray(o)){const e=[];n[s]=e;for(const n of o)r(n)?e.push(this.dehydrateAstNode(n,t)):i(n)?e.push(this.dehydrateReference(n,t)):e.push(n)}else r(o)?n[s]=this.dehydrateAstNode(o,t):i(o)?n[s]=this.dehydrateReference(o,t):void 0!==o&&(n[s]=o);return n}dehydrateReference(e,t){const n={};return n.$refText=e.$refText,e.$refNode&&(n.$refNode=t.cstNodes.get(e.$refNode)),n}dehydrateCstNode(e,t){const n=t.cstNodes.get(e);return l(e)?n.fullText=e.fullText:n.grammarSource=this.getGrammarElementId(e.grammarSource),n.hidden=e.hidden,n.astNode=t.astNodes.get(e.astNode),a(e)?n.content=e.content.map((e=>this.dehydrateCstNode(e,t))):c(e)&&(n.tokenType=e.tokenType.name,n.offset=e.offset,n.length=e.length,n.startLine=e.range.start.line,n.startColumn=e.range.start.character,n.endLine=e.range.end.line,n.endColumn=e.range.end.character),n}hydrate(e){const t=e.value,n=this.createHydrationContext(t);return"$cstNode"in t&&this.hydrateCstNode(t.$cstNode,n),{lexerErrors:e.lexerErrors,parserErrors:e.parserErrors,value:this.hydrateAstNode(t,n)}}createHydrationContext(e){const t=new Map,n=new Map;for(const i of Ue(e))t.set(i,{});let r;if(e.$cstNode)for(const i of T(e.$cstNode)){let e;"fullText"in i?(e=new Mc(i.fullText),r=e):"content"in i?e=new _c:"tokenType"in i&&(e=this.hydrateCstLeafNode(i)),e&&(n.set(i,e),e.root=r)}return{astNodes:t,cstNodes:n}}hydrateAstNode(e,t){const n=t.astNodes.get(e);n.$type=e.$type,n.$containerIndex=e.$containerIndex,n.$containerProperty=e.$containerProperty,e.$cstNode&&(n.$cstNode=t.cstNodes.get(e.$cstNode));for(const[s,o]of Object.entries(e))if(!s.startsWith("$"))if(Array.isArray(o)){const e=[];n[s]=e;for(const a of o)r(a)?e.push(this.setParent(this.hydrateAstNode(a,t),n)):i(a)?e.push(this.hydrateReference(a,n,s,t)):e.push(a)}else r(o)?n[s]=this.setParent(this.hydrateAstNode(o,t),n):i(o)?n[s]=this.hydrateReference(o,n,s,t):void 0!==o&&(n[s]=o);return n}setParent(e,t){return e.$container=t,e}hydrateReference(e,t,n,r){return this.linker.buildReference(t,n,r.cstNodes.get(e.$refNode),e.$refText)}hydrateCstNode(e,t,n=0){const r=t.cstNodes.get(e);if("number"==typeof e.grammarSource&&(r.grammarSource=this.getGrammarElement(e.grammarSource)),r.astNode=t.astNodes.get(e.astNode),a(r))for(const i of e.content){const e=this.hydrateCstNode(i,t,n++);r.content.push(e)}return r}hydrateCstLeafNode(e){const t=this.getTokenType(e.tokenType),n=e.offset,r=e.length,i=e.startLine,s=e.startColumn,o=e.endLine,a=e.endColumn,c=e.hidden;return new bc(n,r,{start:{line:i,character:s},end:{line:o,character:a}},t,c)}getTokenType(e){return this.lexer.definition[e]}getGrammarElementId(e){return 0===this.grammarElementIdMap.size&&this.createGrammarElementIdMap(),this.grammarElementIdMap.get(e)}getGrammarElement(e){0===this.grammarElementIdMap.size&&this.createGrammarElementIdMap();const t=this.grammarElementIdMap.getKey(e);if(t)return t;throw new Error("Invalid grammar element id: "+e)}createGrammarElementIdMap(){let e=0;for(const n of Ue(this.grammar))t=n,Oe.isInstance(t,b)&&this.grammarElementIdMap.set(n,e++);var t}}function bu(e){return{documentation:{CommentProvider:e=>new Cu(e),DocumentationProvider:e=>new Nu(e)},parser:{AsyncParser:e=>new wu(e),GrammarConfig:e=>function(e){const t=[],n=e.Grammar;for(const i of n.rules)te(i)&&(r=i).hidden&&!vt(r).test(" ")&&st(vt(i))&&t.push(i.name);var r;return{multilineCommentRules:t,nameRegexp:k}}(e),LangiumParser:e=>tl(e),CompletionParser:e=>function(e){const t=e.Grammar,n=e.parser.Lexer,r=new Vc(e);return zc(t,r,n.definition),r.finalize(),r}(e),ValueConverter:()=>new rl,TokenBuilder:()=>new nl,Lexer:e=>new ru(e),ParserErrorMessageProvider:()=>new jc},workspace:{AstNodeLocator:()=>new Jl,AstNodeDescriptionProvider:e=>new ql(e),ReferenceDescriptionProvider:e=>new Ql(e)},references:{Linker:e=>new Sl(e),NameProvider:()=>new Nl,ScopeProvider:e=>new Ul(e),ScopeComputation:e=>new Ll(e),References:e=>new Cl(e)},serializer:{Hydrator:e=>new Ou(e),JsonSerializer:e=>new Gl(e)},validation:{DocumentValidator:e=>new zl(e),ValidationRegistry:e=>new Wl(e)},shared:()=>e.shared}}function _u(e){return{ServiceRegistry:()=>new Kl,workspace:{LangiumDocuments:e=>new Il(e),LangiumDocumentFactory:e=>new xl(e),DocumentBuilder:e=>new eu(e),IndexManager:e=>new tu(e),WorkspaceManager:e=>new nu(e),FileSystemProvider:t=>e.fileSystemProvider(t),WorkspaceLock:()=>new Lu,ConfigurationProvider:e=>new Zl(e)}}}function Pu(e,t,n,r,i,s,o,a,c){return Du([e,t,n,r,i,s,o,a,c].reduce(Gu,{}))}!function(e){e.merge=(e,t)=>Gu(Gu({},e),t)}($u||($u={}));const Mu=Symbol("isProxy");function Du(e,t){const n=new Proxy({},{deleteProperty:()=>!1,get:(r,i)=>Fu(r,i,e,t||n),getOwnPropertyDescriptor:(r,i)=>(Fu(r,i,e,t||n),Object.getOwnPropertyDescriptor(r,i)),has:(t,n)=>n in e,ownKeys:()=>[...Reflect.ownKeys(e),Mu]});return n[Mu]=!0,n}const Uu=Symbol();function Fu(e,t,n,r){if(t in e){if(e[t]instanceof Error)throw new Error("Construction failure. Please make sure that your dependencies are constructable.",{cause:e[t]});if(e[t]===Uu)throw new Error('Cycle detected. Please make "'+String(t)+'" lazy. See https://langium.org/docs/configuration-services/#resolving-cyclic-dependencies');return e[t]}if(t in n){const s=n[t];e[t]=Uu;try{e[t]="function"==typeof s?s(r):Du(s,r)}catch(i){throw e[t]=i instanceof Error?i:void 0,i}return e[t]}}function Gu(e,t){if(t)for(const[n,r]of Object.entries(t))if(void 0!==r){const t=e[n];e[n]=null!==t&&null!==r&&"object"==typeof t&&"object"==typeof r?Gu(t,r):r}return e}class Ku{readFile(){throw new Error("No file system is available.")}async readDirectory(){return[]}}const Bu={fileSystemProvider:()=>new Ku},ju={Grammar:()=>{},LanguageMetaData:()=>({caseInsensitive:!1,fileExtensions:[".langium"],languageId:"langium"})},Vu={AstReflection:()=>new Le};function Hu(e){var t;const n=function(){const e=Pu(_u(Bu),Vu),t=Pu(bu({shared:e}),ju);return e.ServiceRegistry.register(t),t}(),r=n.serializer.JsonSerializer.deserialize(e);return n.shared.workspace.LangiumDocumentFactory.fromModel(r,vl.parse(`memory://${null!==(t=r.name)&&void 0!==t?t:"grammar"}.langium`)),r}},72559:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(61882);const i=function(e,t,n){for(var i=-1,s=e.length;++i<s;){var o=e[i],a=t(o);if(null!=a&&(void 0===c?a==a&&!(0,r.A)(a):n(a,c)))var c=a,l=o}return l}},36224:(e,t,n)=>{n.d(t,{A:()=>r});const r=function(e,t){return e<t}},52568:(e,t,n)=>{n.d(t,{A:()=>s});var r=n(6240),i=n(38446);const s=function(e,t){var n=-1,s=(0,i.A)(e)?Array(e.length):[];return(0,r.A)(e,(function(e,r,i){s[++n]=t(e,r,i)})),s}},99354:(e,t,n)=>{n.d(t,{A:()=>u});var r=n(66318),i=n(52851),s=n(7819),o=n(25353),a=n(23149),c=n(30901);const l=function(e,t,n,r){if(!(0,a.A)(e))return e;for(var l=-1,u=(t=(0,s.A)(t,e)).length,d=u-1,h=e;null!=h&&++l<u;){var f=(0,c.A)(t[l]),p=n;if("__proto__"===f||"constructor"===f||"prototype"===f)return e;if(l!=d){var m=h[f];void 0===(p=r?r(m,f,h):void 0)&&(p=(0,a.A)(m)?m:(0,o.A)(t[l+1])?[]:{})}(0,i.A)(h,f,p),h=h[f]}return e};const u=function(e,t,n){for(var i=-1,o=t.length,a={};++i<o;){var c=t[i],u=(0,r.A)(e,c);n(u,c)&&l(a,(0,s.A)(c,e),u)}return a}},50053:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(68675);const i=function(e){return(0,r.A)(e,4)}},23068:(e,t,n)=>{n.d(t,{A:()=>l});var r=n(24326),i=n(66984),s=n(6832),o=n(55615),a=Object.prototype,c=a.hasOwnProperty;const l=(0,r.A)((function(e,t){e=Object(e);var n=-1,r=t.length,l=r>2?t[2]:void 0;for(l&&(0,s.A)(t[0],t[1],l)&&(r=1);++n<r;)for(var u=t[n],d=(0,o.A)(u),h=-1,f=d.length;++h<f;){var p=d[h],m=e[p];(void 0===m||(0,i.A)(m,a[p])&&!c.call(e,p))&&(e[p]=u[p])}return e}))},16145:(e,t,n)=>{n.d(t,{A:()=>u});var r=n(23958),i=n(38446),s=n(27422);const o=function(e){return function(t,n,o){var a=Object(t);if(!(0,i.A)(t)){var c=(0,r.A)(n,3);t=(0,s.A)(t),n=function(e){return c(a[e],e,a)}}var l=e(t,n,o);return l>-1?a[c?t[l]:l]:void 0}};var a=n(25707),c=n(18593),l=Math.max;const u=o((function(e,t,n){var i=null==e?0:e.length;if(!i)return-1;var s=null==n?0:(0,c.A)(n);return s<0&&(s=l(i+s,0)),(0,a.A)(e,(0,r.A)(t,3),s)}))},34098:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(13588);const i=function(e){return(null==e?0:e.length)?(0,r.A)(e,1):[]}},48585:(e,t,n)=>{n.d(t,{A:()=>o});var r=Object.prototype.hasOwnProperty;const i=function(e,t){return null!=e&&r.call(e,t)};var s=n(85054);const o=function(e,t){return null!=e&&(0,s.A)(e,t,i)}},9703:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(88496),i=n(92049),s=n(53098);const o=function(e){return"string"==typeof e||!(0,i.A)(e)&&(0,s.A)(e)&&"[object String]"==(0,r.A)(e)}},26666:(e,t,n)=>{n.d(t,{A:()=>r});const r=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},74722:(e,t,n)=>{n.d(t,{A:()=>a});var r=n(45572),i=n(23958),s=n(52568),o=n(92049);const a=function(e,t){return((0,o.A)(e)?r.A:s.A)(e,(0,i.A)(t,3))}},86452:(e,t,n)=>{n.d(t,{A:()=>o});var r=n(72559),i=n(36224),s=n(29008);const o=function(e){return e&&e.length?(0,r.A)(e,s.A,i.A):void 0}},74342:(e,t,n)=>{n.d(t,{A:()=>m});var r=/\s/;const i=function(e){for(var t=e.length;t--&&r.test(e.charAt(t)););return t};var s=/^\s+/;const o=function(e){return e?e.slice(0,i(e)+1).replace(s,""):e};var a=n(23149),c=n(61882),l=/^[-+]0x[0-9a-f]+$/i,u=/^0b[01]+$/i,d=/^0o[0-7]+$/i,h=parseInt;const f=function(e){if("number"==typeof e)return e;if((0,c.A)(e))return NaN;if((0,a.A)(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=(0,a.A)(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=o(e);var n=u.test(e);return n||d.test(e)?h(e.slice(2),n?2:8):l.test(e)?NaN:+e};var p=1/0;const m=function(e){return e?(e=f(e))===p||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},18593:(e,t,n)=>{n.d(t,{A:()=>i});var r=n(74342);const i=function(e){var t=(0,r.A)(e),n=t%1;return t==t?n?t-n:t:0}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/890.8531ec8c.js b/pr-preview/pr-976/assets/js/890.8531ec8c.js new file mode 100644 index 0000000000..42429f67c9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/890.8531ec8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[890],{10890:(s,c,e)=>{e.d(c,{createInfoServices:()=>t.v});var t=e(97021);e(19369)}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/89486910.2245dcd7.js b/pr-preview/pr-976/assets/js/89486910.2245dcd7.js new file mode 100644 index 0000000000..aee1d9efeb --- /dev/null +++ b/pr-preview/pr-976/assets/js/89486910.2245dcd7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7086],{41805:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/docs/components/overview.md","sourceDirName":"components","slug":"/components/overview","permalink":"/contrast/pr-preview/pr-976/next/components/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/components/overview.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/next/troubleshooting"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/next/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},l=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(71789).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},71789:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8965cb1f.7fa15643.js b/pr-preview/pr-976/assets/js/8965cb1f.7fa15643.js new file mode 100644 index 0000000000..03e16f71b8 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8965cb1f.7fa15643.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2731],{45337:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Network Encryption","slug":"/category/network-encryption","permalink":"/contrast/pr-preview/pr-976/0.5/category/network-encryption","sidebar":"docs","navigation":{"previous":{"title":"PKI","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki"},"next":{"title":"Sidecar","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/896da145.a1a53ce3.js b/pr-preview/pr-976/assets/js/896da145.a1a53ce3.js new file mode 100644 index 0000000000..ac243f9a7d --- /dev/null +++ b/pr-preview/pr-976/assets/js/896da145.a1a53ce3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1739],{67766:(e,t,n)=>{n.d(t,{A:()=>b});var r=n(96540),s=n(34164),o=n(85246),c=n(57880),i=n(25792);const l=["zero","one","two","few","many","other"];function a(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function j(e){let{href:t,children:n}=e;return(0,g.jsx)(c.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:r,children:[n," ",r]}),o&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function C(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(y,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,g.jsx)(b,{items:n.items,className:t})}function b(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(C,{item:e})},t)))})}},57204:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"examples/index","title":"Examples","description":"","source":"@site/versioned_docs/version-0.7/examples/index.md","sourceDirName":"examples","slug":"/examples/","permalink":"/contrast/pr-preview/pr-976/0.7/examples/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/examples/index.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.7/examples/emojivoto"}}');var s=n(74848),o=n(28453),c=n(67766);const i={},l="Examples",a={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n","\n",(0,s.jsx)(c.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(96540);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8998.5c85576b.js b/pr-preview/pr-976/assets/js/8998.5c85576b.js new file mode 100644 index 0000000000..9e5c11049e --- /dev/null +++ b/pr-preview/pr-976/assets/js/8998.5c85576b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8998],{68998:(e,r,t)=>{t.d(r,{diagram:()=>c});var a=t(29196),s=t(61021),n=t(45567),d=t(78731),o={parse:(0,n.K2)((async e=>{const r=await(0,d.qg)("info",e);n.Rm.debug(r)}),"parse")},i={version:a.r},c={parser:o,db:{getVersion:(0,n.K2)((()=>i.version),"getVersion")},renderer:{draw:(0,n.K2)(((e,r,t)=>{n.Rm.debug("rendering info diagram\n"+e);const a=(0,s.D)(r);(0,n.a$)(a,100,400,!0);a.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${t}`)}),"draw")}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/89a4f0ca.91bcaa30.js b/pr-preview/pr-976/assets/js/89a4f0ca.91bcaa30.js new file mode 100644 index 0000000000..606ced9eb9 --- /dev/null +++ b/pr-preview/pr-976/assets/js/89a4f0ca.91bcaa30.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4687],{78700:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/docs/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/next/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/basics/features.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/next/basics/security-benefits"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/next/getting-started/install"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8c9a8791.46416e05.js b/pr-preview/pr-976/assets/js/8c9a8791.46416e05.js new file mode 100644 index 0000000000..4ca97c4f73 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8c9a8791.46416e05.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5335],{20016:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-0.7/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/0.7/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/components/runtime.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.7/components/"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.7/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"<code>cloud-hypervisor</code> virtual machine manager (VMM)",id:"cloud-hypervisor-virtual-machine-manager-vmm",level:3},{value:"<code>Tardev snapshotter</code>",id:"tardev-snapshotter",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(85604).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"cloud-hypervisor-virtual-machine-manager-vmm",children:[(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," virtual machine manager (VMM)"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})})," to create a confidential virtual machine for every pod.\nThis requires the ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," binary to be installed on every node (responsibility of the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),")."]}),"\n",(0,i.jsx)(n.h3,{id:"tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"Tardev snapshotter"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses a special ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotter"]})," (",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})}),") to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},85604:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8dca39c2.b4b59560.js b/pr-preview/pr-976/assets/js/8dca39c2.b4b59560.js new file mode 100644 index 0000000000..1fbf1c9452 --- /dev/null +++ b/pr-preview/pr-976/assets/js/8dca39c2.b4b59560.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3116],{82489:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-0.5/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/basics/confidential-containers.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Contrast","permalink":"/contrast/pr-preview/pr-976/0.5/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo Preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable, core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe guest VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo Preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/8f09b871.5bb7d3d7.js b/pr-preview/pr-976/assets/js/8f09b871.5bb7d3d7.js new file mode 100644 index 0000000000..eafe24007a --- /dev/null +++ b/pr-preview/pr-976/assets/js/8f09b871.5bb7d3d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9686],{20088:e=>{e.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Components","slug":"/category/components","permalink":"/contrast/pr-preview/pr-976/0.5/category/components","sidebar":"docs","navigation":{"previous":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/"},"next":{"title":"Coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9040bbc8.06d43bf0.js b/pr-preview/pr-976/assets/js/9040bbc8.06d43bf0.js new file mode 100644 index 0000000000..2e5f760030 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9040bbc8.06d43bf0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2453],{98935:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-1.0/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/1.0/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/examples/emojivoto.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/1.0/deployment"}}');var i=n(74848),s=n(28453);const a={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Downloading the deployment",id:"downloading-the-deployment",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(82463).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"downloading-the-deployment",children:"Downloading the deployment"}),"\n",(0,i.jsx)(t.p,{children:"The emojivoto deployment files are part of Contrast release. You can download the\nlatest deployment by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/download/v1.0.0/emojivoto-demo.yml --create-dirs --output-dir deployment\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,i.jsxs)(t.p,{children:["Contrast depends on a ",(0,i.jsxs)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:["custom Kubernetes ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," (",(0,i.jsx)(t.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,i.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/runtime.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.0.0/coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp deployment/\n"})}),"\n",(0,i.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,i.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,i.jsx)(t.code,{children:"contrast-cc-<platform>-<runtime-hash>"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,i.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the reference values from the manifest to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313" -m manifest.json\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs\nto be communicated out of band to everyone wanting to verify the deployment, as the ",(0,i.jsx)(t.code,{children:"verify"})," command checks\nif the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {\n "SANs": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n "WorkloadSecretID": "web"\n },\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},82463:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/90af0d0d.00afd3dd.js b/pr-preview/pr-976/assets/js/90af0d0d.00afd3dd.js new file mode 100644 index 0000000000..cf315129f3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/90af0d0d.00afd3dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8921],{17170:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-0.6/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/0.6/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/components/runtime.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.6/components/"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.6/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"<code>cloud-hypervisor</code> virtual machine manager (VMM)",id:"cloud-hypervisor-virtual-machine-manager-vmm",level:3},{value:"<code>Tardev snapshotter</code>",id:"tardev-snapshotter",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(92791).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"cloud-hypervisor-virtual-machine-manager-vmm",children:[(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," virtual machine manager (VMM)"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})})," to create a confidential virtual machine for every pod.\nThis requires the ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," binary to be installed on every node (responsibility of the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),")."]}),"\n",(0,i.jsx)(n.h3,{id:"tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"Tardev snapshotter"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses a special ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotter"]})," (",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})}),") to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.6/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},92791:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9152dfbd.3bdd0a61.js b/pr-preview/pr-976/assets/js/9152dfbd.3bdd0a61.js new file mode 100644 index 0000000000..a42cd6471c --- /dev/null +++ b/pr-preview/pr-976/assets/js/9152dfbd.3bdd0a61.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8036],{5359:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"1.0","label":"1.0","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-1.0","isLast":false,"docsSidebars":{"docs":[{"type":"link","label":"What is Contrast?","href":"/contrast/pr-preview/pr-976/1.0/","docId":"intro","unlisted":false},{"type":"category","label":"Basics","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/1.0/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/1.0/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/1.0/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false}],"collapsible":true},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/1.0/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/1.0/deployment","docId":"deployment","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/contrast/pr-preview/pr-976/1.0/troubleshooting","docId":"troubleshooting","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Overview","href":"/contrast/pr-preview/pr-976/1.0/components/overview","docId":"components/overview","unlisted":false},{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/1.0/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/1.0/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/1.0/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/1.0/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Secrets & recovery","href":"/contrast/pr-preview/pr-976/1.0/architecture/secrets","docId":"architecture/secrets","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/1.0/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/1.0/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/1.0/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/1.0/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true}]},"docs":{"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"architecture/secrets":{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/overview":{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"troubleshooting":{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/921.5ff0c680.js b/pr-preview/pr-976/assets/js/921.5ff0c680.js new file mode 100644 index 0000000000..6ac12237c0 --- /dev/null +++ b/pr-preview/pr-976/assets/js/921.5ff0c680.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[921],{80921:(s,r,a)=>{a.d(r,{diagram:()=>c});var e=a(96790),t=(a(79972),a(79740),a(6396),a(5081),a(34483),a(52294),a(62392),a(86825),a(85039),a(45567)),c={parser:e._$,db:e.z2,renderer:e.Lh,styles:e.tM,init:(0,t.K2)((s=>{s.class||(s.class={}),s.class.arrowMarkerAbsolute=s.arrowMarkerAbsolute,e.z2.clear()}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/927cf76e.6f4c28bf.js b/pr-preview/pr-976/assets/js/927cf76e.6f4c28bf.js new file mode 100644 index 0000000000..0e01ee226f --- /dev/null +++ b/pr-preview/pr-976/assets/js/927cf76e.6f4c28bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1226],{9902:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","source":"@site/docs/architecture/observability.md","sourceDirName":"architecture","slug":"/architecture/observability","permalink":"/contrast/pr-preview/pr-976/next/architecture/observability","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/architecture/observability.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Security considerations","permalink":"/contrast/pr-preview/pr-976/next/architecture/security-considerations"},"next":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/next/features-limitations"}}');var s=r(74848),i=r(28453);const o={},c="Observability",a={},d=[{value:"Exposed metrics",id:"exposed-metrics",level:2},{value:"Service mesh metrics",id:"service-mesh-metrics",level:2}];function h(e){const t={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"observability",children:"Observability"})}),"\n",(0,s.jsxs)(t.p,{children:["The Contrast Coordinator can expose metrics in the\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/",children:"Prometheus"})," format. These can be monitored to quickly\nidentify problems in the gRPC layer or attestation errors. Prometheus metrics\nare numerical values associated with a name and additional key/values pairs,\ncalled labels."]}),"\n",(0,s.jsx)(t.h2,{id:"exposed-metrics",children:"Exposed metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The metrics can be accessed at the Coordinator pod at the port specified in the\n",(0,s.jsx)(t.code,{children:"CONTRAST_METRICS_PORT"})," environment variable under the ",(0,s.jsx)(t.code,{children:"/metrics"})," endpoint. By\ndefault, this environment variable isn't specified, hence no metrics will be\nexposed."]}),"\n",(0,s.jsxs)(t.p,{children:["The Coordinator exports gRPC metrics under the prefix ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_"}),".\nThese metrics are labeled with the gRPC service name and method name.\nMetrics of interest include ",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handled_total"}),", which counts\nthe number of requests by return code, and\n",(0,s.jsx)(t.code,{children:"contrast_grpc_server_handling_seconds_bucket"}),", which produces a histogram of",(0,s.jsx)(t.br,{}),"\n","request latency."]}),"\n",(0,s.jsxs)(t.p,{children:["The gRPC service ",(0,s.jsx)(t.code,{children:"userapi.UserAPI"})," records metrics for the methods\n",(0,s.jsx)(t.code,{children:"SetManifest"})," and ",(0,s.jsx)(t.code,{children:"GetManifest"}),", which get called when ",(0,s.jsx)(t.a,{href:"../deployment#set-the-manifest",children:"setting the\nmanifest"})," and ",(0,s.jsx)(t.a,{href:"../deployment#verify-the-coordinator",children:"verifying the\nCoordinator"})," respectively."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"meshapi.MeshAPI"})," service records metrics for the method ",(0,s.jsx)(t.code,{children:"NewMeshCert"}),", which\ngets called by the ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-initializer",children:"Initializer"})," when starting a\nnew workload. Attestation failures from workloads to the Coordinator can be\ntracked with the counter ",(0,s.jsx)(t.code,{children:"contrast_meshapi_attestation_failures_total"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The current manifest generation is exposed as a\n",(0,s.jsx)(t.a,{href:"https://prometheus.io/docs/concepts/metric_types/#gauge",children:"gauge"})," with the metric\nname ",(0,s.jsx)(t.code,{children:"contrast_coordinator_manifest_generation"}),". If no manifest is set at the\nCoordinator, this counter will be zero."]}),"\n",(0,s.jsx)(t.h2,{id:"service-mesh-metrics",children:"Service mesh metrics"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"Service Mesh"})," can be configured to expose\nmetrics via its ",(0,s.jsx)(t.a,{href:"https://www.envoyproxy.io/docs/envoy/latest/operations/admin",children:"Envoy admin\ninterface"}),". Be\naware that the admin interface can expose private information and allows\ndestructive operations to be performed. To enable the admin interface for the\nService Mesh, set the annotation\n",(0,s.jsx)(t.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," in the configuration\nof your workload. If this annotation is set, the admin interface will be started\non this port."]}),"\n",(0,s.jsxs)(t.p,{children:["To access the admin interface, the ingress settings of the Service Mesh have to\nbe configured to allow access to the specified port (see ",(0,s.jsx)(t.a,{href:"../components/service-mesh#configuring-the-proxy",children:"Configuring the\nProxy"}),"). All metrics will be\nexposed under the ",(0,s.jsx)(t.code,{children:"/stats"})," endpoint. Metrics in Prometheus format can be scraped\nfrom the ",(0,s.jsx)(t.code,{children:"/stats/prometheus"})," endpoint."]})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>c});var n=r(96540);const s={},i=n.createContext(s);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9368.5da20e84.js b/pr-preview/pr-976/assets/js/9368.5da20e84.js new file mode 100644 index 0000000000..8a297728cc --- /dev/null +++ b/pr-preview/pr-976/assets/js/9368.5da20e84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9368],{69368:(t,e,r)=>{r.d(e,{diagram:()=>W});var a=r(85039),i=r(45567),n=r(697),s=r(20007),o=r(62334);const c=[];for(let U=0;U<256;++U)c.push((U+256).toString(16).slice(1));function l(t,e=0){return c[t[e+0]]+c[t[e+1]]+c[t[e+2]]+c[t[e+3]]+"-"+c[t[e+4]]+c[t[e+5]]+"-"+c[t[e+6]]+c[t[e+7]]+"-"+c[t[e+8]]+c[t[e+9]]+"-"+c[t[e+10]]+c[t[e+11]]+c[t[e+12]]+c[t[e+13]]+c[t[e+14]]+c[t[e+15]]}const h=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;const d=function(t){return"string"==typeof t&&h.test(t)};const u=function(t){if(!d(t))throw TypeError("Invalid UUID");let e;const r=new Uint8Array(16);return r[0]=(e=parseInt(t.slice(0,8),16))>>>24,r[1]=e>>>16&255,r[2]=e>>>8&255,r[3]=255&e,r[4]=(e=parseInt(t.slice(9,13),16))>>>8,r[5]=255&e,r[6]=(e=parseInt(t.slice(14,18),16))>>>8,r[7]=255&e,r[8]=(e=parseInt(t.slice(19,23),16))>>>8,r[9]=255&e,r[10]=(e=parseInt(t.slice(24,36),16))/1099511627776&255,r[11]=e/4294967296&255,r[12]=e>>>24&255,r[13]=e>>>16&255,r[14]=e>>>8&255,r[15]=255&e,r};function y(t,e,r,a){switch(t){case 0:return e&r^~e&a;case 1:case 3:return e^r^a;case 2:return e&r^e&a^r&a}}function p(t,e){return t<<e|t>>>32-e}const _=function(t,e,r){function a(t,a,i,n){var s;if("string"==typeof t&&(t=function(t){t=unescape(encodeURIComponent(t));const e=[];for(let r=0;r<t.length;++r)e.push(t.charCodeAt(r));return e}(t)),"string"==typeof a&&(a=u(a)),16!==(null===(s=a)||void 0===s?void 0:s.length))throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let o=new Uint8Array(16+t.length);if(o.set(a),o.set(t,a.length),o=r(o),o[6]=15&o[6]|e,o[8]=63&o[8]|128,i){n=n||0;for(let t=0;t<16;++t)i[n+t]=o[t];return i}return l(o)}try{a.name=t}catch(i){}return a.DNS="6ba7b810-9dad-11d1-80b4-00c04fd430c8",a.URL="6ba7b811-9dad-11d1-80b4-00c04fd430c8",a}("v5",80,(function(t){const e=[1518500249,1859775393,2400959708,3395469782],r=[1732584193,4023233417,2562383102,271733878,3285377520];if("string"==typeof t){const e=unescape(encodeURIComponent(t));t=[];for(let r=0;r<e.length;++r)t.push(e.charCodeAt(r))}else Array.isArray(t)||(t=Array.prototype.slice.call(t));t.push(128);const a=t.length/4+2,i=Math.ceil(a/16),n=new Array(i);for(let s=0;s<i;++s){const e=new Uint32Array(16);for(let r=0;r<16;++r)e[r]=t[64*s+4*r]<<24|t[64*s+4*r+1]<<16|t[64*s+4*r+2]<<8|t[64*s+4*r+3];n[s]=e}n[i-1][14]=8*(t.length-1)/Math.pow(2,32),n[i-1][14]=Math.floor(n[i-1][14]),n[i-1][15]=8*(t.length-1)&4294967295;for(let s=0;s<i;++s){const t=new Uint32Array(80);for(let e=0;e<16;++e)t[e]=n[s][e];for(let e=16;e<80;++e)t[e]=p(t[e-3]^t[e-8]^t[e-14]^t[e-16],1);let a=r[0],i=r[1],o=r[2],c=r[3],l=r[4];for(let r=0;r<80;++r){const n=Math.floor(r/20),s=p(a,5)+y(n,i,o,c)+l+e[n]+t[r]>>>0;l=c,c=o,o=p(i,30)>>>0,i=a,a=s}r[0]=r[0]+a>>>0,r[1]=r[1]+i>>>0,r[2]=r[2]+o>>>0,r[3]=r[3]+c>>>0,r[4]=r[4]+l>>>0}return[r[0]>>24&255,r[0]>>16&255,r[0]>>8&255,255&r[0],r[1]>>24&255,r[1]>>16&255,r[1]>>8&255,255&r[1],r[2]>>24&255,r[2]>>16&255,r[2]>>8&255,255&r[2],r[3]>>24&255,r[3]>>16&255,r[3]>>8&255,255&r[3],r[4]>>24&255,r[4]>>16&255,r[4]>>8&255,255&r[4]]}));var f=function(){var t=(0,i.K2)((function(t,e,r,a){for(r=r||{},a=t.length;a--;r[t[a]]=e);return r}),"o"),e=[6,8,10,20,22,24,26,27,28],r=[1,10],a=[1,11],n=[1,12],s=[1,13],o=[1,14],c=[1,15],l=[1,21],h=[1,22],d=[1,23],u=[1,24],y=[1,25],p=[6,8,10,13,15,18,19,20,22,24,26,27,28,41,42,43,44,45],_=[1,34],f=[27,28,46,47],E=[41,42,43,44,45],g=[17,34],m=[1,54],O=[1,53],k=[17,34,36,38],b={trace:(0,i.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,":":13,role:14,BLOCK_START:15,attributes:16,BLOCK_STOP:17,SQS:18,SQE:19,title:20,title_value:21,acc_title:22,acc_title_value:23,acc_descr:24,acc_descr_value:25,acc_descr_multiline_value:26,ALPHANUM:27,ENTITY_NAME:28,attribute:29,attributeType:30,attributeName:31,attributeKeyTypeList:32,attributeComment:33,ATTRIBUTE_WORD:34,attributeKeyType:35,COMMA:36,ATTRIBUTE_KEY:37,COMMENT:38,cardinality:39,relType:40,ZERO_OR_ONE:41,ZERO_OR_MORE:42,ONE_OR_MORE:43,ONLY_ONE:44,MD_PARENT:45,NON_IDENTIFYING:46,IDENTIFYING:47,WORD:48,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:":",15:"BLOCK_START",17:"BLOCK_STOP",18:"SQS",19:"SQE",20:"title",21:"title_value",22:"acc_title",23:"acc_title_value",24:"acc_descr",25:"acc_descr_value",26:"acc_descr_multiline_value",27:"ALPHANUM",28:"ENTITY_NAME",34:"ATTRIBUTE_WORD",36:"COMMA",37:"ATTRIBUTE_KEY",38:"COMMENT",41:"ZERO_OR_ONE",42:"ZERO_OR_MORE",43:"ONE_OR_MORE",44:"ONLY_ONE",45:"MD_PARENT",46:"NON_IDENTIFYING",47:"IDENTIFYING",48:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,4],[9,3],[9,1],[9,7],[9,6],[9,4],[9,2],[9,2],[9,2],[9,1],[11,1],[11,1],[16,1],[16,2],[29,2],[29,3],[29,3],[29,4],[30,1],[31,1],[32,1],[32,3],[35,1],[33,1],[12,3],[39,1],[39,1],[39,1],[39,1],[39,1],[40,1],[40,1],[14,1],[14,1],[14,1]],performAction:(0,i.K2)((function(t,e,r,a,i,n,s){var o=n.length-1;switch(i){case 1:break;case 2:case 6:case 7:this.$=[];break;case 3:n[o-1].push(n[o]),this.$=n[o-1];break;case 4:case 5:case 19:case 43:case 27:case 28:case 31:this.$=n[o];break;case 8:a.addEntity(n[o-4]),a.addEntity(n[o-2]),a.addRelationship(n[o-4],n[o],n[o-2],n[o-3]);break;case 9:a.addEntity(n[o-3]),a.addAttributes(n[o-3],n[o-1]);break;case 10:a.addEntity(n[o-2]);break;case 11:a.addEntity(n[o]);break;case 12:a.addEntity(n[o-6],n[o-4]),a.addAttributes(n[o-6],n[o-1]);break;case 13:a.addEntity(n[o-5],n[o-3]);break;case 14:a.addEntity(n[o-3],n[o-1]);break;case 15:case 16:this.$=n[o].trim(),a.setAccTitle(this.$);break;case 17:case 18:this.$=n[o].trim(),a.setAccDescription(this.$);break;case 20:case 41:case 42:case 32:this.$=n[o].replace(/"/g,"");break;case 21:case 29:this.$=[n[o]];break;case 22:n[o].push(n[o-1]),this.$=n[o];break;case 23:this.$={attributeType:n[o-1],attributeName:n[o]};break;case 24:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeKeyTypeList:n[o]};break;case 25:this.$={attributeType:n[o-2],attributeName:n[o-1],attributeComment:n[o]};break;case 26:this.$={attributeType:n[o-3],attributeName:n[o-2],attributeKeyTypeList:n[o-1],attributeComment:n[o]};break;case 30:n[o-2].push(n[o]),this.$=n[o-2];break;case 33:this.$={cardA:n[o],relType:n[o-1],cardB:n[o-2]};break;case 34:this.$=a.Cardinality.ZERO_OR_ONE;break;case 35:this.$=a.Cardinality.ZERO_OR_MORE;break;case 36:this.$=a.Cardinality.ONE_OR_MORE;break;case 37:this.$=a.Cardinality.ONLY_ONE;break;case 38:this.$=a.Cardinality.MD_PARENT;break;case 39:this.$=a.Identification.NON_IDENTIFYING;break;case 40:this.$=a.Identification.IDENTIFYING}}),"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,20:r,22:a,24:n,26:s,27:o,28:c},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:16,11:9,20:r,22:a,24:n,26:s,27:o,28:c},t(e,[2,5]),t(e,[2,6]),t(e,[2,11],{12:17,39:20,15:[1,18],18:[1,19],41:l,42:h,43:d,44:u,45:y}),{21:[1,26]},{23:[1,27]},{25:[1,28]},t(e,[2,18]),t(p,[2,19]),t(p,[2,20]),t(e,[2,4]),{11:29,27:o,28:c},{16:30,17:[1,31],29:32,30:33,34:_},{11:35,27:o,28:c},{40:36,46:[1,37],47:[1,38]},t(f,[2,34]),t(f,[2,35]),t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),t(e,[2,15]),t(e,[2,16]),t(e,[2,17]),{13:[1,39]},{17:[1,40]},t(e,[2,10]),{16:41,17:[2,21],29:32,30:33,34:_},{31:42,34:[1,43]},{34:[2,27]},{19:[1,44]},{39:45,41:l,42:h,43:d,44:u,45:y},t(E,[2,39]),t(E,[2,40]),{14:46,27:[1,49],28:[1,48],48:[1,47]},t(e,[2,9]),{17:[2,22]},t(g,[2,23],{32:50,33:51,35:52,37:m,38:O}),t([17,34,37,38],[2,28]),t(e,[2,14],{15:[1,55]}),t([27,28],[2,33]),t(e,[2,8]),t(e,[2,41]),t(e,[2,42]),t(e,[2,43]),t(g,[2,24],{33:56,36:[1,57],38:O}),t(g,[2,25]),t(k,[2,29]),t(g,[2,32]),t(k,[2,31]),{16:58,17:[1,59],29:32,30:33,34:_},t(g,[2,26]),{35:60,37:m},{17:[1,61]},t(e,[2,13]),t(k,[2,30]),t(e,[2,12])],defaultActions:{34:[2,27],41:[2,22]},parseError:(0,i.K2)((function(t,e){if(!e.recoverable){var r=new Error(t);throw r.hash=e,r}this.trace(t)}),"parseError"),parse:(0,i.K2)((function(t){var e=this,r=[0],a=[],n=[null],s=[],o=this.table,c="",l=0,h=0,d=0,u=s.slice.call(arguments,1),y=Object.create(this.lexer),p={yy:{}};for(var _ in this.yy)Object.prototype.hasOwnProperty.call(this.yy,_)&&(p.yy[_]=this.yy[_]);y.setInput(t,p.yy),p.yy.lexer=y,p.yy.parser=this,void 0===y.yylloc&&(y.yylloc={});var f=y.yylloc;s.push(f);var E=y.options&&y.options.ranges;function g(){var t;return"number"!=typeof(t=a.pop()||y.lex()||1)&&(t instanceof Array&&(t=(a=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof p.yy.parseError?this.parseError=p.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,i.K2)((function(t){r.length=r.length-2*t,n.length=n.length-t,s.length=s.length-t}),"popStack"),(0,i.K2)(g,"lex");for(var m,O,k,b,R,N,x,T,A,M={};;){if(k=r[r.length-1],this.defaultActions[k]?b=this.defaultActions[k]:(null==m&&(m=g()),b=o[k]&&o[k][m]),void 0===b||!b.length||!b[0]){var w="";for(N in A=[],o[k])this.terminals_[N]&&N>2&&A.push("'"+this.terminals_[N]+"'");w=y.showPosition?"Parse error on line "+(l+1)+":\n"+y.showPosition()+"\nExpecting "+A.join(", ")+", got '"+(this.terminals_[m]||m)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==m?"end of input":"'"+(this.terminals_[m]||m)+"'"),this.parseError(w,{text:y.match,token:this.terminals_[m]||m,line:y.yylineno,loc:f,expected:A})}if(b[0]instanceof Array&&b.length>1)throw new Error("Parse Error: multiple actions possible at state: "+k+", token: "+m);switch(b[0]){case 1:r.push(m),n.push(y.yytext),s.push(y.yylloc),r.push(b[1]),m=null,O?(m=O,O=null):(h=y.yyleng,c=y.yytext,l=y.yylineno,f=y.yylloc,d>0&&d--);break;case 2:if(x=this.productions_[b[1]][1],M.$=n[n.length-x],M._$={first_line:s[s.length-(x||1)].first_line,last_line:s[s.length-1].last_line,first_column:s[s.length-(x||1)].first_column,last_column:s[s.length-1].last_column},E&&(M._$.range=[s[s.length-(x||1)].range[0],s[s.length-1].range[1]]),void 0!==(R=this.performAction.apply(M,[c,h,l,p.yy,b[1],n,s].concat(u))))return R;x&&(r=r.slice(0,-1*x*2),n=n.slice(0,-1*x),s=s.slice(0,-1*x)),r.push(this.productions_[b[1]][0]),n.push(M.$),s.push(M._$),T=o[r[r.length-2]][r[r.length-1]],r.push(T);break;case 3:return!0}}return!0}),"parse")},R=function(){return{EOF:1,parseError:(0,i.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,i.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,i.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,i.K2)((function(t){var e=t.length,r=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var i=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===a.length?this.yylloc.first_column:0)+a[a.length-r.length].length-r[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[i[0],i[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,i.K2)((function(){return this._more=!0,this}),"more"),reject:(0,i.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,i.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,i.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,i.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,i.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,i.K2)((function(t,e){var r,a,i;if(this.options.backtrack_lexer&&(i={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(i.yylloc.range=this.yylloc.range.slice(0))),(a=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=a.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:a?a[a.length-1].length-a[a.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],r=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),r)return r;if(this._backtrack){for(var n in i)this[n]=i[n];return!1}return!1}),"test_match"),next:(0,i.K2)((function(){if(this.done)return this.EOF;var t,e,r,a;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var i=this._currentRules(),n=0;n<i.length;n++)if((r=this._input.match(this.rules[i[n]]))&&(!e||r[0].length>e[0].length)){if(e=r,a=n,this.options.backtrack_lexer){if(!1!==(t=this.test_match(r,i[n])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,i[a]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,i.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,i.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,i.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,i.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,i.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,i.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,i.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,i.K2)((function(t,e,r,a){switch(r){case 0:return this.begin("acc_title"),22;case 1:return this.popState(),"acc_title_value";case 2:return this.begin("acc_descr"),24;case 3:return this.popState(),"acc_descr_value";case 4:this.begin("acc_descr_multiline");break;case 5:this.popState();break;case 6:return"acc_descr_multiline_value";case 7:return 10;case 8:case 15:case 20:break;case 9:return 8;case 10:return 28;case 11:return 48;case 12:return 4;case 13:return this.begin("block"),15;case 14:return 36;case 16:return 37;case 17:case 18:return 34;case 19:return 38;case 21:return this.popState(),17;case 22:case 54:return e.yytext[0];case 23:return 18;case 24:return 19;case 25:case 29:case 30:case 43:return 41;case 26:case 27:case 28:case 36:case 38:case 45:return 43;case 31:case 32:case 33:case 34:case 35:case 37:case 44:return 42;case 39:case 40:case 41:case 42:return 44;case 46:return 45;case 47:case 50:case 51:case 52:return 46;case 48:case 49:return 47;case 53:return 27;case 55:return 6}}),"anonymous"),rules:[/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:[\n]+)/i,/^(?:\s+)/i,/^(?:[\s]+)/i,/^(?:"[^"%\r\n\v\b\\]+")/i,/^(?:"[^"]*")/i,/^(?:erDiagram\b)/i,/^(?:\{)/i,/^(?:,)/i,/^(?:\s+)/i,/^(?:\b((?:PK)|(?:FK)|(?:UK))\b)/i,/^(?:(.*?)[~](.*?)*[~])/i,/^(?:[\*A-Za-z_][A-Za-z0-9\-_\[\]\(\)]*)/i,/^(?:"[^"]*")/i,/^(?:[\n]+)/i,/^(?:\})/i,/^(?:.)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:one or zero\b)/i,/^(?:one or more\b)/i,/^(?:one or many\b)/i,/^(?:1\+)/i,/^(?:\|o\b)/i,/^(?:zero or one\b)/i,/^(?:zero or more\b)/i,/^(?:zero or many\b)/i,/^(?:0\+)/i,/^(?:\}o\b)/i,/^(?:many\(0\))/i,/^(?:many\(1\))/i,/^(?:many\b)/i,/^(?:\}\|)/i,/^(?:one\b)/i,/^(?:only one\b)/i,/^(?:1\b)/i,/^(?:\|\|)/i,/^(?:o\|)/i,/^(?:o\{)/i,/^(?:\|\{)/i,/^(?:\s*u\b)/i,/^(?:\.\.)/i,/^(?:--)/i,/^(?:to\b)/i,/^(?:optionally to\b)/i,/^(?:\.-)/i,/^(?:-\.)/i,/^(?:[A-Za-z_][A-Za-z0-9\-_]*)/i,/^(?:.)/i,/^(?:$)/i],conditions:{acc_descr_multiline:{rules:[5,6],inclusive:!1},acc_descr:{rules:[3],inclusive:!1},acc_title:{rules:[1],inclusive:!1},block:{rules:[14,15,16,17,18,19,20,21,22],inclusive:!1},INITIAL:{rules:[0,2,4,7,8,9,10,11,12,13,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55],inclusive:!0}}}}();function N(){this.yy={}}return b.lexer=R,(0,i.K2)(N,"Parser"),N.prototype=b,b.Parser=N,new N}();f.parser=f;var E=f,g=new Map,m=[],O=(0,i.K2)((function(t,e=void 0){return g.has(t)?!g.get(t).alias&&e&&(g.get(t).alias=e,i.Rm.info(`Add alias '${e}' to entity '${t}'`)):(g.set(t,{attributes:[],alias:e}),i.Rm.info("Added new entity :",t)),g.get(t)}),"addEntity"),k=(0,i.K2)((()=>g),"getEntities"),b=(0,i.K2)((function(t,e){let r,a=O(t);for(r=e.length-1;r>=0;r--)a.attributes.push(e[r]),i.Rm.debug("Added attribute ",e[r].attributeName)}),"addAttributes"),R=(0,i.K2)((function(t,e,r,a){let n={entityA:t,roleA:e,entityB:r,relSpec:a};m.push(n),i.Rm.debug("Added new relationship :",n)}),"addRelationship"),N=(0,i.K2)((()=>m),"getRelationships"),x=(0,i.K2)((function(){g=new Map,m=[],(0,i.IU)()}),"clear"),T={Cardinality:{ZERO_OR_ONE:"ZERO_OR_ONE",ZERO_OR_MORE:"ZERO_OR_MORE",ONE_OR_MORE:"ONE_OR_MORE",ONLY_ONE:"ONLY_ONE",MD_PARENT:"MD_PARENT"},Identification:{NON_IDENTIFYING:"NON_IDENTIFYING",IDENTIFYING:"IDENTIFYING"},getConfig:(0,i.K2)((()=>(0,i.D7)().er),"getConfig"),addEntity:O,addAttributes:b,getEntities:k,addRelationship:R,getRelationships:N,clear:x,setAccTitle:i.SV,getAccTitle:i.iN,setAccDescription:i.EI,getAccDescription:i.m7,setDiagramTitle:i.ke,getDiagramTitle:i.ab},A={ONLY_ONE_START:"ONLY_ONE_START",ONLY_ONE_END:"ONLY_ONE_END",ZERO_OR_ONE_START:"ZERO_OR_ONE_START",ZERO_OR_ONE_END:"ZERO_OR_ONE_END",ONE_OR_MORE_START:"ONE_OR_MORE_START",ONE_OR_MORE_END:"ONE_OR_MORE_END",ZERO_OR_MORE_START:"ZERO_OR_MORE_START",ZERO_OR_MORE_END:"ZERO_OR_MORE_END",MD_PARENT_END:"MD_PARENT_END",MD_PARENT_START:"MD_PARENT_START"},M={ERMarkers:A,insertMarkers:(0,i.K2)((function(t,e){let r;t.append("defs").append("marker").attr("id",A.MD_PARENT_START).attr("refX",0).attr("refY",7).attr("markerWidth",190).attr("markerHeight",240).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",A.MD_PARENT_END).attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 18,7 L9,13 L1,7 L9,1 Z"),t.append("defs").append("marker").attr("id",A.ONLY_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18 M15,0 L15,18"),t.append("defs").append("marker").attr("id",A.ONLY_ONE_END).attr("refX",18).attr("refY",9).attr("markerWidth",18).attr("markerHeight",18).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,0 L3,18 M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",A.ZERO_OR_ONE_START).attr("refX",0).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",21).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M9,0 L9,18"),r=t.append("defs").append("marker").attr("id",A.ZERO_OR_ONE_END).attr("refX",30).attr("refY",9).attr("markerWidth",30).attr("markerHeight",18).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",9).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,0 L21,18"),t.append("defs").append("marker").attr("id",A.ONE_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q 18,0 36,18 Q 18,36 0,18 M42,9 L42,27"),t.append("defs").append("marker").attr("id",A.ONE_OR_MORE_END).attr("refX",27).attr("refY",18).attr("markerWidth",45).attr("markerHeight",36).attr("orient","auto").append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M3,9 L3,27 M9,18 Q27,0 45,18 Q27,36 9,18"),r=t.append("defs").append("marker").attr("id",A.ZERO_OR_MORE_START).attr("refX",18).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",48).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M0,18 Q18,0 36,18 Q18,36 0,18"),r=t.append("defs").append("marker").attr("id",A.ZERO_OR_MORE_END).attr("refX",39).attr("refY",18).attr("markerWidth",57).attr("markerHeight",36).attr("orient","auto"),r.append("circle").attr("stroke",e.stroke).attr("fill","white").attr("cx",9).attr("cy",18).attr("r",6),r.append("path").attr("stroke",e.stroke).attr("fill","none").attr("d","M21,18 Q39,0 57,18 Q39,36 21,18")}),"insertMarkers")},w=/[^\dA-Za-z](\W)*/g,I={},D=new Map,S=(0,i.K2)((function(t){const e=Object.keys(t);for(const r of e)I[r]=t[r]}),"setConf"),v=(0,i.K2)(((t,e,r)=>{const a=I.entityPadding/3,n=I.entityPadding/3,s=.85*I.fontSize,o=e.node().getBBox(),c=[];let l=!1,h=!1,d=0,u=0,y=0,p=0,_=o.height+2*a,f=1;r.forEach((t=>{void 0!==t.attributeKeyTypeList&&t.attributeKeyTypeList.length>0&&(l=!0),void 0!==t.attributeComment&&(h=!0)})),r.forEach((r=>{const n=`${e.node().id}-attr-${f}`;let o=0;const E=(0,i.QO)(r.attributeType),g=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-type`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.D7)().fontFamily).style("font-size",s+"px").text(E),m=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-name`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.D7)().fontFamily).style("font-size",s+"px").text(r.attributeName),O={};O.tn=g,O.nn=m;const k=g.node().getBBox(),b=m.node().getBBox();if(d=Math.max(d,k.width),u=Math.max(u,b.width),o=Math.max(k.height,b.height),l){const e=void 0!==r.attributeKeyTypeList?r.attributeKeyTypeList.join(","):"",a=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-key`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.D7)().fontFamily).style("font-size",s+"px").text(e);O.kn=a;const c=a.node().getBBox();y=Math.max(y,c.width),o=Math.max(o,c.height)}if(h){const e=t.append("text").classed("er entityLabel",!0).attr("id",`${n}-comment`).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","left").style("font-family",(0,i.D7)().fontFamily).style("font-size",s+"px").text(r.attributeComment||"");O.cn=e;const a=e.node().getBBox();p=Math.max(p,a.width),o=Math.max(o,a.height)}O.height=o,c.push(O),_+=o+2*a,f+=1}));let E=4;l&&(E+=2),h&&(E+=2);const g=d+u+y+p,m={width:Math.max(I.minEntityWidth,Math.max(o.width+2*I.entityPadding,g+n*E)),height:r.length>0?_:Math.max(I.minEntityHeight,o.height+2*I.entityPadding)};if(r.length>0){const r=Math.max(0,(m.width-g-n*E)/(E/2));e.attr("transform","translate("+m.width/2+","+(a+o.height/2)+")");let i=o.height+2*a,s="attributeBoxOdd";c.forEach((e=>{const o=i+a+e.height/2;e.tn.attr("transform","translate("+n+","+o+")");const c=t.insert("rect","#"+e.tn.node().id).classed(`er ${s}`,!0).attr("x",0).attr("y",i).attr("width",d+2*n+r).attr("height",e.height+2*a),_=parseFloat(c.attr("x"))+parseFloat(c.attr("width"));e.nn.attr("transform","translate("+(_+n)+","+o+")");const f=t.insert("rect","#"+e.nn.node().id).classed(`er ${s}`,!0).attr("x",_).attr("y",i).attr("width",u+2*n+r).attr("height",e.height+2*a);let E=parseFloat(f.attr("x"))+parseFloat(f.attr("width"));if(l){e.kn.attr("transform","translate("+(E+n)+","+o+")");const c=t.insert("rect","#"+e.kn.node().id).classed(`er ${s}`,!0).attr("x",E).attr("y",i).attr("width",y+2*n+r).attr("height",e.height+2*a);E=parseFloat(c.attr("x"))+parseFloat(c.attr("width"))}h&&(e.cn.attr("transform","translate("+(E+n)+","+o+")"),t.insert("rect","#"+e.cn.node().id).classed(`er ${s}`,"true").attr("x",E).attr("y",i).attr("width",p+2*n+r).attr("height",e.height+2*a)),i+=e.height+2*a,s="attributeBoxOdd"===s?"attributeBoxEven":"attributeBoxOdd"}))}else m.height=Math.max(I.minEntityHeight,_),e.attr("transform","translate("+m.width/2+","+m.height/2+")");return m}),"drawAttributes"),L=(0,i.K2)((function(t,e,r){let a;return[...e.keys()].forEach((function(n){const s=F(n,"entity");D.set(n,s);const o=t.append("g").attr("id",s);a=void 0===a?s:a;const c="text-"+s,l=o.append("text").classed("er entityLabel",!0).attr("id",c).attr("x",0).attr("y",0).style("dominant-baseline","middle").style("text-anchor","middle").style("font-family",(0,i.D7)().fontFamily).style("font-size",I.fontSize+"px").text(e.get(n).alias??n),{width:h,height:d}=v(o,l,e.get(n).attributes),u=o.insert("rect","#"+c).classed("er entityBox",!0).attr("x",0).attr("y",0).attr("width",h).attr("height",d).node().getBBox();r.setNode(s,{width:u.width,height:u.height,shape:"rect",id:s})})),a}),"drawEntities"),$=(0,i.K2)((function(t,e){e.nodes().forEach((function(r){void 0!==r&&void 0!==e.node(r)&&t.select("#"+r).attr("transform","translate("+(e.node(r).x-e.node(r).width/2)+","+(e.node(r).y-e.node(r).height/2)+" )")}))}),"adjustEntities"),K=(0,i.K2)((function(t){return(t.entityA+t.roleA+t.entityB).replace(/\s/g,"")}),"getEdgeName"),C=(0,i.K2)((function(t,e){return t.forEach((function(t){e.setEdge(D.get(t.entityA),D.get(t.entityB),{relationship:t},K(t))})),t}),"addRelationships"),B=0,P=(0,i.K2)((function(t,e,r,a,n){B++;const o=r.edge(D.get(e.entityA),D.get(e.entityB),K(e)),c=(0,s.n8j)().x((function(t){return t.x})).y((function(t){return t.y})).curve(s.qrM),l=t.insert("path","#"+a).classed("er relationshipLine",!0).attr("d",c(o.points)).style("stroke",I.stroke).style("fill","none");e.relSpec.relType===n.db.Identification.NON_IDENTIFYING&&l.attr("stroke-dasharray","8,8");let h="";switch(I.arrowMarkerAbsolute&&(h=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,h=h.replace(/\(/g,"\\("),h=h.replace(/\)/g,"\\)")),e.relSpec.cardA){case n.db.Cardinality.ZERO_OR_ONE:l.attr("marker-end","url("+h+"#"+M.ERMarkers.ZERO_OR_ONE_END+")");break;case n.db.Cardinality.ZERO_OR_MORE:l.attr("marker-end","url("+h+"#"+M.ERMarkers.ZERO_OR_MORE_END+")");break;case n.db.Cardinality.ONE_OR_MORE:l.attr("marker-end","url("+h+"#"+M.ERMarkers.ONE_OR_MORE_END+")");break;case n.db.Cardinality.ONLY_ONE:l.attr("marker-end","url("+h+"#"+M.ERMarkers.ONLY_ONE_END+")");break;case n.db.Cardinality.MD_PARENT:l.attr("marker-end","url("+h+"#"+M.ERMarkers.MD_PARENT_END+")")}switch(e.relSpec.cardB){case n.db.Cardinality.ZERO_OR_ONE:l.attr("marker-start","url("+h+"#"+M.ERMarkers.ZERO_OR_ONE_START+")");break;case n.db.Cardinality.ZERO_OR_MORE:l.attr("marker-start","url("+h+"#"+M.ERMarkers.ZERO_OR_MORE_START+")");break;case n.db.Cardinality.ONE_OR_MORE:l.attr("marker-start","url("+h+"#"+M.ERMarkers.ONE_OR_MORE_START+")");break;case n.db.Cardinality.ONLY_ONE:l.attr("marker-start","url("+h+"#"+M.ERMarkers.ONLY_ONE_START+")");break;case n.db.Cardinality.MD_PARENT:l.attr("marker-start","url("+h+"#"+M.ERMarkers.MD_PARENT_START+")")}const d=l.node().getTotalLength(),u=l.node().getPointAtLength(.5*d),y="rel"+B,p=e.roleA.split(/<br ?\/>/g),_=t.append("text").classed("er relationshipLabel",!0).attr("id",y).attr("x",u.x).attr("y",u.y).style("text-anchor","middle").style("dominant-baseline","middle").style("font-family",(0,i.D7)().fontFamily).style("font-size",I.fontSize+"px");if(1==p.length)_.text(e.roleA);else{const t=.5*-(p.length-1);p.forEach(((e,r)=>{_.append("tspan").attr("x",u.x).attr("dy",`${0===r?t:1}em`).text(e)}))}const f=_.node().getBBox();t.insert("rect","#"+y).classed("er relationshipLabelBox",!0).attr("x",u.x-f.width/2).attr("y",u.y-f.height/2).attr("width",f.width).attr("height",f.height)}),"drawRelationshipFromLayout"),Y=(0,i.K2)((function(t,e,r,c){I=(0,i.D7)().er,i.Rm.info("Drawing ER diagram");const l=(0,i.D7)().securityLevel;let h;"sandbox"===l&&(h=(0,s.Ltv)("#i"+e));const d=("sandbox"===l?(0,s.Ltv)(h.nodes()[0].contentDocument.body):(0,s.Ltv)("body")).select(`[id='${e}']`);let u;M.insertMarkers(d,I),u=new n.T({multigraph:!0,directed:!0,compound:!1}).setGraph({rankdir:I.layoutDirection,marginx:20,marginy:20,nodesep:100,edgesep:100,ranksep:100}).setDefaultEdgeLabel((function(){return{}}));const y=L(d,c.db.getEntities(),u),p=C(c.db.getRelationships(),u);(0,o.Zp)(u),$(d,u),p.forEach((function(t){P(d,t,u,y,c)}));const _=I.diagramPadding;a._K.insertTitle(d,"entityTitleText",I.titleTopMargin,c.db.getDiagramTitle());const f=d.node().getBBox(),E=f.width+2*_,g=f.height+2*_;(0,i.a$)(d,g,E,I.useMaxWidth),d.attr("viewBox",`${f.x-_} ${f.y-_} ${E} ${g}`)}),"draw"),Z="28e9f9db-3c8d-5aa5-9faf-44286ae5937c";function F(t="",e=""){const r=t.replace(w,"");return`${z(e)}${z(r)}${_(t,Z)}`}function z(t=""){return t.length>0?`${t}-`:""}(0,i.K2)(F,"generateId"),(0,i.K2)(z,"strWithHyphen");var W={parser:E,db:T,renderer:{setConf:S,draw:Y},styles:(0,i.K2)((t=>`\n .entityBox {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxOdd {\n fill: ${t.attributeBackgroundColorOdd};\n stroke: ${t.nodeBorder};\n }\n\n .attributeBoxEven {\n fill: ${t.attributeBackgroundColorEven};\n stroke: ${t.nodeBorder};\n }\n\n .relationshipLabelBox {\n fill: ${t.tertiaryColor};\n opacity: 0.7;\n background-color: ${t.tertiaryColor};\n rect {\n opacity: 0.5;\n }\n }\n\n .relationshipLine {\n stroke: ${t.lineColor};\n }\n\n .entityTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n } \n #MD_PARENT_START {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n #MD_PARENT_END {\n fill: #f5f5f5 !important;\n stroke: ${t.lineColor} !important;\n stroke-width: 1;\n }\n \n`),"getStyles")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9397123b.2f0b3891.js b/pr-preview/pr-976/assets/js/9397123b.2f0b3891.js new file mode 100644 index 0000000000..c88b5d3394 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9397123b.2f0b3891.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2941],{99845:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"architecture/attestation/manifest","title":"manifest","description":"","source":"@site/versioned_docs/version-0.5/architecture/attestation/manifest.md","sourceDirName":"architecture/attestation","slug":"/architecture/attestation/manifest","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/attestation/manifest.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime policies","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies"},"next":{"title":"Coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator"}}');var s=n(74848),o=n(28453);const i={},a=void 0,c={},u=[];function p(t){return(0,s.jsx)(s.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,o.R)(),...t.components};return e?(0,s.jsx)(e,{...t,children:(0,s.jsx)(p,{...t})}):p()}},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>a});var r=n(96540);const s={},o=r.createContext(s);function i(t){const e=r.useContext(o);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),r.createElement(o.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9620adf5.133d730b.js b/pr-preview/pr-976/assets/js/9620adf5.133d730b.js new file mode 100644 index 0000000000..bf314dd477 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9620adf5.133d730b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[912],{81469:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-1.0/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/1.0/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/basics/security-benefits.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/1.0/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(25217).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(74745).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},74745:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},25217:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9664.5583cedf.js b/pr-preview/pr-976/assets/js/9664.5583cedf.js new file mode 100644 index 0000000000..68ef08d232 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9664.5583cedf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9664],{79972:(t,e,s)=>{s.d(e,{A:()=>r,P:()=>o});var i=s(45567),n=s(20007),r=(0,i.K2)(((t,e)=>{let s;"sandbox"===e&&(s=(0,n.Ltv)("#i"+t));return("sandbox"===e?(0,n.Ltv)(s.nodes()[0].contentDocument.body):(0,n.Ltv)("body")).select(`[id="${t}"]`)}),"getDiagramElement"),o=(0,i.K2)(((t,e,s,n)=>{t.attr("class",s);const{width:r,height:o,x:l,y:h}=a(t,e);(0,i.a$)(t,o,r,n);const d=c(l,h,r,o,e);t.attr("viewBox",d),i.Rm.debug(`viewBox configured: ${d} with padding: ${e}`)}),"setupViewPortForSVG"),a=(0,i.K2)(((t,e)=>{const s=t.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:s.width+2*e,height:s.height+2*e,x:s.x,y:s.y}}),"calculateDimensionsWithPadding"),c=(0,i.K2)(((t,e,s,i,n)=>`${t-n} ${e-n} ${s} ${i}`),"createViewBox")},69664:(t,e,s)=>{s.d(e,{Zk:()=>c,iP:()=>Bt,q7:()=>w,tM:()=>Ft});var i=s(79972),n=s(79740),r=s(85039),o=s(45567),a=function(){var t=(0,o.K2)((function(t,e,s,i){for(s=s||{},i=t.length;i--;s[t[i]]=e);return s}),"o"),e=[1,2],s=[1,3],i=[1,4],n=[2,4],r=[1,9],a=[1,11],c=[1,16],l=[1,17],h=[1,18],d=[1,19],u=[1,32],p=[1,20],y=[1,21],g=[1,22],f=[1,23],m=[1,24],S=[1,26],_=[1,27],b=[1,28],T=[1,29],k=[1,30],E=[1,31],x=[1,34],D=[1,35],C=[1,36],$=[1,37],v=[1,33],L=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],I=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],A=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],K={trace:(0,o.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"--\x3e":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,classDef:38,CLASSDEF_ID:39,CLASSDEF_STYLEOPTS:40,DEFAULT:41,style:42,STYLE_IDS:43,STYLEDEF_STYLEOPTS:44,class:45,CLASSENTITY_IDS:46,STYLECLASS:47,direction_tb:48,direction_bt:49,direction_rl:50,direction_lr:51,eol:52,";":53,EDGE_STATE:54,STYLE_SEPARATOR:55,left_of:56,right_of:57,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"--\x3e",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"classDef",39:"CLASSDEF_ID",40:"CLASSDEF_STYLEOPTS",41:"DEFAULT",42:"style",43:"STYLE_IDS",44:"STYLEDEF_STYLEOPTS",45:"class",46:"CLASSENTITY_IDS",47:"STYLECLASS",48:"direction_tb",49:"direction_bt",50:"direction_rl",51:"direction_lr",53:";",54:"EDGE_STATE",55:"STYLE_SEPARATOR",56:"left_of",57:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[52,1],[52,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:(0,o.K2)((function(t,e,s,i,n,r,o){var a=r.length-1;switch(n){case 3:return i.setRootDoc(r[a]),r[a];case 4:this.$=[];break;case 5:"nl"!=r[a]&&(r[a-1].push(r[a]),this.$=r[a-1]);break;case 6:case 7:case 12:this.$=r[a];break;case 8:this.$="nl";break;case 13:const t=r[a-1];t.description=i.trimColon(r[a]),this.$=t;break;case 14:this.$={stmt:"relation",state1:r[a-2],state2:r[a]};break;case 15:const e=i.trimColon(r[a]);this.$={stmt:"relation",state1:r[a-3],state2:r[a-1],description:e};break;case 19:this.$={stmt:"state",id:r[a-3],type:"default",description:"",doc:r[a-1]};break;case 20:var c=r[a],l=r[a-2].trim();if(r[a].match(":")){var h=r[a].split(":");c=h[0],l=[l,h[1]]}this.$={stmt:"state",id:c,type:"default",description:l};break;case 21:this.$={stmt:"state",id:r[a-3],type:"default",description:r[a-5],doc:r[a-1]};break;case 22:this.$={stmt:"state",id:r[a],type:"fork"};break;case 23:this.$={stmt:"state",id:r[a],type:"join"};break;case 24:this.$={stmt:"state",id:r[a],type:"choice"};break;case 25:this.$={stmt:"state",id:i.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:r[a-1].trim(),note:{position:r[a-2].trim(),text:r[a].trim()}};break;case 29:this.$=r[a].trim(),i.setAccTitle(this.$);break;case 30:case 31:this.$=r[a].trim(),i.setAccDescription(this.$);break;case 32:case 33:this.$={stmt:"classDef",id:r[a-1].trim(),classes:r[a].trim()};break;case 34:this.$={stmt:"style",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 35:this.$={stmt:"applyClass",id:r[a-1].trim(),styleClass:r[a].trim()};break;case 36:i.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 37:i.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 38:i.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 39:i.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 42:case 43:this.$={stmt:"state",id:r[a].trim(),type:"default",description:""};break;case 44:case 45:this.$={stmt:"state",id:r[a-2].trim(),classes:[r[a].trim()],type:"default",description:""}}}),"anonymous"),table:[{3:1,4:e,5:s,6:i},{1:[3]},{3:5,4:e,5:s,6:i},{3:6,4:e,5:s,6:i},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,42,45,48,49,50,51,54],n,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:r,5:a,8:8,9:10,10:12,11:13,12:14,13:15,16:c,17:l,19:h,22:d,24:u,25:p,26:y,27:g,28:f,29:m,32:25,33:S,35:_,37:b,38:T,42:k,45:E,48:x,49:D,50:C,51:$,54:v},t(L,[2,5]),{9:38,10:12,11:13,12:14,13:15,16:c,17:l,19:h,22:d,24:u,25:p,26:y,27:g,28:f,29:m,32:25,33:S,35:_,37:b,38:T,42:k,45:E,48:x,49:D,50:C,51:$,54:v},t(L,[2,7]),t(L,[2,8]),t(L,[2,9]),t(L,[2,10]),t(L,[2,11]),t(L,[2,12],{14:[1,39],15:[1,40]}),t(L,[2,16]),{18:[1,41]},t(L,[2,18],{20:[1,42]}),{23:[1,43]},t(L,[2,22]),t(L,[2,23]),t(L,[2,24]),t(L,[2,25]),{30:44,31:[1,45],56:[1,46],57:[1,47]},t(L,[2,28]),{34:[1,48]},{36:[1,49]},t(L,[2,31]),{39:[1,50],41:[1,51]},{43:[1,52]},{46:[1,53]},t(I,[2,42],{55:[1,54]}),t(I,[2,43],{55:[1,55]}),t(L,[2,36]),t(L,[2,37]),t(L,[2,38]),t(L,[2,39]),t(L,[2,6]),t(L,[2,13]),{13:56,24:u,54:v},t(L,[2,17]),t(A,n,{7:57}),{24:[1,58]},{24:[1,59]},{23:[1,60]},{24:[2,46]},{24:[2,47]},t(L,[2,29]),t(L,[2,30]),{40:[1,61]},{40:[1,62]},{44:[1,63]},{47:[1,64]},{24:[1,65]},{24:[1,66]},t(L,[2,14],{14:[1,67]}),{4:r,5:a,8:8,9:10,10:12,11:13,12:14,13:15,16:c,17:l,19:h,21:[1,68],22:d,24:u,25:p,26:y,27:g,28:f,29:m,32:25,33:S,35:_,37:b,38:T,42:k,45:E,48:x,49:D,50:C,51:$,54:v},t(L,[2,20],{20:[1,69]}),{31:[1,70]},{24:[1,71]},t(L,[2,32]),t(L,[2,33]),t(L,[2,34]),t(L,[2,35]),t(I,[2,44]),t(I,[2,45]),t(L,[2,15]),t(L,[2,19]),t(A,n,{7:72}),t(L,[2,26]),t(L,[2,27]),{4:r,5:a,8:8,9:10,10:12,11:13,12:14,13:15,16:c,17:l,19:h,21:[1,73],22:d,24:u,25:p,26:y,27:g,28:f,29:m,32:25,33:S,35:_,37:b,38:T,42:k,45:E,48:x,49:D,50:C,51:$,54:v},t(L,[2,21])],defaultActions:{5:[2,1],6:[2,2],46:[2,46],47:[2,47]},parseError:(0,o.K2)((function(t,e){if(!e.recoverable){var s=new Error(t);throw s.hash=e,s}this.trace(t)}),"parseError"),parse:(0,o.K2)((function(t){var e=this,s=[0],i=[],n=[null],r=[],a=this.table,c="",l=0,h=0,d=0,u=r.slice.call(arguments,1),p=Object.create(this.lexer),y={yy:{}};for(var g in this.yy)Object.prototype.hasOwnProperty.call(this.yy,g)&&(y.yy[g]=this.yy[g]);p.setInput(t,y.yy),y.yy.lexer=p,y.yy.parser=this,void 0===p.yylloc&&(p.yylloc={});var f=p.yylloc;r.push(f);var m=p.options&&p.options.ranges;function S(){var t;return"number"!=typeof(t=i.pop()||p.lex()||1)&&(t instanceof Array&&(t=(i=t).pop()),t=e.symbols_[t]||t),t}"function"==typeof y.yy.parseError?this.parseError=y.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,o.K2)((function(t){s.length=s.length-2*t,n.length=n.length-t,r.length=r.length-t}),"popStack"),(0,o.K2)(S,"lex");for(var _,b,T,k,E,x,D,C,$,v={};;){if(T=s[s.length-1],this.defaultActions[T]?k=this.defaultActions[T]:(null==_&&(_=S()),k=a[T]&&a[T][_]),void 0===k||!k.length||!k[0]){var L="";for(x in $=[],a[T])this.terminals_[x]&&x>2&&$.push("'"+this.terminals_[x]+"'");L=p.showPosition?"Parse error on line "+(l+1)+":\n"+p.showPosition()+"\nExpecting "+$.join(", ")+", got '"+(this.terminals_[_]||_)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==_?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(L,{text:p.match,token:this.terminals_[_]||_,line:p.yylineno,loc:f,expected:$})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+T+", token: "+_);switch(k[0]){case 1:s.push(_),n.push(p.yytext),r.push(p.yylloc),s.push(k[1]),_=null,b?(_=b,b=null):(h=p.yyleng,c=p.yytext,l=p.yylineno,f=p.yylloc,d>0&&d--);break;case 2:if(D=this.productions_[k[1]][1],v.$=n[n.length-D],v._$={first_line:r[r.length-(D||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(D||1)].first_column,last_column:r[r.length-1].last_column},m&&(v._$.range=[r[r.length-(D||1)].range[0],r[r.length-1].range[1]]),void 0!==(E=this.performAction.apply(v,[c,h,l,y.yy,k[1],n,r].concat(u))))return E;D&&(s=s.slice(0,-1*D*2),n=n.slice(0,-1*D),r=r.slice(0,-1*D)),s.push(this.productions_[k[1]][0]),n.push(v.$),r.push(v._$),C=a[s[s.length-2]][s[s.length-1]],s.push(C);break;case 3:return!0}}return!0}),"parse")},R=function(){return{EOF:1,parseError:(0,o.K2)((function(t,e){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,e)}),"parseError"),setInput:(0,o.K2)((function(t,e){return this.yy=e||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,o.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,o.K2)((function(t){var e=t.length,s=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-e),this.offset-=e;var i=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),s.length-1&&(this.yylineno-=s.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:s?(s.length===i.length?this.yylloc.first_column:0)+i[i.length-s.length].length-s[0].length:this.yylloc.first_column-e},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-e]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,o.K2)((function(){return this._more=!0,this}),"more"),reject:(0,o.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,o.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,o.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,o.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,o.K2)((function(){var t=this.pastInput(),e=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+e+"^"}),"showPosition"),test_match:(0,o.K2)((function(t,e){var s,i,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(i=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=i.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:i?i[i.length-1].length-i[i.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],s=this.performAction.call(this,this.yy,this,e,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),s)return s;if(this._backtrack){for(var r in n)this[r]=n[r];return!1}return!1}),"test_match"),next:(0,o.K2)((function(){if(this.done)return this.EOF;var t,e,s,i;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),r=0;r<n.length;r++)if((s=this._input.match(this.rules[n[r]]))&&(!e||s[0].length>e[0].length)){if(e=s,i=r,this.options.backtrack_lexer){if(!1!==(t=this.test_match(s,n[r])))return t;if(this._backtrack){e=!1;continue}return!1}if(!this.options.flex)break}return e?!1!==(t=this.test_match(e,n[i]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,o.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,o.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,o.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,o.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,o.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,o.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,o.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,o.K2)((function(t,e,s,i){switch(s){case 0:return 41;case 1:case 42:return 48;case 2:case 43:return 49;case 3:case 44:return 50;case 4:case 45:return 51;case 5:case 6:case 8:case 9:case 10:case 11:case 54:case 56:case 62:break;case 7:case 77:return 5;case 12:case 32:return this.pushState("SCALE"),17;case 13:case 33:return 18;case 14:case 20:case 34:case 49:case 52:this.popState();break;case 15:return this.begin("acc_title"),33;case 16:return this.popState(),"acc_title_value";case 17:return this.begin("acc_descr"),35;case 18:return this.popState(),"acc_descr_value";case 19:this.begin("acc_descr_multiline");break;case 21:return"acc_descr_multiline_value";case 22:return this.pushState("CLASSDEF"),38;case 23:return this.popState(),this.pushState("CLASSDEFID"),"DEFAULT_CLASSDEF_ID";case 24:return this.popState(),this.pushState("CLASSDEFID"),39;case 25:return this.popState(),40;case 26:return this.pushState("CLASS"),45;case 27:return this.popState(),this.pushState("CLASS_STYLE"),46;case 28:return this.popState(),47;case 29:return this.pushState("STYLE"),42;case 30:return this.popState(),this.pushState("STYLEDEF_STYLES"),43;case 31:return this.popState(),44;case 35:this.pushState("STATE");break;case 36:case 39:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),25;case 37:case 40:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),26;case 38:case 41:return this.popState(),e.yytext=e.yytext.slice(0,-10).trim(),27;case 46:this.pushState("STATE_STRING");break;case 47:return this.pushState("STATE_ID"),"AS";case 48:case 64:return this.popState(),"ID";case 50:return"STATE_DESCR";case 51:return 19;case 53:return this.popState(),this.pushState("struct"),20;case 55:return this.popState(),21;case 57:return this.begin("NOTE"),29;case 58:return this.popState(),this.pushState("NOTE_ID"),56;case 59:return this.popState(),this.pushState("NOTE_ID"),57;case 60:this.popState(),this.pushState("FLOATING_NOTE");break;case 61:return this.popState(),this.pushState("FLOATING_NOTE_ID"),"AS";case 63:return"NOTE_TEXT";case 65:return this.popState(),this.pushState("NOTE_TEXT"),24;case 66:return this.popState(),e.yytext=e.yytext.substr(2).trim(),31;case 67:return this.popState(),e.yytext=e.yytext.slice(0,-8).trim(),31;case 68:case 69:return 6;case 70:return 16;case 71:return 54;case 72:return 24;case 73:return e.yytext=e.yytext.trim(),14;case 74:return 15;case 75:return 28;case 76:return 55;case 78:return"INVALID"}}),"anonymous"),rules:[/^(?:default\b)/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:[\n]+)/i,/^(?:[\s]+)/i,/^(?:((?!\n)\s)+)/i,/^(?:#[^\n]*)/i,/^(?:%[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:[\}])/i,/^(?:[^\}]*)/i,/^(?:classDef\s+)/i,/^(?:DEFAULT\s+)/i,/^(?:\w+\s+)/i,/^(?:[^\n]*)/i,/^(?:class\s+)/i,/^(?:(\w+)+((,\s*\w+)*))/i,/^(?:[^\n]*)/i,/^(?:style\s+)/i,/^(?:[\w,]+\s+)/i,/^(?:[^\n]*)/i,/^(?:scale\s+)/i,/^(?:\d+)/i,/^(?:\s+width\b)/i,/^(?:state\s+)/i,/^(?:.*<<fork>>)/i,/^(?:.*<<join>>)/i,/^(?:.*<<choice>>)/i,/^(?:.*\[\[fork\]\])/i,/^(?:.*\[\[join\]\])/i,/^(?:.*\[\[choice\]\])/i,/^(?:.*direction\s+TB[^\n]*)/i,/^(?:.*direction\s+BT[^\n]*)/i,/^(?:.*direction\s+RL[^\n]*)/i,/^(?:.*direction\s+LR[^\n]*)/i,/^(?:["])/i,/^(?:\s*as\s+)/i,/^(?:[^\n\{]*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n\s\{]+)/i,/^(?:\n)/i,/^(?:\{)/i,/^(?:%%(?!\{)[^\n]*)/i,/^(?:\})/i,/^(?:[\n])/i,/^(?:note\s+)/i,/^(?:left of\b)/i,/^(?:right of\b)/i,/^(?:")/i,/^(?:\s*as\s*)/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:[^\n]*)/i,/^(?:\s*[^:\n\s\-]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:[\s\S]*?end note\b)/i,/^(?:stateDiagram\s+)/i,/^(?:stateDiagram-v2\s+)/i,/^(?:hide empty description\b)/i,/^(?:\[\*\])/i,/^(?:[^:\n\s\-\{]+)/i,/^(?:\s*:[^:\n;]+)/i,/^(?:-->)/i,/^(?:--)/i,/^(?::::)/i,/^(?:$)/i,/^(?:.)/i],conditions:{LINE:{rules:[9,10],inclusive:!1},struct:{rules:[9,10,22,26,29,35,42,43,44,45,54,55,56,57,71,72,73,74,75],inclusive:!1},FLOATING_NOTE_ID:{rules:[64],inclusive:!1},FLOATING_NOTE:{rules:[61,62,63],inclusive:!1},NOTE_TEXT:{rules:[66,67],inclusive:!1},NOTE_ID:{rules:[65],inclusive:!1},NOTE:{rules:[58,59,60],inclusive:!1},STYLEDEF_STYLEOPTS:{rules:[],inclusive:!1},STYLEDEF_STYLES:{rules:[31],inclusive:!1},STYLE_IDS:{rules:[],inclusive:!1},STYLE:{rules:[30],inclusive:!1},CLASS_STYLE:{rules:[28],inclusive:!1},CLASS:{rules:[27],inclusive:!1},CLASSDEFID:{rules:[25],inclusive:!1},CLASSDEF:{rules:[23,24],inclusive:!1},acc_descr_multiline:{rules:[20,21],inclusive:!1},acc_descr:{rules:[18],inclusive:!1},acc_title:{rules:[16],inclusive:!1},SCALE:{rules:[13,14,33,34],inclusive:!1},ALIAS:{rules:[],inclusive:!1},STATE_ID:{rules:[48],inclusive:!1},STATE_STRING:{rules:[49,50],inclusive:!1},FORK_STATE:{rules:[],inclusive:!1},STATE:{rules:[9,10,36,37,38,39,40,41,46,47,51,52,53],inclusive:!1},ID:{rules:[9,10],inclusive:!1},INITIAL:{rules:[0,1,2,3,4,5,6,7,8,10,11,12,15,17,19,22,26,29,32,35,53,57,68,69,70,71,72,73,74,76,77,78],inclusive:!0}}}}();function w(){this.yy={}}return K.lexer=R,(0,o.K2)(w,"Parser"),w.prototype=K,K.Parser=w,new w}();a.parser=a;var c=a,l="state",h="relation",d="default",u="divider",p="fill:none",y="fill: #333",g="text",f="normal",m="rect",S="rectWithTitle",_="divider",b="roundedWithTitle",T="statediagram",k=`${T}-state`,E="transition",x=`${E} note-edge`,D=`${T}-note`,C=`${T}-cluster`,$=`${T}-cluster-alt`,v="parent",L="note",I="----",A=`${I}${L}`,K=`${I}${v}`,R=(0,o.K2)(((t,e="TB")=>{if(!t.doc)return e;let s=e;for(const i of t.doc)"dir"===i.stmt&&(s=i.value);return s}),"getDir"),w={getClasses:(0,o.K2)((function(t,e){return e.db.extract(e.db.getRootDocV2()),e.db.getClasses()}),"getClasses"),draw:(0,o.K2)((async function(t,e,s,a){o.Rm.info("REF0:"),o.Rm.info("Drawing state diagram (v2)",e);const{securityLevel:c,state:l,layout:h}=(0,o.D7)();a.db.extract(a.db.getRootDocV2());const d=a.db.getData(),u=(0,i.A)(e,c);d.type=a.type,d.layoutAlgorithm=h,d.nodeSpacing=l?.nodeSpacing||50,d.rankSpacing=l?.rankSpacing||50,d.markers=["barb"],d.diagramId=e,await(0,n.XX)(d,u);r._K.insertTitle(u,"statediagramTitleText",l?.titleTopMargin??25,a.db.getDiagramTitle()),(0,i.P)(u,8,T,l?.useMaxWidth??!0)}),"draw"),getDir:R},O=new Map,N=0;function B(t="",e=0,s="",i=I){return`state-${t}${null!==s&&s.length>0?`${i}${s}`:""}-${e}`}(0,o.K2)(B,"stateDomId");var F=(0,o.K2)(((t,e,s,i,n,r,a,c)=>{o.Rm.trace("items",e),e.forEach((e=>{switch(e.stmt){case l:case d:z(t,e,s,i,n,r,a,c);break;case h:{z(t,e.state1,s,i,n,r,a,c),z(t,e.state2,s,i,n,r,a,c);const l={id:"edge"+N,start:e.state1.id,end:e.state2.id,arrowhead:"normal",arrowTypeEnd:"arrow_barb",style:p,labelStyle:"",label:o.Y2.sanitizeText(e.description,(0,o.D7)()),arrowheadStyle:y,labelpos:"c",labelType:g,thickness:f,classes:E,look:a};n.push(l),N++}}}))}),"setupDoc"),P=(0,o.K2)(((t,e="TB")=>{let s=e;if(t.doc)for(const i of t.doc)"dir"===i.stmt&&(s=i.value);return s}),"getDir");function Y(t,e,s){if(!e.id||"</join></fork>"===e.id||"</choice>"===e.id)return;e.cssClasses&&(Array.isArray(e.cssCompiledStyles)||(e.cssCompiledStyles=[]),e.cssClasses.split(" ").forEach((t=>{if(s.get(t)){const i=s.get(t);e.cssCompiledStyles=[...e.cssCompiledStyles,...i.styles]}})));const i=t.find((t=>t.id===e.id));i?Object.assign(i,e):t.push(e)}function G(t){return t?.classes?.join(" ")??""}function j(t){return t?.styles??[]}(0,o.K2)(Y,"insertOrUpdateNode"),(0,o.K2)(G,"getClassesFromDbInfo"),(0,o.K2)(j,"getStylesFromDbInfo");var z=(0,o.K2)(((t,e,s,i,n,r,a,c)=>{const l=e.id,h=s.get(l),T=G(h),E=j(h);if(o.Rm.info("dataFetcher parsedItem",e,h,E),"root"!==l){let s=m;!0===e.start?s="stateStart":!1===e.start&&(s="stateEnd"),e.type!==d&&(s=e.type),O.get(l)||O.set(l,{id:l,shape:s,description:o.Y2.sanitizeText(l,(0,o.D7)()),cssClasses:`${T} ${k}`,cssStyles:E});const h=O.get(l);e.description&&(Array.isArray(h.description)?(h.shape=S,h.description.push(e.description)):h.description?.length>0?(h.shape=S,h.description===l?h.description=[e.description]:h.description=[h.description,e.description]):(h.shape=m,h.description=e.description),h.description=o.Y2.sanitizeTextOrArray(h.description,(0,o.D7)())),1===h.description?.length&&h.shape===S&&("group"===h.type?h.shape=b:h.shape=m),!h.type&&e.doc&&(o.Rm.info("Setting cluster for XCX",l,P(e)),h.type="group",h.isGroup=!0,h.dir=P(e),h.shape=e.type===u?_:b,h.cssClasses=`${h.cssClasses} ${C} ${r?$:""}`);const I={labelStyle:"",shape:h.shape,label:h.description,cssClasses:h.cssClasses,cssCompiledStyles:[],cssStyles:h.cssStyles,id:l,dir:h.dir,domId:B(l,N),type:h.type,isGroup:"group"===h.type,padding:8,rx:10,ry:10,look:a};if(I.shape===_&&(I.label=""),t&&"root"!==t.id&&(o.Rm.trace("Setting node ",l," to be child of its parent ",t.id),I.parentId=t.id),I.centerLabel=!0,e.note){const t={labelStyle:"",shape:"note",label:e.note.text,cssClasses:D,cssStyles:[],cssCompilesStyles:[],id:l+A+"-"+N,domId:B(l,N,L),type:h.type,isGroup:"group"===h.type,padding:(0,o.D7)().flowchart.padding,look:a,position:e.note.position},s=l+K,r={labelStyle:"",shape:"noteGroup",label:e.note.text,cssClasses:h.cssClasses,cssStyles:[],id:l+K,domId:B(l,N,v),type:"group",isGroup:!0,padding:16,look:a,position:e.note.position};N++,r.id=s,t.parentId=s,Y(i,r,c),Y(i,t,c),Y(i,I,c);let d=l,u=t.id;"left of"===e.note.position&&(d=t.id,u=l),n.push({id:d+"-"+u,start:d,end:u,arrowhead:"none",arrowTypeEnd:"",style:p,labelStyle:"",classes:x,arrowheadStyle:y,labelpos:"c",labelType:g,thickness:f,look:a})}else Y(i,I,c)}e.doc&&(o.Rm.trace("Adding nodes children "),F(e,e.doc,s,i,n,!r,a,c))}),"dataFetcher"),U=(0,o.K2)((()=>{O.clear(),N=0}),"reset"),M="[*]",X="start",V=M,W="color",H="fill";function J(){return new Map}(0,o.K2)(J,"newClassesList");var q=[],Z=[],Q="LR",tt=[],et=J(),st=(0,o.K2)((()=>({relations:[],states:new Map,documents:{}})),"newDoc"),it={root:st()},nt=it.root,rt=0,ot=0,at=(0,o.K2)((t=>JSON.parse(JSON.stringify(t))),"clone"),ct=(0,o.K2)((t=>{o.Rm.info("Setting root doc",t),tt=t}),"setRootDoc"),lt=(0,o.K2)((()=>tt),"getRootDoc"),ht=(0,o.K2)(((t,e,s)=>{if(e.stmt===h)ht(t,e.state1,!0),ht(t,e.state2,!1);else if(e.stmt===l&&("[*]"===e.id?(e.id=s?t.id+"_start":t.id+"_end",e.start=s):e.id=e.id.trim()),e.doc){const t=[];let s,i=[];for(s=0;s<e.doc.length;s++)if(e.doc[s].type===u){const n=at(e.doc[s]);n.doc=at(i),t.push(n),i=[]}else i.push(e.doc[s]);if(t.length>0&&i.length>0){const s={stmt:l,id:(0,r.$C)(),type:"divider",doc:at(i)};t.push(at(s)),e.doc=t}e.doc.forEach((t=>ht(e,t,!0)))}}),"docTranslator"),dt=(0,o.K2)((()=>(ht({id:"root"},{id:"root",doc:tt},!0),{id:"root",doc:tt})),"getRootDocV2"),ut=(0,o.K2)((t=>{let e;e=t.doc?t.doc:t,o.Rm.info(e),yt(!0),o.Rm.info("Extract initial document:",e),e.forEach((t=>{switch(o.Rm.warn("Statement",t.stmt),t.stmt){case l:pt(t.id.trim(),t.type,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles);break;case h:xt(t.state1,t.state2,t.description);break;case"classDef":vt(t.id.trim(),t.classes);break;case"style":{const e=t.id.trim().split(","),s=t.styleClass.split(",");e.forEach((t=>{let e=gt(t);if(void 0===e){const s=t.trim();pt(s),e=gt(s)}e.styles=s.map((t=>t.replace(/;/g,"")?.trim()))}))}break;case"applyClass":It(t.id.trim(),t.styleClass)}}));const s=ft(),i=(0,o.D7)().look;U(),z(void 0,dt(),s,q,Z,!0,i,et),q.forEach((t=>{if(Array.isArray(t.label)){if(t.description=t.label.slice(1),t.isGroup&&t.description.length>0)throw new Error("Group nodes can only have label. Remove the additional description for node ["+t.id+"]");t.label=t.label[0]}}))}),"extract"),pt=(0,o.K2)((function(t,e=d,s=null,i=null,n=null,r=null,a=null,c=null){const l=t?.trim();if(nt.states.has(l)?(nt.states.get(l).doc||(nt.states.get(l).doc=s),nt.states.get(l).type||(nt.states.get(l).type=e)):(o.Rm.info("Adding state ",l,i),nt.states.set(l,{id:l,descriptions:[],type:e,doc:s,note:n,classes:[],styles:[],textStyles:[]})),i&&(o.Rm.info("Setting state description",l,i),"string"==typeof i&&Dt(l,i.trim()),"object"==typeof i&&i.forEach((t=>Dt(l,t.trim())))),n){const t=nt.states.get(l);t.note=n,t.note.text=o.Y2.sanitizeText(t.note.text,(0,o.D7)())}if(r){o.Rm.info("Setting state classes",l,r);("string"==typeof r?[r]:r).forEach((t=>It(l,t.trim())))}if(a){o.Rm.info("Setting state styles",l,a);("string"==typeof a?[a]:a).forEach((t=>At(l,t.trim())))}if(c){o.Rm.info("Setting state styles",l,a);("string"==typeof c?[c]:c).forEach((t=>Kt(l,t.trim())))}}),"addState"),yt=(0,o.K2)((function(t){q=[],Z=[],it={root:st()},nt=it.root,rt=0,et=J(),t||(0,o.IU)()}),"clear"),gt=(0,o.K2)((function(t){return nt.states.get(t)}),"getState"),ft=(0,o.K2)((function(){return nt.states}),"getStates"),mt=(0,o.K2)((function(){o.Rm.info("Documents = ",it)}),"logDocuments"),St=(0,o.K2)((function(){return nt.relations}),"getRelations");function _t(t=""){let e=t;return t===M&&(rt++,e=`${X}${rt}`),e}function bt(t="",e=d){return t===M?X:e}function Tt(t=""){let e=t;return t===V&&(e=`end${++rt}`),e}function kt(t="",e=d){return t===V?"end":e}function Et(t,e,s){let i=_t(t.id.trim()),n=bt(t.id.trim(),t.type),r=_t(e.id.trim()),a=bt(e.id.trim(),e.type);pt(i,n,t.doc,t.description,t.note,t.classes,t.styles,t.textStyles),pt(r,a,e.doc,e.description,e.note,e.classes,e.styles,e.textStyles),nt.relations.push({id1:i,id2:r,relationTitle:o.Y2.sanitizeText(s,(0,o.D7)())})}(0,o.K2)(_t,"startIdIfNeeded"),(0,o.K2)(bt,"startTypeIfNeeded"),(0,o.K2)(Tt,"endIdIfNeeded"),(0,o.K2)(kt,"endTypeIfNeeded"),(0,o.K2)(Et,"addRelationObjs");var xt=(0,o.K2)((function(t,e,s){if("object"==typeof t)Et(t,e,s);else{const i=_t(t.trim()),n=bt(t),r=Tt(e.trim()),a=kt(e);pt(i,n),pt(r,a),nt.relations.push({id1:i,id2:r,title:o.Y2.sanitizeText(s,(0,o.D7)())})}}),"addRelation"),Dt=(0,o.K2)((function(t,e){const s=nt.states.get(t),i=e.startsWith(":")?e.replace(":","").trim():e;s.descriptions.push(o.Y2.sanitizeText(i,(0,o.D7)()))}),"addDescription"),Ct=(0,o.K2)((function(t){return":"===t.substring(0,1)?t.substr(2).trim():t.trim()}),"cleanupLabel"),$t=(0,o.K2)((()=>"divider-id-"+ ++ot),"getDividerId"),vt=(0,o.K2)((function(t,e=""){et.has(t)||et.set(t,{id:t,styles:[],textStyles:[]});const s=et.get(t);null!=e&&e.split(",").forEach((t=>{const e=t.replace(/([^;]*);/,"$1").trim();if(RegExp(W).exec(t)){const t=e.replace(H,"bgFill").replace(W,H);s.textStyles.push(t)}s.styles.push(e)}))}),"addStyleClass"),Lt=(0,o.K2)((function(){return et}),"getClasses"),It=(0,o.K2)((function(t,e){t.split(",").forEach((function(t){let s=gt(t);if(void 0===s){const e=t.trim();pt(e),s=gt(e)}s.classes.push(e)}))}),"setCssClass"),At=(0,o.K2)((function(t,e){const s=gt(t);void 0!==s&&s.styles.push(e)}),"setStyle"),Kt=(0,o.K2)((function(t,e){const s=gt(t);void 0!==s&&s.textStyles.push(e)}),"setTextStyle"),Rt=(0,o.K2)((()=>Q),"getDirection"),wt=(0,o.K2)((t=>{Q=t}),"setDirection"),Ot=(0,o.K2)((t=>t&&":"===t[0]?t.substr(1).trim():t.trim()),"trimColon"),Nt=(0,o.K2)((()=>{const t=(0,o.D7)();return{nodes:q,edges:Z,other:{},config:t,direction:R(dt())}}),"getData"),Bt={getConfig:(0,o.K2)((()=>(0,o.D7)().state),"getConfig"),getData:Nt,addState:pt,clear:yt,getState:gt,getStates:ft,getRelations:St,getClasses:Lt,getDirection:Rt,addRelation:xt,getDividerId:$t,setDirection:wt,cleanupLabel:Ct,lineType:{LINE:0,DOTTED_LINE:1},relationType:{AGGREGATION:0,EXTENSION:1,COMPOSITION:2,DEPENDENCY:3},logDocuments:mt,getRootDoc:lt,setRootDoc:ct,getRootDocV2:dt,extract:ut,trimColon:Ot,getAccTitle:o.iN,setAccTitle:o.SV,getAccDescription:o.m7,setAccDescription:o.EI,addStyleClass:vt,setCssClass:It,addDescription:Dt,setDiagramTitle:o.ke,getDiagramTitle:o.ab},Ft=(0,o.K2)((t=>`\ndefs #statediagram-barbEnd {\n fill: ${t.transitionColor};\n stroke: ${t.transitionColor};\n }\ng.stateGroup text {\n fill: ${t.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${t.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${t.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${t.mainBkg};\n stroke: ${t.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${t.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${t.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${t.noteBorderColor};\n fill: ${t.noteBkgColor};\n\n text {\n fill: ${t.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${t.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${t.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel {\n background-color: ${t.edgeLabelBackground};\n p {\n background-color: ${t.edgeLabelBackground};\n }\n rect {\n opacity: 0.5;\n background-color: ${t.edgeLabelBackground};\n fill: ${t.edgeLabelBackground};\n }\n text-align: center;\n}\n.edgeLabel .label text {\n fill: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${t.transitionLabelColor||t.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${t.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${t.specialStateColor};\n stroke: ${t.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${t.innerEndBackground};\n stroke: ${t.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${t.compositeBackground||t.background};\n // stroke: ${t.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${t.stateBkg||t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${t.mainBkg};\n stroke: ${t.stateBorder||t.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${t.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${t.compositeTitleBackground};\n stroke: ${t.stateBorder||t.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${t.stateLabelColor};\n // line-height: 1;\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${t.stateBorder||t.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${t.compositeBackground||t.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${t.altBackground?t.altBackground:"#efefef"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${t.noteBkgColor};\n stroke: ${t.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${t.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${t.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${t.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${t.lineColor};\n stroke: ${t.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${t.textColor};\n}\n`),"getStyles")}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/966b9f47.b375a919.js b/pr-preview/pr-976/assets/js/966b9f47.b375a919.js new file mode 100644 index 0000000000..4be9743104 --- /dev/null +++ b/pr-preview/pr-976/assets/js/966b9f47.b375a919.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1112],{98525:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>r,toc:()=>p});const r=JSON.parse('{"id":"architecture/components/cli","title":"cli","description":"","source":"@site/versioned_docs/version-0.5/architecture/components/cli.md","sourceDirName":"architecture/components","slug":"/architecture/components/cli","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/components/cli.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Init container","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container"},"next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers"}}');var o=n(74848),c=n(28453);const s={},i=void 0,a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function l(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},28453:(t,e,n)=>{n.d(e,{R:()=>s,x:()=>i});var r=n(96540);const o={},c=r.createContext(o);function s(t){const e=r.useContext(c);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:s(t.components),r.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/969019ea.32517b56.js b/pr-preview/pr-976/assets/js/969019ea.32517b56.js new file mode 100644 index 0000000000..1960be33b2 --- /dev/null +++ b/pr-preview/pr-976/assets/js/969019ea.32517b56.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[485],{31424:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-1.1/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/components/service-mesh.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/components/policies"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/architecture/attestation"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"CONTRAST_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"CONTRAST_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"<name>#<port>#false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:"<name>"})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"<name>#<port>#true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: CONTRAST_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v1.1.0@sha256:603ef5f817894b0a1406dda625eccd106bec61996a00aa13507b8058a5f76c5c"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-secrets\n mountPath: /contrast\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"<name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port>"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:"<name>"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9720.8e4604d2.js b/pr-preview/pr-976/assets/js/9720.8e4604d2.js new file mode 100644 index 0000000000..605afb06e2 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9720.8e4604d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9720],{39720:(c,e,s)=>{s.d(e,{createArchitectureServices:()=>t.S});var t=s(49936);s(19369)}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9802.bb09c288.js b/pr-preview/pr-976/assets/js/9802.bb09c288.js new file mode 100644 index 0000000000..faad9baa07 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9802.bb09c288.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9802],{89802:(t,i,e)=>{e.d(i,{diagram:()=>J});var s=e(86825),n=e(85039),a=e(61021),h=e(45567),o=e(20007),r=function(){var t=(0,h.K2)((function(t,i,e,s){for(e=e||{},s=t.length;s--;e[t[s]]=i);return e}),"o"),i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],n=[1,5],a=[1,6],o=[1,7],r=[1,5,10,12,14,16,18,19,21,23,34,35,36],l=[1,25],c=[1,26],g=[1,28],u=[1,29],x=[1,30],d=[1,31],p=[1,32],f=[1,33],y=[1,34],m=[1,35],b=[1,36],A=[1,37],S=[1,43],C=[1,42],w=[1,47],k=[1,50],_=[1,10,12,14,16,18,19,21,23,34,35,36],T=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36],R=[1,10,12,14,16,18,19,21,23,24,26,27,28,34,35,36,41,42,43,44,45,46,47,48,49,50],D=[1,64],L={trace:(0,h.K2)((function(){}),"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,commaSeparatedNumbers:25,SQUARE_BRACES_END:26,NUMBER_WITH_DECIMAL:27,COMMA:28,xAxisData:29,bandData:30,ARROW_DELIMITER:31,commaSeparatedTexts:32,yAxisData:33,NEWLINE:34,SEMI:35,EOF:36,alphaNum:37,STR:38,MD_STR:39,alphaNumToken:40,AMP:41,NUM:42,ALPHA:43,PLUS:44,EQUALS:45,MULT:46,DOT:47,BRKT:48,MINUS:49,UNDERSCORE:50,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",27:"NUMBER_WITH_DECIMAL",28:"COMMA",31:"ARROW_DELIMITER",34:"NEWLINE",35:"SEMI",36:"EOF",38:"STR",39:"MD_STR",41:"AMP",42:"NUM",43:"ALPHA",44:"PLUS",45:"EQUALS",46:"MULT",47:"DOT",48:"BRKT",49:"MINUS",50:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[13,1],[13,2],[13,1],[29,1],[29,3],[30,3],[32,3],[32,1],[15,1],[15,2],[15,1],[33,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[37,1],[37,2],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1],[40,1]],performAction:(0,h.K2)((function(t,i,e,s,n,a,h){var o=a.length-1;switch(n){case 5:s.setOrientation(a[o]);break;case 9:s.setDiagramTitle(a[o].text.trim());break;case 12:s.setLineData({text:"",type:"text"},a[o]);break;case 13:s.setLineData(a[o-1],a[o]);break;case 14:s.setBarData({text:"",type:"text"},a[o]);break;case 15:s.setBarData(a[o-1],a[o]);break;case 16:this.$=a[o].trim(),s.setAccTitle(this.$);break;case 17:case 18:this.$=a[o].trim(),s.setAccDescription(this.$);break;case 19:case 27:this.$=a[o-1];break;case 20:this.$=[Number(a[o-2]),...a[o]];break;case 21:this.$=[Number(a[o])];break;case 22:s.setXAxisTitle(a[o]);break;case 23:s.setXAxisTitle(a[o-1]);break;case 24:s.setXAxisTitle({type:"text",text:""});break;case 25:s.setXAxisBand(a[o]);break;case 26:s.setXAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 28:this.$=[a[o-2],...a[o]];break;case 29:this.$=[a[o]];break;case 30:s.setYAxisTitle(a[o]);break;case 31:s.setYAxisTitle(a[o-1]);break;case 32:s.setYAxisTitle({type:"text",text:""});break;case 33:s.setYAxisRangeData(Number(a[o-2]),Number(a[o]));break;case 37:case 38:this.$={text:a[o],type:"text"};break;case 39:this.$={text:a[o],type:"markdown"};break;case 40:this.$=a[o];break;case 41:this.$=a[o-1]+""+a[o]}}),"anonymous"),table:[t(i,e,{3:1,4:2,7:4,5:s,34:n,35:a,36:o}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,34:n,35:a,36:o}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],34:n,35:a,36:o}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(r,[2,34]),t(r,[2,35]),t(r,[2,36]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,34:n,35:a,36:o}),{1:[2,3]},t(r,[2,5]),t(i,[2,7],{4:22,34:n,35:a,36:o}),{11:23,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:39,13:38,24:S,27:C,29:40,30:41,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:45,15:44,27:w,33:46,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:49,17:48,24:k,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{11:52,17:51,24:k,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},{20:[1,53]},{22:[1,54]},t(_,[2,18]),{1:[2,2]},t(_,[2,8]),t(_,[2,9]),t(T,[2,37],{40:55,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A}),t(T,[2,38]),t(T,[2,39]),t(R,[2,40]),t(R,[2,42]),t(R,[2,43]),t(R,[2,44]),t(R,[2,45]),t(R,[2,46]),t(R,[2,47]),t(R,[2,48]),t(R,[2,49]),t(R,[2,50]),t(R,[2,51]),t(_,[2,10]),t(_,[2,22],{30:41,29:56,24:S,27:C}),t(_,[2,24]),t(_,[2,25]),{31:[1,57]},{11:59,32:58,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},t(_,[2,11]),t(_,[2,30],{33:60,27:w}),t(_,[2,32]),{31:[1,61]},t(_,[2,12]),{17:62,24:k},{25:63,27:D},t(_,[2,14]),{17:65,24:k},t(_,[2,16]),t(_,[2,17]),t(R,[2,41]),t(_,[2,23]),{27:[1,66]},{26:[1,67]},{26:[2,29],28:[1,68]},t(_,[2,31]),{27:[1,69]},t(_,[2,13]),{26:[1,70]},{26:[2,21],28:[1,71]},t(_,[2,15]),t(_,[2,26]),t(_,[2,27]),{11:59,32:72,37:24,38:l,39:c,40:27,41:g,42:u,43:x,44:d,45:p,46:f,47:y,48:m,49:b,50:A},t(_,[2,33]),t(_,[2,19]),{25:73,27:D},{26:[2,28]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],72:[2,28],73:[2,20]},parseError:(0,h.K2)((function(t,i){if(!i.recoverable){var e=new Error(t);throw e.hash=i,e}this.trace(t)}),"parseError"),parse:(0,h.K2)((function(t){var i=this,e=[0],s=[],n=[null],a=[],o=this.table,r="",l=0,c=0,g=0,u=a.slice.call(arguments,1),x=Object.create(this.lexer),d={yy:{}};for(var p in this.yy)Object.prototype.hasOwnProperty.call(this.yy,p)&&(d.yy[p]=this.yy[p]);x.setInput(t,d.yy),d.yy.lexer=x,d.yy.parser=this,void 0===x.yylloc&&(x.yylloc={});var f=x.yylloc;a.push(f);var y=x.options&&x.options.ranges;function m(){var t;return"number"!=typeof(t=s.pop()||x.lex()||1)&&(t instanceof Array&&(t=(s=t).pop()),t=i.symbols_[t]||t),t}"function"==typeof d.yy.parseError?this.parseError=d.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError,(0,h.K2)((function(t){e.length=e.length-2*t,n.length=n.length-t,a.length=a.length-t}),"popStack"),(0,h.K2)(m,"lex");for(var b,A,S,C,w,k,_,T,R,D={};;){if(S=e[e.length-1],this.defaultActions[S]?C=this.defaultActions[S]:(null==b&&(b=m()),C=o[S]&&o[S][b]),void 0===C||!C.length||!C[0]){var L="";for(k in R=[],o[S])this.terminals_[k]&&k>2&&R.push("'"+this.terminals_[k]+"'");L=x.showPosition?"Parse error on line "+(l+1)+":\n"+x.showPosition()+"\nExpecting "+R.join(", ")+", got '"+(this.terminals_[b]||b)+"'":"Parse error on line "+(l+1)+": Unexpected "+(1==b?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(L,{text:x.match,token:this.terminals_[b]||b,line:x.yylineno,loc:f,expected:R})}if(C[0]instanceof Array&&C.length>1)throw new Error("Parse Error: multiple actions possible at state: "+S+", token: "+b);switch(C[0]){case 1:e.push(b),n.push(x.yytext),a.push(x.yylloc),e.push(C[1]),b=null,A?(b=A,A=null):(c=x.yyleng,r=x.yytext,l=x.yylineno,f=x.yylloc,g>0&&g--);break;case 2:if(_=this.productions_[C[1]][1],D.$=n[n.length-_],D._$={first_line:a[a.length-(_||1)].first_line,last_line:a[a.length-1].last_line,first_column:a[a.length-(_||1)].first_column,last_column:a[a.length-1].last_column},y&&(D._$.range=[a[a.length-(_||1)].range[0],a[a.length-1].range[1]]),void 0!==(w=this.performAction.apply(D,[r,c,l,d.yy,C[1],n,a].concat(u))))return w;_&&(e=e.slice(0,-1*_*2),n=n.slice(0,-1*_),a=a.slice(0,-1*_)),e.push(this.productions_[C[1]][0]),n.push(D.$),a.push(D._$),T=o[e[e.length-2]][e[e.length-1]],e.push(T);break;case 3:return!0}}return!0}),"parse")},P=function(){return{EOF:1,parseError:(0,h.K2)((function(t,i){if(!this.yy.parser)throw new Error(t);this.yy.parser.parseError(t,i)}),"parseError"),setInput:(0,h.K2)((function(t,i){return this.yy=i||this.yy||{},this._input=t,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this}),"setInput"),input:(0,h.K2)((function(){var t=this._input[0];return this.yytext+=t,this.yyleng++,this.offset++,this.match+=t,this.matched+=t,t.match(/(?:\r\n?|\n).*/g)?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),t}),"input"),unput:(0,h.K2)((function(t){var i=t.length,e=t.split(/(?:\r\n?|\n)/g);this._input=t+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),e.length-1&&(this.yylineno-=e.length-1);var n=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:e?(e.length===s.length?this.yylloc.first_column:0)+s[s.length-e.length].length-e[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[n[0],n[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this}),"unput"),more:(0,h.K2)((function(){return this._more=!0,this}),"more"),reject:(0,h.K2)((function(){return this.options.backtrack_lexer?(this._backtrack=!0,this):this.parseError("Lexical error on line "+(this.yylineno+1)+". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"reject"),less:(0,h.K2)((function(t){this.unput(this.match.slice(t))}),"less"),pastInput:(0,h.K2)((function(){var t=this.matched.substr(0,this.matched.length-this.match.length);return(t.length>20?"...":"")+t.substr(-20).replace(/\n/g,"")}),"pastInput"),upcomingInput:(0,h.K2)((function(){var t=this.match;return t.length<20&&(t+=this._input.substr(0,20-t.length)),(t.substr(0,20)+(t.length>20?"...":"")).replace(/\n/g,"")}),"upcomingInput"),showPosition:(0,h.K2)((function(){var t=this.pastInput(),i=new Array(t.length+1).join("-");return t+this.upcomingInput()+"\n"+i+"^"}),"showPosition"),test_match:(0,h.K2)((function(t,i){var e,s,n;if(this.options.backtrack_lexer&&(n={yylineno:this.yylineno,yylloc:{first_line:this.yylloc.first_line,last_line:this.last_line,first_column:this.yylloc.first_column,last_column:this.yylloc.last_column},yytext:this.yytext,match:this.match,matches:this.matches,matched:this.matched,yyleng:this.yyleng,offset:this.offset,_more:this._more,_input:this._input,yy:this.yy,conditionStack:this.conditionStack.slice(0),done:this.done},this.options.ranges&&(n.yylloc.range=this.yylloc.range.slice(0))),(s=t[0].match(/(?:\r\n?|\n).*/g))&&(this.yylineno+=s.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:s?s[s.length-1].length-s[s.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+t[0].length},this.yytext+=t[0],this.match+=t[0],this.matches=t,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._backtrack=!1,this._input=this._input.slice(t[0].length),this.matched+=t[0],e=this.performAction.call(this,this.yy,this,i,this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),e)return e;if(this._backtrack){for(var a in n)this[a]=n[a];return!1}return!1}),"test_match"),next:(0,h.K2)((function(){if(this.done)return this.EOF;var t,i,e,s;this._input||(this.done=!0),this._more||(this.yytext="",this.match="");for(var n=this._currentRules(),a=0;a<n.length;a++)if((e=this._input.match(this.rules[n[a]]))&&(!i||e[0].length>i[0].length)){if(i=e,s=a,this.options.backtrack_lexer){if(!1!==(t=this.test_match(e,n[a])))return t;if(this._backtrack){i=!1;continue}return!1}if(!this.options.flex)break}return i?!1!==(t=this.test_match(i,n[s]))&&t:""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}),"next"),lex:(0,h.K2)((function(){var t=this.next();return t||this.lex()}),"lex"),begin:(0,h.K2)((function(t){this.conditionStack.push(t)}),"begin"),popState:(0,h.K2)((function(){return this.conditionStack.length-1>0?this.conditionStack.pop():this.conditionStack[0]}),"popState"),_currentRules:(0,h.K2)((function(){return this.conditionStack.length&&this.conditionStack[this.conditionStack.length-1]?this.conditions[this.conditionStack[this.conditionStack.length-1]].rules:this.conditions.INITIAL.rules}),"_currentRules"),topState:(0,h.K2)((function(t){return(t=this.conditionStack.length-1-Math.abs(t||0))>=0?this.conditionStack[t]:"INITIAL"}),"topState"),pushState:(0,h.K2)((function(t){this.begin(t)}),"pushState"),stateStackSize:(0,h.K2)((function(){return this.conditionStack.length}),"stateStackSize"),options:{"case-insensitive":!0},performAction:(0,h.K2)((function(t,i,e,s){switch(e){case 0:case 1:case 5:case 43:break;case 2:case 3:return this.popState(),34;case 4:return 34;case 6:return 10;case 7:return this.pushState("acc_title"),19;case 8:return this.popState(),"acc_title_value";case 9:return this.pushState("acc_descr"),21;case 10:return this.popState(),"acc_descr_value";case 11:this.pushState("acc_descr_multiline");break;case 12:case 25:case 27:this.popState();break;case 13:return"acc_descr_multiline_value";case 14:return 5;case 15:return 8;case 16:return this.pushState("axis_data"),"X_AXIS";case 17:return this.pushState("axis_data"),"Y_AXIS";case 18:return this.pushState("axis_band_data"),24;case 19:return 31;case 20:return this.pushState("data"),16;case 21:return this.pushState("data"),18;case 22:return this.pushState("data_inner"),24;case 23:return 27;case 24:return this.popState(),26;case 26:this.pushState("string");break;case 28:return"STR";case 29:return 24;case 30:return 26;case 31:return 43;case 32:return"COLON";case 33:return 44;case 34:return 28;case 35:return 45;case 36:return 46;case 37:return 48;case 38:return 50;case 39:return 47;case 40:return 41;case 41:return 49;case 42:return 42;case 44:return 35;case 45:return 36}}),"anonymous"),rules:[/^(?:%%(?!\{)[^\n]*)/i,/^(?:[^\}]%%[^\n]*)/i,/^(?:(\r?\n))/i,/^(?:(\r?\n))/i,/^(?:[\n\r]+)/i,/^(?:%%[^\n]*)/i,/^(?:title\b)/i,/^(?:accTitle\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*:\s*)/i,/^(?:(?!\n||)*[^\n]*)/i,/^(?:accDescr\s*\{\s*)/i,/^(?:\{)/i,/^(?:[^\}]*)/i,/^(?:xychart-beta\b)/i,/^(?:(?:vertical|horizontal))/i,/^(?:x-axis\b)/i,/^(?:y-axis\b)/i,/^(?:\[)/i,/^(?:-->)/i,/^(?:line\b)/i,/^(?:bar\b)/i,/^(?:\[)/i,/^(?:[+-]?(?:\d+(?:\.\d+)?|\.\d+))/i,/^(?:\])/i,/^(?:(?:`\) \{ this\.pushState\(md_string\); \}\n<md_string>\(\?:\(\?!`"\)\.\)\+ \{ return MD_STR; \}\n<md_string>\(\?:`))/i,/^(?:["])/i,/^(?:["])/i,/^(?:[^"]*)/i,/^(?:\[)/i,/^(?:\])/i,/^(?:[A-Za-z]+)/i,/^(?::)/i,/^(?:\+)/i,/^(?:,)/i,/^(?:=)/i,/^(?:\*)/i,/^(?:#)/i,/^(?:[\_])/i,/^(?:\.)/i,/^(?:&)/i,/^(?:-)/i,/^(?:[0-9]+)/i,/^(?:\s+)/i,/^(?:;)/i,/^(?:$)/i],conditions:{data_inner:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,23,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},data:{rules:[0,1,3,4,5,6,7,9,11,14,15,16,17,20,21,22,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_band_data:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,24,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},axis_data:{rules:[0,1,2,4,5,6,7,9,11,14,15,16,17,18,19,20,21,23,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0},acc_descr_multiline:{rules:[12,13],inclusive:!1},acc_descr:{rules:[10],inclusive:!1},acc_title:{rules:[8],inclusive:!1},title:{rules:[],inclusive:!1},md_string:{rules:[],inclusive:!1},string:{rules:[27,28],inclusive:!1},INITIAL:{rules:[0,1,4,5,6,7,9,11,14,15,16,17,20,21,25,26,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],inclusive:!0}}}}();function E(){this.yy={}}return L.lexer=P,(0,h.K2)(E,"Parser"),E.prototype=L,L.Parser=E,new E}();r.parser=r;var l=r;function c(t){return"bar"===t.type}function g(t){return"band"===t.type}function u(t){return"linear"===t.type}(0,h.K2)(c,"isBarPlot"),(0,h.K2)(g,"isBandAxisData"),(0,h.K2)(u,"isLinearAxisData");var x=class{constructor(t){this.parentGroup=t}static{(0,h.K2)(this,"TextDimensionCalculatorWithFont")}getMaxDimension(t,i){if(!this.parentGroup)return{width:t.reduce(((t,i)=>Math.max(i.length,t)),0)*i,height:i};const e={width:0,height:0},n=this.parentGroup.append("g").attr("visibility","hidden").attr("font-size",i);for(const a of t){const t=(0,s.W6)(n,1,a),h=t?t.width:a.length*i,o=t?t.height:i;e.width=Math.max(e.width,h),e.height=Math.max(e.height,o)}return n.remove(),e}},d=class{constructor(t,i,e,s){this.axisConfig=t,this.title=i,this.textDimensionCalculator=e,this.axisThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left",this.showTitle=!1,this.showLabel=!1,this.showTick=!1,this.showAxisLine=!1,this.outerPadding=0,this.titleTextHeight=0,this.labelTextHeight=0,this.range=[0,10],this.boundingRect={x:0,y:0,width:0,height:0},this.axisPosition="left"}static{(0,h.K2)(this,"BaseAxis")}setRange(t){this.range=t,"left"===this.axisPosition||"right"===this.axisPosition?this.boundingRect.height=t[1]-t[0]:this.boundingRect.width=t[1]-t[0],this.recalculateScale()}getRange(){return[this.range[0]+this.outerPadding,this.range[1]-this.outerPadding]}setAxisPosition(t){this.axisPosition=t,this.setRange(this.range)}getTickDistance(){const t=this.getRange();return Math.abs(t[0]-t[1])/this.getTickValues().length}getAxisOuterPadding(){return this.outerPadding}getLabelDimension(){return this.textDimensionCalculator.getMaxDimension(this.getTickValues().map((t=>t.toString())),this.axisConfig.labelFontSize)}recalculateOuterPaddingToDrawBar(){.7*this.getTickDistance()>2*this.outerPadding&&(this.outerPadding=Math.floor(.7*this.getTickDistance()/2)),this.recalculateScale()}calculateSpaceIfDrawnHorizontally(t){let i=t.height;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.width;this.outerPadding=Math.min(e.width/2,s);const n=e.height+2*this.axisConfig.labelPadding;this.labelTextHeight=e.height,n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width,this.boundingRect.height=t.height-i}calculateSpaceIfDrawnVertical(t){let i=t.width;if(this.axisConfig.showAxisLine&&i>this.axisConfig.axisLineWidth&&(i-=this.axisConfig.axisLineWidth,this.showAxisLine=!0),this.axisConfig.showLabel){const e=this.getLabelDimension(),s=.2*t.height;this.outerPadding=Math.min(e.height/2,s);const n=e.width+2*this.axisConfig.labelPadding;n<=i&&(i-=n,this.showLabel=!0)}if(this.axisConfig.showTick&&i>=this.axisConfig.tickLength&&(this.showTick=!0,i-=this.axisConfig.tickLength),this.axisConfig.showTitle&&this.title){const t=this.textDimensionCalculator.getMaxDimension([this.title],this.axisConfig.titleFontSize),e=t.height+2*this.axisConfig.titlePadding;this.titleTextHeight=t.height,e<=i&&(i-=e,this.showTitle=!0)}this.boundingRect.width=t.width-i,this.boundingRect.height=t.height}calculateSpace(t){return"left"===this.axisPosition||"right"===this.axisPosition?this.calculateSpaceIfDrawnVertical(t):this.calculateSpaceIfDrawnHorizontally(t),this.recalculateScale(),{width:this.boundingRect.width,height:this.boundingRect.height}}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}getDrawableElementsForLeftAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.x+this.boundingRect.width-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["left-axis","axisl-line"],data:[{path:`M ${i},${this.boundingRect.y} L ${i},${this.boundingRect.y+this.boundingRect.height} `,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["left-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.boundingRect.x+this.boundingRect.width-(this.showLabel?this.axisConfig.labelPadding:0)-(this.showTick?this.axisConfig.tickLength:0)-(this.showAxisLine?this.axisConfig.axisLineWidth:0),y:this.getScaleValue(t),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"middle",horizontalPos:"right"})))}),this.showTick){const i=this.boundingRect.x+this.boundingRect.width-(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["left-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${i},${this.getScaleValue(t)} L ${i-this.axisConfig.tickLength},${this.getScaleValue(t)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["left-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.axisConfig.titlePadding,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:270,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForBottomAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["bottom-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["bottom-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+this.axisConfig.labelPadding+(this.showTick?this.axisConfig.tickLength:0)+(this.showAxisLine?this.axisConfig.axisLineWidth:0),fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y+(this.showAxisLine?this.axisConfig.axisLineWidth:0);t.push({type:"path",groupTexts:["bottom-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i} L ${this.getScaleValue(t)},${i+this.axisConfig.tickLength}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["bottom-axis","title"],data:[{text:this.title,x:this.range[0]+(this.range[1]-this.range[0])/2,y:this.boundingRect.y+this.boundingRect.height-this.axisConfig.titlePadding-this.titleTextHeight,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElementsForTopAxis(){const t=[];if(this.showAxisLine){const i=this.boundingRect.y+this.boundingRect.height-this.axisConfig.axisLineWidth/2;t.push({type:"path",groupTexts:["top-axis","axis-line"],data:[{path:`M ${this.boundingRect.x},${i} L ${this.boundingRect.x+this.boundingRect.width},${i}`,strokeFill:this.axisThemeConfig.axisLineColor,strokeWidth:this.axisConfig.axisLineWidth}]})}if(this.showLabel&&t.push({type:"text",groupTexts:["top-axis","label"],data:this.getTickValues().map((t=>({text:t.toString(),x:this.getScaleValue(t),y:this.boundingRect.y+(this.showTitle?this.titleTextHeight+2*this.axisConfig.titlePadding:0)+this.axisConfig.labelPadding,fill:this.axisThemeConfig.labelColor,fontSize:this.axisConfig.labelFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"})))}),this.showTick){const i=this.boundingRect.y;t.push({type:"path",groupTexts:["top-axis","ticks"],data:this.getTickValues().map((t=>({path:`M ${this.getScaleValue(t)},${i+this.boundingRect.height-(this.showAxisLine?this.axisConfig.axisLineWidth:0)} L ${this.getScaleValue(t)},${i+this.boundingRect.height-this.axisConfig.tickLength-(this.showAxisLine?this.axisConfig.axisLineWidth:0)}`,strokeFill:this.axisThemeConfig.tickColor,strokeWidth:this.axisConfig.tickWidth})))})}return this.showTitle&&t.push({type:"text",groupTexts:["top-axis","title"],data:[{text:this.title,x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.axisConfig.titlePadding,fill:this.axisThemeConfig.titleColor,fontSize:this.axisConfig.titleFontSize,rotation:0,verticalPos:"top",horizontalPos:"center"}]}),t}getDrawableElements(){if("left"===this.axisPosition)return this.getDrawableElementsForLeftAxis();if("right"===this.axisPosition)throw Error("Drawing of right axis is not implemented");return"bottom"===this.axisPosition?this.getDrawableElementsForBottomAxis():"top"===this.axisPosition?this.getDrawableElementsForTopAxis():[]}},p=class extends d{static{(0,h.K2)(this,"BandAxis")}constructor(t,i,e,s,n){super(t,s,n,i),this.categories=e,this.scale=(0,o.WH)().domain(this.categories).range(this.getRange())}setRange(t){super.setRange(t)}recalculateScale(){this.scale=(0,o.WH)().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(.5),h.Rm.trace("BandAxis axis final categories, range: ",this.categories,this.getRange())}getTickValues(){return this.categories}getScaleValue(t){return this.scale(t)??this.getRange()[0]}},f=class extends d{static{(0,h.K2)(this,"LinearAxis")}constructor(t,i,e,s,n){super(t,s,n,i),this.domain=e,this.scale=(0,o.m4Y)().domain(this.domain).range(this.getRange())}getTickValues(){return this.scale.ticks()}recalculateScale(){const t=[...this.domain];"left"===this.axisPosition&&t.reverse(),this.scale=(0,o.m4Y)().domain(t).range(this.getRange())}getScaleValue(t){return this.scale(t)}};function y(t,i,e,s){const n=new x(s);return g(t)?new p(i,e,t.categories,t.title,n):new f(i,e,[t.min,t.max],t.title,n)}(0,h.K2)(y,"getAxis");var m=class{constructor(t,i,e,s){this.textDimensionCalculator=t,this.chartConfig=i,this.chartData=e,this.chartThemeConfig=s,this.boundingRect={x:0,y:0,width:0,height:0},this.showChartTitle=!1}static{(0,h.K2)(this,"ChartTitle")}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){const i=this.textDimensionCalculator.getMaxDimension([this.chartData.title],this.chartConfig.titleFontSize),e=Math.max(i.width,t.width),s=i.height+2*this.chartConfig.titlePadding;return i.width<=e&&i.height<=s&&this.chartConfig.showTitle&&this.chartData.title&&(this.boundingRect.width=e,this.boundingRect.height=s,this.showChartTitle=!0),{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){const t=[];return this.showChartTitle&&t.push({groupTexts:["chart-title"],type:"text",data:[{fontSize:this.chartConfig.titleFontSize,text:this.chartData.title,verticalPos:"middle",horizontalPos:"center",x:this.boundingRect.x+this.boundingRect.width/2,y:this.boundingRect.y+this.boundingRect.height/2,fill:this.chartThemeConfig.titleColor,rotation:0}]}),t}};function b(t,i,e,s){const n=new x(s);return new m(n,t,i,e)}(0,h.K2)(b,"getChartTitleComponent");var A=class{constructor(t,i,e,s,n){this.plotData=t,this.xAxis=i,this.yAxis=e,this.orientation=s,this.plotIndex=n}static{(0,h.K2)(this,"LinePlot")}getDrawableElement(){const t=this.plotData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])]));let i;return i="horizontal"===this.orientation?(0,o.n8j)().y((t=>t[0])).x((t=>t[1]))(t):(0,o.n8j)().x((t=>t[0])).y((t=>t[1]))(t),i?[{groupTexts:["plot",`line-plot-${this.plotIndex}`],type:"path",data:[{path:i,strokeFill:this.plotData.strokeFill,strokeWidth:this.plotData.strokeWidth}]}]:[]}},S=class{constructor(t,i,e,s,n,a){this.barData=t,this.boundingRect=i,this.xAxis=e,this.yAxis=s,this.orientation=n,this.plotIndex=a}static{(0,h.K2)(this,"BarPlot")}getDrawableElement(){const t=this.barData.data.map((t=>[this.xAxis.getScaleValue(t[0]),this.yAxis.getScaleValue(t[1])])),i=.95*Math.min(2*this.xAxis.getAxisOuterPadding(),this.xAxis.getTickDistance()),e=i/2;return"horizontal"===this.orientation?[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:this.boundingRect.x,y:t[0]-e,height:i,width:t[1]-this.boundingRect.x,fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]:[{groupTexts:["plot",`bar-plot-${this.plotIndex}`],type:"rect",data:t.map((t=>({x:t[0]-e,y:t[1],width:i,height:this.boundingRect.y+this.boundingRect.height-t[1],fill:this.barData.fill,strokeWidth:0,strokeFill:this.barData.fill})))}]}},C=class{constructor(t,i,e){this.chartConfig=t,this.chartData=i,this.chartThemeConfig=e,this.boundingRect={x:0,y:0,width:0,height:0}}static{(0,h.K2)(this,"BasePlot")}setAxes(t,i){this.xAxis=t,this.yAxis=i}setBoundingBoxXY(t){this.boundingRect.x=t.x,this.boundingRect.y=t.y}calculateSpace(t){return this.boundingRect.width=t.width,this.boundingRect.height=t.height,{width:this.boundingRect.width,height:this.boundingRect.height}}getDrawableElements(){if(!this.xAxis||!this.yAxis)throw Error("Axes must be passed to render Plots");const t=[];for(const[i,e]of this.chartData.plots.entries())switch(e.type){case"line":{const s=new A(e,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}break;case"bar":{const s=new S(e,this.boundingRect,this.xAxis,this.yAxis,this.chartConfig.chartOrientation,i);t.push(...s.getDrawableElement())}}return t}};function w(t,i,e){return new C(t,i,e)}(0,h.K2)(w,"getPlotComponent");var k,_=class{constructor(t,i,e,s){this.chartConfig=t,this.chartData=i,this.componentStore={title:b(t,i,e,s),plot:w(t,i,e),xAxis:y(i.xAxis,t.xAxis,{titleColor:e.xAxisTitleColor,labelColor:e.xAxisLabelColor,tickColor:e.xAxisTickColor,axisLineColor:e.xAxisLineColor},s),yAxis:y(i.yAxis,t.yAxis,{titleColor:e.yAxisTitleColor,labelColor:e.yAxisLabelColor,tickColor:e.yAxisTickColor,axisLineColor:e.yAxisLineColor},s)}}static{(0,h.K2)(this,"Orchestrator")}calculateVerticalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),a=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),h=this.componentStore.plot.calculateSpace({width:n,height:a});t-=h.width,i-=h.height,h=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),s=h.height,i-=h.height,this.componentStore.xAxis.setAxisPosition("bottom"),h=this.componentStore.xAxis.calculateSpace({width:t,height:i}),i-=h.height,this.componentStore.yAxis.setAxisPosition("left"),h=this.componentStore.yAxis.calculateSpace({width:t,height:i}),e=h.width,t-=h.width,t>0&&(n+=t,t=0),i>0&&(a+=i,i=0),this.componentStore.plot.calculateSpace({width:n,height:a}),this.componentStore.plot.setBoundingBoxXY({x:e,y:s}),this.componentStore.xAxis.setRange([e,e+n]),this.componentStore.xAxis.setBoundingBoxXY({x:e,y:s+a}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:0,y:s}),this.chartData.plots.some((t=>c(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateHorizontalSpace(){let t=this.chartConfig.width,i=this.chartConfig.height,e=0,s=0,n=0,a=Math.floor(t*this.chartConfig.plotReservedSpacePercent/100),h=Math.floor(i*this.chartConfig.plotReservedSpacePercent/100),o=this.componentStore.plot.calculateSpace({width:a,height:h});t-=o.width,i-=o.height,o=this.componentStore.title.calculateSpace({width:this.chartConfig.width,height:i}),e=o.height,i-=o.height,this.componentStore.xAxis.setAxisPosition("left"),o=this.componentStore.xAxis.calculateSpace({width:t,height:i}),t-=o.width,s=o.width,this.componentStore.yAxis.setAxisPosition("top"),o=this.componentStore.yAxis.calculateSpace({width:t,height:i}),i-=o.height,n=e+o.height,t>0&&(a+=t,t=0),i>0&&(h+=i,i=0),this.componentStore.plot.calculateSpace({width:a,height:h}),this.componentStore.plot.setBoundingBoxXY({x:s,y:n}),this.componentStore.yAxis.setRange([s,s+a]),this.componentStore.yAxis.setBoundingBoxXY({x:s,y:e}),this.componentStore.xAxis.setRange([n,n+h]),this.componentStore.xAxis.setBoundingBoxXY({x:0,y:n}),this.chartData.plots.some((t=>c(t)))&&this.componentStore.xAxis.recalculateOuterPaddingToDrawBar()}calculateSpace(){"horizontal"===this.chartConfig.chartOrientation?this.calculateHorizontalSpace():this.calculateVerticalSpace()}getDrawableElement(){this.calculateSpace();const t=[];this.componentStore.plot.setAxes(this.componentStore.xAxis,this.componentStore.yAxis);for(const i of Object.values(this.componentStore))t.push(...i.getDrawableElements());return t}},T=class{static{(0,h.K2)(this,"XYChartBuilder")}static build(t,i,e,s){return new _(t,i,e,s).getDrawableElement()}},R=0,D=$(),L=I(),P=M(),E=L.plotColorPalette.split(",").map((t=>t.trim())),v=!1,K=!1;function I(){const t=(0,h.P$)(),i=(0,h.zj)();return(0,n.$t)(t.xyChart,i.themeVariables.xyChart)}function $(){const t=(0,h.zj)();return(0,n.$t)(h.UI.xyChart,t.xyChart)}function M(){return{yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]}}function B(t){const i=(0,h.zj)();return(0,h.jZ)(t.trim(),i)}function z(t){k=t}function W(t){D.chartOrientation="horizontal"===t?"horizontal":"vertical"}function O(t){P.xAxis.title=B(t.text)}function F(t,i){P.xAxis={type:"linear",title:P.xAxis.title,min:t,max:i},v=!0}function N(t){P.xAxis={type:"band",title:P.xAxis.title,categories:t.map((t=>B(t.text)))},v=!0}function V(t){P.yAxis.title=B(t.text)}function X(t,i){P.yAxis={type:"linear",title:P.yAxis.title,min:t,max:i},K=!0}function Y(t){const i=Math.min(...t),e=Math.max(...t),s=u(P.yAxis)?P.yAxis.min:1/0,n=u(P.yAxis)?P.yAxis.max:-1/0;P.yAxis={type:"linear",title:P.yAxis.title,min:Math.min(s,i),max:Math.max(n,e)}}function U(t){let i=[];if(0===t.length)return i;if(!v){const i=u(P.xAxis)?P.xAxis.min:1/0,e=u(P.xAxis)?P.xAxis.max:-1/0;F(Math.min(i,1),Math.max(e,t.length))}if(K||Y(t),g(P.xAxis)&&(i=P.xAxis.categories.map(((i,e)=>[i,t[e]]))),u(P.xAxis)){const e=P.xAxis.min,s=P.xAxis.max,n=(s-e)/(t.length-1),a=[];for(let t=e;t<=s;t+=n)a.push(`${t}`);i=a.map(((i,e)=>[i,t[e]]))}return i}function H(t){return E[0===t?0:t%E.length]}function j(t,i){const e=U(i);P.plots.push({type:"line",strokeFill:H(R),strokeWidth:2,data:e}),R++}function G(t,i){const e=U(i);P.plots.push({type:"bar",fill:H(R),data:e}),R++}function Q(){if(0===P.plots.length)throw Error("No Plot to render, please provide a plot with some data");return P.title=(0,h.ab)(),T.build(D,P,L,k)}function Z(){return L}function q(){return D}(0,h.K2)(I,"getChartDefaultThemeConfig"),(0,h.K2)($,"getChartDefaultConfig"),(0,h.K2)(M,"getChartDefaultData"),(0,h.K2)(B,"textSanitizer"),(0,h.K2)(z,"setTmpSVGG"),(0,h.K2)(W,"setOrientation"),(0,h.K2)(O,"setXAxisTitle"),(0,h.K2)(F,"setXAxisRangeData"),(0,h.K2)(N,"setXAxisBand"),(0,h.K2)(V,"setYAxisTitle"),(0,h.K2)(X,"setYAxisRangeData"),(0,h.K2)(Y,"setYAxisRangeFromPlotData"),(0,h.K2)(U,"transformDataWithoutCategory"),(0,h.K2)(H,"getPlotColorFromPalette"),(0,h.K2)(j,"setLineData"),(0,h.K2)(G,"setBarData"),(0,h.K2)(Q,"getDrawableElem"),(0,h.K2)(Z,"getChartThemeConfig"),(0,h.K2)(q,"getChartConfig");var J={parser:l,db:{getDrawableElem:Q,clear:(0,h.K2)((function(){(0,h.IU)(),R=0,D=$(),P={yAxis:{type:"linear",title:"",min:1/0,max:-1/0},xAxis:{type:"band",title:"",categories:[]},title:"",plots:[]},L=I(),E=L.plotColorPalette.split(",").map((t=>t.trim())),v=!1,K=!1}),"clear"),setAccTitle:h.SV,getAccTitle:h.iN,setDiagramTitle:h.ke,getDiagramTitle:h.ab,getAccDescription:h.m7,setAccDescription:h.EI,setOrientation:W,setXAxisTitle:O,setXAxisRangeData:F,setXAxisBand:N,setYAxisTitle:V,setYAxisRangeData:X,setLineData:j,setBarData:G,setTmpSVGG:z,getChartThemeConfig:Z,getChartConfig:q},renderer:{draw:(0,h.K2)(((t,i,e,s)=>{const n=s.db,o=n.getChartThemeConfig(),r=n.getChartConfig();function l(t){return"top"===t?"text-before-edge":"middle"}function c(t){return"left"===t?"start":"right"===t?"end":"middle"}function g(t){return`translate(${t.x}, ${t.y}) rotate(${t.rotation||0})`}(0,h.K2)(l,"getDominantBaseLine"),(0,h.K2)(c,"getTextAnchor"),(0,h.K2)(g,"getTextTransformation"),h.Rm.debug("Rendering xychart chart\n"+t);const u=(0,a.D)(i),x=u.append("g").attr("class","main"),d=x.append("rect").attr("width",r.width).attr("height",r.height).attr("class","background");(0,h.a$)(u,r.height,r.width,!0),u.attr("viewBox",`0 0 ${r.width} ${r.height}`),d.attr("fill",o.backgroundColor),n.setTmpSVGG(u.append("g").attr("class","mermaid-tmp-group"));const p=n.getDrawableElem(),f={};function y(t){let i=x,e="";for(const[s]of t.entries()){let n=x;s>0&&f[e]&&(n=f[e]),e+=t[s],i=f[e],i||(i=f[e]=n.append("g").attr("class",t[s]))}return i}(0,h.K2)(y,"getGroup");for(const a of p){if(0===a.data.length)continue;const t=y(a.groupTexts);switch(a.type){case"rect":t.selectAll("rect").data(a.data).enter().append("rect").attr("x",(t=>t.x)).attr("y",(t=>t.y)).attr("width",(t=>t.width)).attr("height",(t=>t.height)).attr("fill",(t=>t.fill)).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth));break;case"text":t.selectAll("text").data(a.data).enter().append("text").attr("x",0).attr("y",0).attr("fill",(t=>t.fill)).attr("font-size",(t=>t.fontSize)).attr("dominant-baseline",(t=>l(t.verticalPos))).attr("text-anchor",(t=>c(t.horizontalPos))).attr("transform",(t=>g(t))).text((t=>t.text));break;case"path":t.selectAll("path").data(a.data).enter().append("path").attr("d",(t=>t.path)).attr("fill",(t=>t.fill?t.fill:"none")).attr("stroke",(t=>t.strokeFill)).attr("stroke-width",(t=>t.strokeWidth))}}}),"draw")}}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/98367cce.28290f99.js b/pr-preview/pr-976/assets/js/98367cce.28290f99.js new file mode 100644 index 0000000000..d908673d2b --- /dev/null +++ b/pr-preview/pr-976/assets/js/98367cce.28290f99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[133],{71663:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-0.8/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/0.8/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/basics/security-benefits.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.8/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(47262).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(95300).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},95300:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},47262:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9875.78d2cec3.js b/pr-preview/pr-976/assets/js/9875.78d2cec3.js new file mode 100644 index 0000000000..aeae7f932d --- /dev/null +++ b/pr-preview/pr-976/assets/js/9875.78d2cec3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9875],{29875:(r,e,t)=>{t.d(e,{diagram:()=>c});var s=t(69664),a=(t(79972),t(79740),t(6396),t(5081),t(34483),t(52294),t(62392),t(86825),t(85039),t(45567)),c={parser:s.Zk,db:s.iP,renderer:s.q7,styles:s.tM,init:(0,a.K2)((r=>{r.state||(r.state={}),r.state.arrowMarkerAbsolute=r.arrowMarkerAbsolute,s.iP.clear()}),"init")}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/989c6d03.4ac694c4.js b/pr-preview/pr-976/assets/js/989c6d03.4ac694c4.js new file mode 100644 index 0000000000..bf0f4c41da --- /dev/null +++ b/pr-preview/pr-976/assets/js/989c6d03.4ac694c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[782],{91122:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/docs/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/next/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/components/policies.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/next/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/next/components/service-mesh"}}');var s=n(74848),r=n(28453);const o={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2},{value:"Platform Differences",id:"platform-differences",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," or TDX ",(0,s.jsx)(t.code,{children:"MRCONFIGID"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," or ",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"/",(0,s.jsx)(t.code,{children:"MRCONFIGID"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."}),"\n",(0,s.jsx)(t.h2,{id:"platform-differences",children:"Platform Differences"}),"\n",(0,s.jsx)(t.p,{children:"Contrast uses different rules and data sections for different platforms.\nThis results in different policy hashes for different platforms."}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"generate"})," command automatically derives the correct set of rules and data sections from the ",(0,s.jsx)(t.code,{children:"reference-values"})," flag."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"verify"}),", ",(0,s.jsx)(t.code,{children:"set"}),", and ",(0,s.jsx)(t.code,{children:"recover"})," commands need to know the coordinator's expected policy hash to verify its identity.\nBy default these commands assume that the coordinator is using the policy for the ",(0,s.jsx)(t.code,{children:"AKS-CLH-SNP"})," platform.\nIf the coordinator is running on a different platform, the correct policy hash can be looked up in the ",(0,s.jsx)(t.code,{children:"coordinator-policy.hash"})," file bundled with the ",(0,s.jsx)(t.a,{href:"https://github.com/edgelesssys/contrast/releases",children:"Contrast release"}),".\nThe coordinator policy hash can be overwritten using the ",(0,s.jsx)(t.code,{children:"--coordinator-policy-hash"})," flag."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9a06ae3d.046ea467.js b/pr-preview/pr-976/assets/js/9a06ae3d.046ea467.js new file mode 100644 index 0000000000..162e7cf661 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9a06ae3d.046ea467.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2912],{56704:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>l});const t=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/docs/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/getting-started/cluster-setup.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/next/getting-started/install"},"next":{"title":"Bare metal setup","permalink":"/contrast/pr-preview/pr-976/next/getting-started/bare-metal"}}');var s=r(74848),a=r(28453);const o={},i="Create a cluster",c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Install version 2.44.1 or newer of the ",(0,s.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),". Note that your package manager will likely install an outdated version."]}),"\n",(0,s.jsxs)(n.li,{children:["Install a recent version of ",(0,s.jsx)(n.a,{href:"https://kubernetes.io/docs/tasks/tools/",children:"kubectl"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,s.jsx)(n.p,{children:"First, log in to your Azure subscription:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,s.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,s.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,s.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,s.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,s.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,s.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,s.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,s.jsx)(n.p,{children:"First, create a CoCo enabled AKS cluster with:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.30 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,s.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["For validation, list the available nodes using ",(0,s.jsx)(n.code,{children:"kubectl"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,s.jsx)(n.p,{children:"It should show a single node:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\n"})}),"\n",(0,s.jsxs)(n.p,{children:["\ud83e\udd73 Congratulations. You're now ready to set up your first application with Contrast. Follow this ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/examples/emojivoto",children:"example"})," to learn how."]}),"\n",(0,s.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,s.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,s.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,s.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>i});var t=r(96540);const s={},a=t.createContext(s);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9a28f5c4.01963c55.js b/pr-preview/pr-976/assets/js/9a28f5c4.01963c55.js new file mode 100644 index 0000000000..313f0fd70c --- /dev/null +++ b/pr-preview/pr-976/assets/js/9a28f5c4.01963c55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3505],{99764:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-0.9/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/0.9/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/examples/emojivoto.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.9/deployment"}}');var i=n(74848),s=n(28453);const a={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Downloading the deployment",id:"downloading-the-deployment",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(2115).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"downloading-the-deployment",children:"Downloading the deployment"}),"\n",(0,i.jsx)(t.p,{children:"The emojivoto deployment files are part of Contrast release. You can download the\nlatest deployment by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.9.0/emojivoto-demo.yml --create-dirs --output-dir deployment\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,i.jsxs)(t.p,{children:["Contrast depends on a ",(0,i.jsxs)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/runtime",children:["custom Kubernetes ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," (",(0,i.jsx)(t.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,i.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/runtime.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.9.0/coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp deployment/\n"})}),"\n",(0,i.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,i.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,i.jsx)(t.code,{children:"contrast-cc-<platform>-<runtime-hash>"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/overview#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,i.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the reference values from the manifest to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313" -m manifest.json\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs\nto be communicated out of band to everyone wanting to verify the deployment, as the ",(0,i.jsx)(t.code,{children:"verify"})," command checks\nif the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},2115:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9a99019d.7c69ee4c.js b/pr-preview/pr-976/assets/js/9a99019d.7c69ee4c.js new file mode 100644 index 0000000000..32ee23cd35 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9a99019d.7c69ee4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[801],{89293:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-0.7/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/0.7/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/intro.md","tags":[],"version":"0.7","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Contrast concept",src:n(96274).A+"",width:"1644",height:"764"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/getting-started/",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},96274:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/concept-c1792eb1b8f3959308512d1e518b0176.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9c8ec574.c337425b.js b/pr-preview/pr-976/assets/js/9c8ec574.c337425b.js new file mode 100644 index 0000000000..0ad8a0d197 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9c8ec574.c337425b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1831],{81069:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"0.9","label":"0.9","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.9","isLast":false,"docsSidebars":{"docs":[{"type":"link","label":"What is Contrast?","href":"/contrast/pr-preview/pr-976/0.9/","docId":"intro","unlisted":false},{"type":"category","label":"Basics","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/0.9/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/0.9/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/0.9/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false}],"collapsible":true},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/0.9/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/0.9/deployment","docId":"deployment","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/contrast/pr-preview/pr-976/0.9/troubleshooting","docId":"troubleshooting","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Overview","href":"/contrast/pr-preview/pr-976/0.9/components/overview","docId":"components/overview","unlisted":false},{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/0.9/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/0.9/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/0.9/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/0.9/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Secrets & recovery","href":"/contrast/pr-preview/pr-976/0.9/architecture/secrets","docId":"architecture/secrets","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/0.9/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/0.9/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/0.9/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/0.9/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true}]},"docs":{"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"architecture/secrets":{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/overview":{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"troubleshooting":{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9ccb1fc6.873740e8.js b/pr-preview/pr-976/assets/js/9ccb1fc6.873740e8.js new file mode 100644 index 0000000000..3f7d1dcf1e --- /dev/null +++ b/pr-preview/pr-976/assets/js/9ccb1fc6.873740e8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9874],{65339:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/versioned_docs/version-0.8/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/0.8/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/components/runtime.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/0.8/components/overview"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.8/components/policies"}}');var i=t(74848),r=t(28453);const o={},a="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"<code>cloud-hypervisor</code> virtual machine manager (VMM)",id:"cloud-hypervisor-virtual-machine-manager-vmm",level:3},{value:"<code>Tardev snapshotter</code>",id:"tardev-snapshotter",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(24261).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsxs)(n.h3,{id:"cloud-hypervisor-virtual-machine-manager-vmm",children:[(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," virtual machine manager (VMM)"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})})," to create a confidential virtual machine for every pod.\nThis requires the ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," binary to be installed on every node (responsibility of the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),")."]}),"\n",(0,i.jsx)(n.h3,{id:"tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"Tardev snapshotter"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses a special ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotter"]})," (",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})}),") to provide container images as block devices to the pod-VM. This snapshotter consists of a host component that pulls container images and a guest component (kernel module) used to mount container images.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},24261:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9ce1fd56.9821471c.js b/pr-preview/pr-976/assets/js/9ce1fd56.9821471c.js new file mode 100644 index 0000000000..b4fa420823 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9ce1fd56.9821471c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[426],{42809:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-0.8/components/overview.md","sourceDirName":"components","slug":"/components/overview","permalink":"/contrast/pr-preview/pr-976/0.8/components/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/components/overview.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.8/troubleshooting"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.8/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},l=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(91175).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},91175:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9d9e06f4.34f01e43.js b/pr-preview/pr-976/assets/js/9d9e06f4.34f01e43.js new file mode 100644 index 0000000000..792f39abb3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/9d9e06f4.34f01e43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4670],{67766:(e,t,r)=>{r.d(t,{A:()=>C});var n=r(96540),c=r(34164),s=r(85246),o=r(57880),i=r(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const c=r.select(t),s=r.pluralForms.indexOf(c);return n[Math.min(s,n.length-1)]}(r,t,e)}}var h=r(77056),p=r(32032),f=r(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=r(74848);function j(e){let{href:t,children:r}=e;return(0,g.jsx)(o.A,{href:t,className:(0,c.A)("card padding--lg",x.cardContainer),children:r})}function v(e){let{href:t,icon:r,title:n,description:s}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,c.A)("text--truncate",x.cardTitle),title:n,children:[r," ",n]}),s&&(0,g.jsx)("p",{className:(0,c.A)("text--truncate",x.cardDescription),title:s,children:s})]})}function w(e){let{item:t}=e;const r=(0,s.Nr)(t),n=function(){const{selectMessage:e}=m();return t=>e(t,(0,p.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return r?(0,g.jsx)(v,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??n(t.items.length)}):null}function y(e){let{item:t}=e;const r=(0,h.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,s.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:r,title:t.label,description:t.description??n?.description})}function A(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(y,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function k(e){let{className:t}=e;const r=(0,s.$S)();return(0,g.jsx)(C,{items:r.items,className:t})}function C(e){const{items:t,className:r}=e;if(!t)return(0,g.jsx)(k,{...e});const n=(0,s.d1)(t);return(0,g.jsx)("section",{className:(0,c.A)("row",r),children:n.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(A,{item:e})},t)))})}},12325:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>i,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"architecture/index","title":"Architecture","description":"","source":"@site/versioned_docs/version-0.5/architecture/index.md","sourceDirName":"architecture","slug":"/architecture/","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/index.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.5/deployment"},"next":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.5/category/components"}}');var c=r(74848),s=r(28453),o=r(67766);const i={},a="Architecture",l={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"architecture",children:"Architecture"})}),"\n","\n",(0,c.jsx)(o.A,{})]})}function m(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const c={},s=n.createContext(c);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/9d9f8394.950345c7.js b/pr-preview/pr-976/assets/js/9d9f8394.950345c7.js new file mode 100644 index 0000000000..ffc0aa08aa --- /dev/null +++ b/pr-preview/pr-976/assets/js/9d9f8394.950345c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9013],{64626:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","source":"@site/docs/troubleshooting.md","sourceDirName":".","slug":"/troubleshooting","permalink":"/contrast/pr-preview/pr-976/next/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/troubleshooting.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/next/deployment"},"next":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/next/components/overview"}}');var i=t(74848),s=t(28453);const a={},r="Troubleshooting",c={},l=[{value:"Logging",id:"logging",level:2},{value:"CLI",id:"cli",level:3},{value:"Coordinator and Initializer",id:"coordinator-and-initializer",level:3},{value:"Pod fails to start",id:"pod-fails-to-start",level:2},{value:"Regenerating the policies",id:"regenerating-the-policies",level:3},{value:"Pin container images",id:"pin-container-images",level:3},{value:"Validate Contrast components match",id:"validate-contrast-components-match",level:3}];function d(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section contains information on how to debug your Contrast deployment."}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"Collecting logs can be a good first step to identify problems in your\ndeployment. Both the CLI and the Contrast Coordinator as well as the Initializer\ncan be configured to emit additional logs."}),"\n",(0,i.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.p,{children:["The CLI logs can be configured with the ",(0,i.jsx)(n.code,{children:"--log-level"})," command-line flag, which\ncan be set to either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"})," or ",(0,i.jsx)(n.code,{children:"error"}),". The default is ",(0,i.jsx)(n.code,{children:"info"}),".\nSetting this to ",(0,i.jsx)(n.code,{children:"debug"})," can get more fine-grained information as to where the\nproblem lies."]}),"\n",(0,i.jsx)(n.h3,{id:"coordinator-and-initializer",children:"Coordinator and Initializer"}),"\n",(0,i.jsxs)(n.p,{children:["The logs from the Coordinator and the Initializer can be configured via the\nenvironment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"}),", ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," and\n",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"})," can be set to one of either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"}),", or\n",(0,i.jsx)(n.code,{children:"error"}),", similar to the CLI (defaults to ",(0,i.jsx)(n.code,{children:"info"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," can be set to ",(0,i.jsx)(n.code,{children:"text"})," or ",(0,i.jsx)(n.code,{children:"json"}),", determining the output\nformat (defaults to ",(0,i.jsx)(n.code,{children:"text"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," is a comma-separated list of subsystems that should\nbe enabled for logging, which are disabled by default. Subsystems include:\n",(0,i.jsx)(n.code,{children:"kds-getter"}),", ",(0,i.jsx)(n.code,{children:"issuer"})," and ",(0,i.jsx)(n.code,{children:"validator"}),".\nTo enable all subsystems, use ",(0,i.jsx)(n.code,{children:"*"})," as the value for this environment variable.\nWarnings and error messages from subsystems get printed regardless of whether\nthe subsystem is listed in the ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," environment variable."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"To configure debug logging with all subsystems for your Coordinator, add the\nfollowing variables to your container definition."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n containers:\n image: "ghcr.io/edgelesssys/contrast/coordinator:latest"\n name: coordinator\n env:\n - name: CONTRAST_LOG_LEVEL\n value: debug\n - name: CONTRAST_LOG_SUBSYSTEMS\n value: "*"\n # ...\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["While the Contrast Coordinator has a policy that allows certain configurations,\nthe Initializer and service mesh don't. When changing environment variables of other\nparts than the Coordinator, ensure to rerun ",(0,i.jsx)(n.code,{children:"contrast generate"})," to update the policy."]})}),"\n",(0,i.jsxs)(n.p,{children:["To access the logs generated by the Coordinator, you can use ",(0,i.jsx)(n.code,{children:"kubectl"})," with the\nfollowing command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl logs <coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"pod-fails-to-start",children:"Pod fails to start"}),"\n",(0,i.jsxs)(n.p,{children:["If the Coordinator or a workload pod fails to even start, it can be helpful to\nlook at the events of the pod during the startup process using the ",(0,i.jsx)(n.code,{children:"describe"}),"\ncommand."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> events --for pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'LAST SEEN TYPE REASON OBJECT MESSAGE\n32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"A common error, as in this example, is that the container creation was blocked by the\npolicy. Potential reasons are a modification of the deployment YAML without updating\nthe policies afterward, or a version mismatch between Contrast components."}),"\n",(0,i.jsx)(n.h3,{id:"regenerating-the-policies",children:"Regenerating the policies"}),"\n",(0,i.jsx)(n.p,{children:"To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated\npolicies, rerun"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast generate\n"})}),"\n",(0,i.jsx)(n.p,{children:"on your deployment. If any of the policy annotations change, re-deploy with the updated policies."}),"\n",(0,i.jsx)(n.h3,{id:"pin-container-images",children:"Pin container images"}),"\n",(0,i.jsx)(n.p,{children:"When generating the policies, Contrast will download the images specified in your deployment\nYAML and include their cryptographic identity. If the image tag is moved to another\ncontainer image after the policy has been generated, the image downloaded at deploy time\nwill differ from the one at generation time, and the policy enforcement won't allow the\ncontainer to be started in the pod VM."}),"\n",(0,i.jsxs)(n.p,{children:["To ensure the correct image is always used, pin the container image to a fixed ",(0,i.jsx)(n.code,{children:"sha256"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This way, the same image will still be pulled when the container tag (",(0,i.jsx)(n.code,{children:"22.04"}),") is moved\nto another image."]}),"\n",(0,i.jsx)(n.h3,{id:"validate-contrast-components-match",children:"Validate Contrast components match"}),"\n",(0,i.jsx)(n.p,{children:"A version mismatch between Contrast components can cause policy validation or attestation\nto fail. Each Contrast runtime is identifiable based on its (shortened) measurement value\nused to name the runtime class version."}),"\n",(0,i.jsx)(n.p,{children:"First, analyze which runtime class is currently installed in your cluster by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl get runtimeclasses\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give you output similar to the following one."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"NAME HANDLER AGE\ncontrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h\nkata-cc-isolation kata-cc 45d\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided\nby the AKS CoCo preview, which isn't used by Contrast)."}),"\n",(0,i.jsx)(n.p,{children:"Next, check if the pod that won't start has the correct runtime class configured, and the\nCoordinator uses the exact same runtime:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>\nkubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output should list the runtime class the pod is using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast-cc-aks-clh-snp-7173acb5\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Version information about the currently used CLI can be obtained via the ",(0,i.jsx)(n.code,{children:"version"})," flag:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast --version\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast version v0.X.0\n\n runtime handler: contrast-cc-aks-clh-snp-7173acb5\n launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35\n genpolicy version: 3.2.0.azl1.genpolicy0\n image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...\n ghcr.io/edgelesssys/contrast/initializer@sha256:...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a0a1fd3b.d49c396c.js b/pr-preview/pr-976/assets/js/a0a1fd3b.d49c396c.js new file mode 100644 index 0000000000..b070b3abee --- /dev/null +++ b/pr-preview/pr-976/assets/js/a0a1fd3b.d49c396c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6755],{92395:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-1.1/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/getting-started/install.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/basics/features"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/getting-started/cluster-setup"}}');var r=s(74848),a=s(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v1.1.0/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>o,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function o(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a0a4ec6e.e66a8111.js b/pr-preview/pr-976/assets/js/a0a4ec6e.e66a8111.js new file mode 100644 index 0000000000..d329c550cb --- /dev/null +++ b/pr-preview/pr-976/assets/js/a0a4ec6e.e66a8111.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4980],{48542:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/versioned_docs/version-0.8/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/0.8/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/examples/emojivoto.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.8/deployment"}}');var i=n(74848),s=n(28453);const a={},r="Confidential emoji voting",d={},l=[{value:"Motivation",id:"motivation",level:3},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Downloading the deployment",id:"downloading-the-deployment",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Voter's perspective: Verifying the ballot",id:"voters-perspective-verifying-the-ballot",level:2},{value:"Attest the Coordinator",id:"attest-the-coordinator",level:3},{value:"Manifest history and artifact audit",id:"manifest-history-and-artifact-audit",level:3},{value:"Confidential connection to the attested workload",id:"confidential-connection-to-the-attested-workload",level:3},{value:"Certificate SAN and manifest update (optional)",id:"certificate-san-and-manifest-update-optional",level:2},{value:"Configure the service SAN in the manifest",id:"configure-the-service-san-in-the-manifest",level:3},{value:"Update the manifest",id:"update-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(88616).A+"",width:"1503",height:"732"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,i.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voters perspective."]})}),"\n",(0,i.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,i.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,i.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,i.jsx)(t.code,{children:"voting"}),"). The ",(0,i.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,i.jsx)(t.h3,{id:"motivation",children:"Motivation"}),"\n",(0,i.jsx)(t.p,{children:"Using a voting service, users' votes are considered highly sensitive data, as we require\na secret ballot. Also, users are likely interested in the fairness of the ballot. For\nboth requirements, we can use Confidential Computing and, specifically, workload attestation\nto prove to those interested in voting that the app is running in a protected environment\nwhere their votes are processed without leaking to the platform provider or workload owner."}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Installed Contrast CLI."}),"\nSee the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/getting-started/install",children:"installation instructions"})," on how to get it."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:"Running cluster with Confidential Containers support."}),"\nPlease follow the ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup",children:"cluster setup instructions"}),"\nto create a cluster."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,i.jsx)(t.h3,{id:"downloading-the-deployment",children:"Downloading the deployment"}),"\n",(0,i.jsx)(t.p,{children:"The emojivoto deployment files are part of Contrast release. You can download the\nlatest deployment by running:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/download/v0.8.1/emojivoto-demo.yml --create-dirs --output-dir deployment\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,i.jsxs)(t.p,{children:["Contrast depends on a ",(0,i.jsxs)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:["custom Kubernetes ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," (",(0,i.jsx)(t.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,i.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,i.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/runtime.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/coordinator.yml\n"})}),"\n",(0,i.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,i.jsxs)(t.p,{children:["Run the ",(0,i.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,i.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp deployment/\n"})}),"\n",(0,i.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,i.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,i.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,i.jsx)(t.code,{children:"contrast-cc-<VERSIONHASH>"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/overview#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,i.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,i.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,i.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsx)(t.p,{children:"The CLI will use the reference values from the manifest to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,i.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,i.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,i.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,i.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,i.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,i.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,i.jsx)(t.h2,{id:"voters-perspective-verifying-the-ballot",children:"Voter's perspective: Verifying the ballot"}),"\n",(0,i.jsx)(t.p,{children:"As voters, we want to verify the fairness and confidentiality of the deployment before\ndeciding to vote. Regardless of the scale of our distributed deployment, Contrast only\nneeds a single remote attestation step to verify the deployment. By doing remote attestation\nof the Coordinator, we transitively verify those systems the Coordinator has already attested\nor will attest in the future. Successful verification of the Coordinator means that\nwe can be sure it will enforce the configured manifest."}),"\n",(0,i.jsx)(t.h3,{id:"attest-the-coordinator",children:"Attest the Coordinator"}),"\n",(0,i.jsx)(t.p,{children:"A potential voter can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313" -m manifest.json\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The CLI will attest the Coordinator using the reference values from a given manifest. This manifest needs\nto be communicated out of band to everyone wanting to verify the deployment, as the ",(0,i.jsx)(t.code,{children:"verify"})," command checks\nif the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,i.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,i.jsx)(t.h3,{id:"manifest-history-and-artifact-audit",children:"Manifest history and artifact audit"}),"\n",(0,i.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,i.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,i.jsx)(t.h3,{id:"confidential-connection-to-the-attested-workload",children:"Confidential connection to the attested workload"}),"\n",(0,i.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, you can securely connect\nto the workloads using the Coordinator's ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,i.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,i.jsxs)(t.p,{children:["Using ",(0,i.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,i.jsx)(t.h2,{id:"certificate-san-and-manifest-update-optional",children:"Certificate SAN and manifest update (optional)"}),"\n",(0,i.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,i.jsx)(t.h3,{id:"configure-the-service-san-in-the-manifest",children:"Configure the service SAN in the manifest"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,i.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,i.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n'})}),"\n",(0,i.jsx)(t.h3,{id:"update-the-manifest",children:"Update the manifest"}),"\n",(0,i.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,i.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,i.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,i.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,i.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,i.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},88616:(e,t,n)=>{n.d(t,{A:()=>o});const o=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a161c24f.491f18fc.js b/pr-preview/pr-976/assets/js/a161c24f.491f18fc.js new file mode 100644 index 0000000000..814062ffea --- /dev/null +++ b/pr-preview/pr-976/assets/js/a161c24f.491f18fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1575],{82560:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the bundle from the URL you received:","source":"@site/versioned_docs/version-0.5/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/getting-started/install.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup"}}');var r=n(74848),a=n(28453);const o={},l="Installation",i={},c=[];function d(e){const t={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsxs)(s,{groupId:"method",queryString:!0,children:[(0,r.jsxs)(n,{value:"private-preview",label:"Private preview bundle",children:[(0,r.jsx)(t.p,{children:"Download the bundle from the URL you received:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"curl -fLO <URL>\n"})}),(0,r.jsx)(t.p,{children:"Then unpack the unpack the downloaded archive:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"unzip contrast.zip\n"})})]}),(0,r.jsxs)(n,{value:"release",label:"Release",children:[(0,r.jsx)(t.p,{children:"Download the Contrast CLI from the latest release:"}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"curl -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast\n"})})]})]}),"\n",(0,r.jsx)(t.p,{children:"Install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"mv contrast /usr/local/bin/contrast\n"})})]})}function p(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>l});var s=n(96540);const r={},a=s.createContext(r);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a2899f6e.7ec951c7.js b/pr-preview/pr-976/assets/js/a2899f6e.7ec951c7.js new file mode 100644 index 0000000000..3e1ee9c02f --- /dev/null +++ b/pr-preview/pr-976/assets/js/a2899f6e.7ec951c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1861],{51866:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-1.0/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/getting-started/cluster-setup.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/install"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/1.0/examples/emojivoto"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which needs\nto have the permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a\nnon-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool."}),"\n",(0,t.jsx)(n.p,{children:"We'll first start by creating the non-CoCo cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "${azResourceGroup:?}" \\\n --name nodepool2 \\\n --cluster-name "${azClusterName:?}" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Optionally, we can now remove the non-CoCo node pool:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool delete \\\n --resource-group "${azResourceGroup:?}" \\\n --cluster-name "${azClusterName:?}" \\\n --name nodepool1\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a3713279.cb16cfe2.js b/pr-preview/pr-976/assets/js/a3713279.cb16cfe2.js new file mode 100644 index 0000000000..36dd1f383f --- /dev/null +++ b/pr-preview/pr-976/assets/js/a3713279.cb16cfe2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9588],{33745:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/docs/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/next/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/deployment.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/next/examples/emojivoto"},"next":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/next/troubleshooting"}}');var r=t(74848),a=t(28453);const i={},o="Workload deployment",l={},c=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"Security review",id:"security-review",level:3},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2},{value:"Recover the Coordinator",id:"recover-the-coordinator",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components},{TabItem:t,Tabs:s}=n;return t||u("TabItem",!0),s||u("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,r.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup",children:"setup guide"})," on how to set up a cluster on AKS."]})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/bare-metal",children:"setup guide"})," on how to set up a bare-metal cluster."]})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/bare-metal",children:"setup guide"})," on how to set up a bare-metal cluster."]})})]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,r.jsxs)(n.p,{children:["Contrast depends on a ",(0,r.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:["custom Kubernetes ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," (",(0,r.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,r.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-aks-clh-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-k3s-qemu-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-aks-clh-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-k3s-qemu-snp.yml\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,r.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,r.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,r.jsx)(n.h3,{id:"security-review",children:"Security review"}),"\n",(0,r.jsxs)(n.p,{children:["Contrast ensures integrity and confidentiality of the applications, but interactions with untrusted systems require the developers' attention.\nReview the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/security-considerations",children:"security considerations"})," and the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates",children:"certificates"})," section for writing secure Contrast application."]}),"\n",(0,r.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,r.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,r.jsxs)(s,{groupId:"yaml-source",children:[(0,r.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"helm",label:"helm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"copy",label:"copy",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,r.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,r.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,r.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,r.jsxs)(n.p,{children:["In the initialization process, the ",(0,r.jsx)(n.code,{children:"contrast-secrets"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,r.jsxs)(s,{groupId:"tls",children:[(0,r.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,r.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,r.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,r.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,r.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,r.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,r.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,r.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,r.jsxs)(n.p,{children:["During the ",(0,r.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,r.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,r.jsxs)(t,{value:"go",label:"Go integration",children:[(0,r.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,r.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,r.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,r.jsxs)(s,{groupId:"golang-tls-setup",children:[(0,r.jsx)(t,{value:"client",label:"Client",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,r.jsx)(t,{value:"server",label:"Server",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/contrast/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/contrast/tls-config/certChain.pem", "/contrast/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,r.jsxs)(n.p,{children:["Run the ",(0,r.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,r.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp resources/\n"})})}),(0,r.jsxs)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp resources/\n"})}),(0,r.jsx)(n.admonition,{title:"Missing TCB values",type:"note",children:(0,r.jsxs)(n.p,{children:["On bare-metal SEV-SNP, ",(0,r.jsx)(n.code,{children:"contrast generate"})," is unable to fill in the ",(0,r.jsx)(n.code,{children:"MinimumTCB"})," values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,r.jsx)(n.code,{children:'{"BootloaderVersion":255,"TEEVersion":255,"SNPVersion":255,"MicrocodeVersion":255}'})," and observe the real values in the error messages in the following steps. This should only be done in a secure environment. Note that the values will differ between CPU models."]})})]}),(0,r.jsxs)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:[(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx resources/\n"})}),(0,r.jsx)(n.admonition,{title:"Missing TCB values",type:"note",children:(0,r.jsxs)(n.p,{children:["On bare-metal TDX, ",(0,r.jsx)(n.code,{children:"contrast generate"})," is unable to fill in the ",(0,r.jsx)(n.code,{children:"MinimumTeeTcbSvn"})," and ",(0,r.jsx)(n.code,{children:"MrSeam"})," TCB values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,r.jsx)(n.code,{children:"ffffffffffffffffffffffffffffffff"})," and ",(0,r.jsx)(n.code,{children:"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"})," respectively and observe the real values in the error messages in the following steps. This should only be done in a secure environment."]})})]})]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,r.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,r.jsxs)(s,{groupId:"injection",children:[(0,r.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,r.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,r.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,r.jsx)(n.code,{children:"generate"})," command."]}),(0,r.jsxs)(s,{queryString:"platform",children:[(0,r.jsx)(t,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp --skip-initializer resources/\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp --skip-initializer resources/\n"})})}),(0,r.jsx)(t,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx --skip-initializer resources/\n"})})})]})]}),(0,r.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,r.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,r.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,r.jsx)(n.code,{children:"contrast-secrets"})," ",(0,r.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:latest"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /contrast\n name: contrast-secrets\n volumes:\n - emptyDir: {}\n name: contrast-secrets\n'})}),"\n",(0,r.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,r.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,r.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,r.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,r.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,r.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,r.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,r.jsx)(n.p,{children:"This will use the reference values from the manifest file to attest the Coordinator.\nAfter this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,r.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,r.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the\nservice mesh root certificate and the history of manifests into the ",(0,r.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies\nreferenced in the active manifest are also written to the directory. The verification will fail if the active\nmanifest at the Coordinator doesn't match the manifest passed to the CLI."]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,r.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,r.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, attempting to connect with curl and the mesh CA certificate will throw the following error:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Using ",(0,r.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,r.jsx)(n.h2,{id:"recover-the-coordinator",children:"Recover the Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material.\nFor demonstration purposes, you can simulate this scenario by deleting the Coordinator pod."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl delete pod -l app.kubernetes.io/name=coordinator\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet.\nYou can confirm this by running ",(0,r.jsx)(n.code,{children:"verify"})," again, or you can restart a workload pod, which should stay in the initialization phase.\nHowever, the secret seed in your working directory is sufficient to recover the coordinator."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast recover -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsx)(n.p,{children:"Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state.\nYou can now verify the Coordinator again, which should return the same manifest you set before."}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The recovery process invalidates the mesh CA certificate:\nexisting workloads won't be able to communicate with workloads newly spawned.\nAll workloads should be restarted after the recovery succeeded."})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["On bare metal, the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,r.jsx)(n.code,{children:"--coordinator-policy-hash"}),"."]})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function u(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>o});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a66d714b.bad912b3.js b/pr-preview/pr-976/assets/js/a66d714b.bad912b3.js new file mode 100644 index 0000000000..af2fb11da8 --- /dev/null +++ b/pr-preview/pr-976/assets/js/a66d714b.bad912b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9974],{91304:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-0.8/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/0.8/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/deployment.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.8/examples/emojivoto"},"next":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/0.8/troubleshooting"}}');var o=t(74848),s=t(28453);const i={},a="Workload deployment",c={},l=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2},{value:"Recover the Coordinator",id:"recover-the-coordinator",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components},{TabItem:t,Tabs:r}=n;return t||p("TabItem",!0),r||p("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,o.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,o.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,o.jsxs)(n.p,{children:["Contrast depends on a ",(0,o.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/runtime",children:["custom Kubernetes ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," (",(0,o.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,o.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,o.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/runtime.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.8.1/coordinator.yml\n"})}),"\n",(0,o.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,o.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,o.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,o.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,o.jsxs)(r,{groupId:"yaml-source",children:[(0,o.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"helm",label:"helm",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,o.jsx)(t,{value:"copy",label:"copy",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,o.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,o.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,o.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,o.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,o.jsxs)(n.p,{children:["In the initialization process, the ",(0,o.jsx)(n.code,{children:"contrast-tls-certs"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,o.jsxs)(r,{groupId:"tls",children:[(0,o.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,o.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,o.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,o.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,o.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,o.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,o.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,o.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,o.jsxs)(n.p,{children:["During the ",(0,o.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,o.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,o.jsxs)(t,{value:"go",label:"Go integration",children:[(0,o.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,o.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,o.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,o.jsxs)(r,{groupId:"golang-tls-setup",children:[(0,o.jsx)(t,{value:"client",label:"Client",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,o.jsx)(t,{value:"server",label:"Server",children:(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,o.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,o.jsxs)(n.p,{children:["Run the ",(0,o.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,o.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp resources/\n"})}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,o.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,o.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,o.jsxs)(r,{groupId:"injection",children:[(0,o.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,o.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,o.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,o.jsx)(n.code,{children:"generate"})," command."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp --skip-initializer resources/\n"})})]}),(0,o.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,o.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,o.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,o.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,o.jsx)(n.code,{children:"contrast-tls-certs"})," ",(0,o.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:v0.8.1@sha256:6260af0b4ee2b5e583970aaa74ba6f5cbaa4d2029bc2aef947987d2398f1164f"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /tls-config\n name: contrast-tls-certs\n volumes:\n - emptyDir: {}\n name: contrast-tls-certs\n'})}),"\n",(0,o.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,o.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,o.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,o.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,o.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,o.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,o.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,o.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,o.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,o.jsx)(n.p,{children:"This will use the reference values from the manifest file to attest the Coordinator.\nAfter this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,o.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,o.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,o.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the\nservice mesh root certificate and the history of manifests into the ",(0,o.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies\nreferenced in the active manifest are also written to the directory. The verification will fail if the active\nmanifest at the Coordinator doesn't match the manifest passed to the CLI."]}),"\n",(0,o.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,o.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,o.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,o.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,o.jsxs)(n.p,{children:["Using ",(0,o.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,o.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,o.jsx)(n.h2,{id:"recover-the-coordinator",children:"Recover the Coordinator"}),"\n",(0,o.jsx)(n.p,{children:"If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material.\nFor demonstration purposes, you can simulate this scenario by deleting the Coordinator pod."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:"kubectl delete pod -l app.kubernetes.io/name=coordinator\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet.\nYou can confirm this by running ",(0,o.jsx)(n.code,{children:"verify"})," again, or you can restart a workload pod, which should stay in the initialization phase.\nHowever, the secret seed in your working directory is sufficient to recover the coordinator."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-sh",children:'contrast recover -c "${coordinator}:1313"\n'})}),"\n",(0,o.jsx)(n.p,{children:"Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state.\nYou can now verify the Coordinator again, which should return the same manifest you set before."}),"\n",(0,o.jsx)(n.admonition,{type:"warning",children:(0,o.jsx)(n.p,{children:"The recovery process invalidates the mesh CA certificate:\nexisting workloads won't be able to communicate with workloads newly spawned.\nAll workloads should be restarted after the recovery succeeded."})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function p(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a71cbd8f.fee2c6c8.js b/pr-preview/pr-976/assets/js/a71cbd8f.fee2c6c8.js new file mode 100644 index 0000000000..9749286768 --- /dev/null +++ b/pr-preview/pr-976/assets/js/a71cbd8f.fee2c6c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5003],{91238:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","source":"@site/versioned_docs/version-0.8/architecture/secrets.md","sourceDirName":"architecture","slug":"/architecture/secrets","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/secrets","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/architecture/secrets.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/attestation"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/certificates"}}');var i=r(74848),n=r(28453);const o={},a="Secrets & recovery",c={},d=[{value:"Persistence",id:"persistence",level:2},{value:"Recovery",id:"recovery",level:2}];function h(e){const t={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"secrets--recovery",children:"Secrets & recovery"})}),"\n",(0,i.jsx)(t.p,{children:"When the Coordinator is configured with the initial manifest, it generates a random secret seed.\nFrom this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history.\nThis derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state."}),"\n",(0,i.jsxs)(t.p,{children:["The secret seed is returned to the user on the first call to ",(0,i.jsx)(t.code,{children:"contrast set"}),", encrypted with the user's public seed share owner key.\nIf no seed share owner key is provided, a key is generated and stored in the working directory."]}),"\n",(0,i.jsx)(t.h2,{id:"persistence",children:"Persistence"}),"\n",(0,i.jsxs)(t.p,{children:["The Coordinator runs as a ",(0,i.jsx)(t.code,{children:"StatefulSet"})," with a dynamically provisioned persistent volume.\nThis volume stores the manifest history and the associated runtime policies.\nThe manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads.\nHowever, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users.\nThus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed."]}),"\n",(0,i.jsx)(t.h2,{id:"recovery",children:"Recovery"}),"\n",(0,i.jsxs)(t.p,{children:["When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests.\nIt needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures.\nThis procedure is called recovery and is initiated by the workload owner.\nThe CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the ",(0,i.jsx)(t.code,{children:"Recover"})," method.\nThe Coordinator recovers its key material and verifies the manifest history signature."]})]})}function u(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var s=r(96540);const i={},n=s.createContext(i);function o(e){const t=s.useContext(n);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a7bd4aaa.3effeeae.js b/pr-preview/pr-976/assets/js/a7bd4aaa.3effeeae.js new file mode 100644 index 0000000000..370225b599 --- /dev/null +++ b/pr-preview/pr-976/assets/js/a7bd4aaa.3effeeae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7098],{50298:(n,s,e)=>{e.r(s),e.d(s,{default:()=>d});e(96540);var r=e(63523),o=e(95947),t=e(18875),c=e(22831),i=e(28505),a=e(74848);function u(n){const{version:s}=n;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.A,{version:s.version,tag:(0,o.k)(s.pluginId,s.version)}),(0,a.jsx)(r.be,{children:s.noIndex&&(0,a.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:s,route:e}=n;return(0,a.jsx)(r.e3,{className:s.className,children:(0,a.jsx)(t.n,{version:s,children:(0,c.v)(e.routes)})})}function d(n){return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(u,{...n}),(0,a.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a86a94ce.db57590c.js b/pr-preview/pr-976/assets/js/a86a94ce.db57590c.js new file mode 100644 index 0000000000..08677a9a25 --- /dev/null +++ b/pr-preview/pr-976/assets/js/a86a94ce.db57590c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[212],{55850:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-1.1/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/about/telemetry.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/features-limitations"}}');var r=n(74848),o=n(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/a94703ab.e63edbb7.js b/pr-preview/pr-976/assets/js/a94703ab.e63edbb7.js new file mode 100644 index 0000000000..6f8fa902d3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/a94703ab.e63edbb7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9048],{40350:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(96540),o=n(34164),i=n(63523),s=n(74717),l=n(85246),r=n(5779),c=n(32032),d=n(53622),u=n(24232);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(14459),x=n(56347),f=n(49607),j=n(31436),v=n(979);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(82459),C=n(15302);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(70936),B=n(86707),y=n(57880),w=n(94753);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(77056),H=n(88584);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const K="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(K,s&&z,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(Y,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(67078),Z=n(1227);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(79825);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},79825:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(34164),o=n(32032),i=n(98445),s=n(74848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/aa0f7abf.62cf75e4.js b/pr-preview/pr-976/assets/js/aa0f7abf.62cf75e4.js new file mode 100644 index 0000000000..c696c88f78 --- /dev/null +++ b/pr-preview/pr-976/assets/js/aa0f7abf.62cf75e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8295],{67766:(e,t,r)=>{r.d(t,{A:()=>b});var n=r(96540),c=r(34164),s=r(85246),o=r(57880),i=r(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function h(){const e=d();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const c=r.select(t),s=r.pluralForms.indexOf(c);return n[Math.min(s,n.length-1)]}(r,t,e)}}var m=r(77056),p=r(32032),f=r(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=r(74848);function j(e){let{href:t,children:r}=e;return(0,g.jsx)(o.A,{href:t,className:(0,c.A)("card padding--lg",x.cardContainer),children:r})}function v(e){let{href:t,icon:r,title:n,description:s}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(f.A,{as:"h2",className:(0,c.A)("text--truncate",x.cardTitle),title:n,children:[r," ",n]}),s&&(0,g.jsx)("p",{className:(0,c.A)("text--truncate",x.cardDescription),title:s,children:s})]})}function w(e){let{item:t}=e;const r=(0,s.Nr)(t),n=function(){const{selectMessage:e}=h();return t=>e(t,(0,p.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return r?(0,g.jsx)(v,{href:r,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??n(t.items.length)}):null}function A(e){let{item:t}=e;const r=(0,m.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",n=(0,s.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:r,title:t.label,description:t.description??n?.description})}function y(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(A,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const r=(0,s.$S)();return(0,g.jsx)(b,{items:r.items,className:t})}function b(e){const{items:t,className:r}=e;if(!t)return(0,g.jsx)(N,{...e});const n=(0,s.d1)(t);return(0,g.jsx)("section",{className:(0,c.A)("row",r),children:n.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(y,{item:e})},t)))})}},40593:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"architecture/index","title":"Architecture","description":"","source":"@site/versioned_docs/version-0.7/architecture/index.md","sourceDirName":"architecture","slug":"/architecture/","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/architecture/index.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.7/components/service-mesh"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/attestation"}}');var c=r(74848),s=r(28453),o=r(67766);const i={},a="Architecture",l={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(t.header,{children:(0,c.jsx)(t.h1,{id:"architecture",children:"Architecture"})}),"\n","\n",(0,c.jsx)(o.A,{})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,c.jsx)(t,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const c={},s=n.createContext(c);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/aaec90ae.14899e6c.js b/pr-preview/pr-976/assets/js/aaec90ae.14899e6c.js new file mode 100644 index 0000000000..20489bee79 --- /dev/null +++ b/pr-preview/pr-976/assets/js/aaec90ae.14899e6c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4304],{19947:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/versioned_docs/version-1.0/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/1.0/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/features-limitations.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/observability"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/1.0/about/telemetry"}}');var r=t(74848),s=t(28453);const o={},a="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2},{value:"Automatic recovery and high availability",id:"automatic-recovery-and-high-availability",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,r.jsx)(n.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,r.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,r.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Bare-metal support"}),": Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Persistent volumes"}),": Contrast only supports volumes with ",(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode",children:(0,r.jsx)(n.code,{children:"volumeMode: Block"})}),". These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Port forwarding"}),": This feature ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,r.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,r.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,r.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,r.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,r.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,r.jsx)(n.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"automatic-recovery-and-high-availability",children:"Automatic recovery and high availability"}),"\n",(0,r.jsx)(n.p,{children:"The Contrast Coordinator is a singleton and can't be scaled to more than one instance.\nWhen this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually.\nIn a future release, we plan to support distributed Coordinator instances that can recover automatically."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/aafa6b90.3f7af2d6.js b/pr-preview/pr-976/assets/js/aafa6b90.3f7af2d6.js new file mode 100644 index 0000000000..dcef67c18d --- /dev/null +++ b/pr-preview/pr-976/assets/js/aafa6b90.3f7af2d6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6645],{55633:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-0.8/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/architecture/certificates.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/secrets"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/observability"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(720).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},720:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ab09c42c.54be6c5a.js b/pr-preview/pr-976/assets/js/ab09c42c.54be6c5a.js new file mode 100644 index 0000000000..9e3fe0c1e8 --- /dev/null +++ b/pr-preview/pr-976/assets/js/ab09c42c.54be6c5a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8683],{99437:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-0.7/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/architecture/attestation.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/certificates"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(55689).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(98568).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nOn AMD SEV-SNP the hash of the policy is then added to the attestation report via the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field by the hypervisor.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(61631).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},61631:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},98568:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},55689:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/aba21aa0.0f4e95f1.js b/pr-preview/pr-976/assets/js/aba21aa0.0f4e95f1.js new file mode 100644 index 0000000000..a33e31ad59 --- /dev/null +++ b/pr-preview/pr-976/assets/js/aba21aa0.0f4e95f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5742],{27093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/abfbdc79.2729a342.js b/pr-preview/pr-976/assets/js/abfbdc79.2729a342.js new file mode 100644 index 0000000000..0a2dd99d00 --- /dev/null +++ b/pr-preview/pr-976/assets/js/abfbdc79.2729a342.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2045],{71925:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"components/index","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-0.7/components/index.md","sourceDirName":"components","slug":"/components/","permalink":"/contrast/pr-preview/pr-976/0.7/components/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/components/index.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/0.7/deployment"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.7/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},d=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(56356).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},56356:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ac3e6feb.c8d4aa8b.js b/pr-preview/pr-976/assets/js/ac3e6feb.c8d4aa8b.js new file mode 100644 index 0000000000..58f392a376 --- /dev/null +++ b/pr-preview/pr-976/assets/js/ac3e6feb.c8d4aa8b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3074],{25315:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-0.8/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/0.8/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/about/telemetry.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Planned features and limitations","permalink":"/contrast/pr-preview/pr-976/0.8/features-limitations"}}');var r=n(74848),o=n(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},o=s.createContext(r);function i(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ae6c0c68.92c1ee41.js b/pr-preview/pr-976/assets/js/ae6c0c68.92c1ee41.js new file mode 100644 index 0000000000..b93f6630bd --- /dev/null +++ b/pr-preview/pr-976/assets/js/ae6c0c68.92c1ee41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2729],{32113:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-0.8/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/0.8/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/components/policies.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.8/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.8/components/service-mesh"}}');var s=n(74848),o=n(28453);const r={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b0cb3eb4.99a5cbf3.js b/pr-preview/pr-976/assets/js/b0cb3eb4.99a5cbf3.js new file mode 100644 index 0000000000..6b9ad2dfff --- /dev/null +++ b/pr-preview/pr-976/assets/js/b0cb3eb4.99a5cbf3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2132],{81850:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"architecture/security-considerations","title":"Security Considerations","description":"Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits).","source":"@site/docs/architecture/security-considerations.md","sourceDirName":"architecture","slug":"/architecture/security-considerations","permalink":"/contrast/pr-preview/pr-976/next/architecture/security-considerations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/architecture/security-considerations.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/next/architecture/certificates"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/next/architecture/observability"}}');var r=n(74848),s=n(28453);const o={},a="Security Considerations",c={},d=[{value:"General recommendations",id:"general-recommendations",level:2},{value:"Authentication",id:"authentication",level:3},{value:"Encryption",id:"encryption",level:3},{value:"Contrast security guarantees",id:"contrast-security-guarantees",level:2},{value:"Limitations inherent to policy checking",id:"limitations-inherent-to-policy-checking",level:3},{value:"Logs",id:"logs",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"security-considerations",children:"Security Considerations"})}),"\n",(0,r.jsxs)(t.p,{children:["Contrast ensures application integrity and provides secure means of communication and bootstrapping (see ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/basics/security-benefits",children:"security benefits"}),").\nHowever, care must be taken when interacting with the outside of Contrast's confidential environment.\nThis page presents some tips for writing secure applications and outlines the trust boundaries app developers need to know."]}),"\n",(0,r.jsx)(t.h2,{id:"general-recommendations",children:"General recommendations"}),"\n",(0,r.jsx)(t.h3,{id:"authentication",children:"Authentication"}),"\n",(0,r.jsx)(t.p,{children:"The application receives credentials from the Contrast Coordinator during initialization.\nThis allows to authenticate towards peers and to verify credentials received from peers.\nThe application should use the certificate bundle to authenticate incoming requests and be wary of unauthenticated requests or requests with a different root of trust (for example the internet PKI)."}),"\n",(0,r.jsx)(t.p,{children:"The recommendation to authenticate not only applies to network traffic, but also to volumes, GPUs and other devices.\nGenerally speaking, all information provided by the world outside the confidential VM should be treated with due scepticism, especially if it's not authenticated.\nCommon cases where Kubernetes apps interact with external services include DNS, Kubernetes API clients and cloud storage endpoints."}),"\n",(0,r.jsx)(t.h3,{id:"encryption",children:"Encryption"}),"\n",(0,r.jsx)(t.p,{children:"Any external persistence should be encrypted with an authenticated cipher.\nThis recommendation applies to block devices or filesystems mounted into the container, but also to cloud blob storage or external databases."}),"\n",(0,r.jsx)(t.h2,{id:"contrast-security-guarantees",children:"Contrast security guarantees"}),"\n",(0,r.jsx)(t.p,{children:"If an application authenticates with a certificate signed by the Contrast Mesh CA of a given manifest, Contrast provides the following guarantees:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"The container images used by the app are the images specified in the resource definitions."}),"\n",(0,r.jsx)(t.li,{children:"The command line arguments of containers are exactly the arguments specified in the resource definitions."}),"\n",(0,r.jsx)(t.li,{children:"All environment variables are either specified in resource definitions, in the container image manifest or in a settings file for the Contrast CLI."}),"\n",(0,r.jsx)(t.li,{children:"The containers run in a confidential VM that matches the reference values in the manifest."}),"\n",(0,r.jsx)(t.li,{children:"The containers' root filesystems are mounted in encrypted memory."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"limitations-inherent-to-policy-checking",children:"Limitations inherent to policy checking"}),"\n",(0,r.jsx)(t.p,{children:"Workload policies serve as workload identities.\nFrom the perspective of the Contrast Coordinator, all workloads that authenticate with the same policy are equal.\nThus, it's not possible to disambiguate, for example, pods spawned from a deployment or to limit the amount of certificates issued per policy."}),"\n",(0,r.jsxs)(t.p,{children:["Container image references from Kubernetes resource definitions are taken into account when generating the policy.\nA mutable reference may lead to policy failures or unverified image content, depending on the Contrast runtime.\nReliability and security can only be ensured with a full image reference, including digest.\nThe ",(0,r.jsxs)(t.a,{href:"https://docs.docker.com/reference/cli/docker/image/pull/#pull-an-image-by-digest-immutable-identifier",children:[(0,r.jsx)(t.code,{children:"docker pull"})," documentation"]})," explains pinned image references in detail."]}),"\n",(0,r.jsxs)(t.p,{children:["Policies can only verify what can be inferred at generation time.\nSome attributes of Kubernetes pods can't be predicted and thus can't be verified.\nParticularly the ",(0,r.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/downward-api/",children:"downward API"})," contains many fields that are dynamic or depend on the host environment, rendering it unsafe for process environment or arguments.\nThe same goes for ",(0,r.jsx)(t.code,{children:"ConfigMap"})," and ",(0,r.jsx)(t.code,{children:"Secret"})," resources, which can also be used to populate container fields.\nIf the application requires such external information, it should be injected as a mount point and carefully inspected before use."]}),"\n",(0,r.jsx)(t.p,{children:"Another type of dynamic content are persistent volumes.\nAny volumes mounted to the pod need to be scrutinized, and sensitive data must not be written to unprotected volumes.\nIdeally, a volume is mounted as a raw block device and authenticated encryption is added within the confidential container."}),"\n",(0,r.jsx)(t.h3,{id:"logs",children:"Logs"}),"\n",(0,r.jsx)(t.p,{children:"By default, container logs are visible to the host.\nSensitive information shouldn't be logged."}),"\n",(0,r.jsxs)(t.p,{children:["As of right now, hiding logs isn't natively supported.\nIf ",(0,r.jsx)(t.code,{children:"ReadStreamRequest"})," is denied in the policy, the Kata Agent stops reading the logs.\nThis causes the pipes used for standard out and standard error to fill up and potentially deadlock the container.\nIf absolutely required, standard out and standard error should be manually redirected to ",(0,r.jsx)(t.code,{children:"/dev/null"})," inside the container."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const r={},s=i.createContext(r);function o(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b20d32fc.e428ea64.js b/pr-preview/pr-976/assets/js/b20d32fc.e428ea64.js new file mode 100644 index 0000000000..c2fda67588 --- /dev/null +++ b/pr-preview/pr-976/assets/js/b20d32fc.e428ea64.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4325],{66744:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"0.7","label":"0.7","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.7","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"What is Contrast?","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/0.7/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/0.7/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/"},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/0.7/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/getting-started/"},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/0.7/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/examples/"},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/0.7/deployment","docId":"deployment","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/0.7/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/0.7/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/0.7/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/components/"},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/0.7/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/0.7/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/0.7/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/architecture/"},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/0.7/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/0.7/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.7/about/"}]},"docs":{"about/index":{"id":"about/index","title":"About","description":"","sidebar":"docs"},"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/index":{"id":"architecture/index","title":"Architecture","description":"","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/index":{"id":"components/index","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"examples/index":{"id":"examples/index","title":"Examples","description":"","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b27c3275.a5dbc455.js b/pr-preview/pr-976/assets/js/b27c3275.a5dbc455.js new file mode 100644 index 0000000000..1faac34d3e --- /dev/null +++ b/pr-preview/pr-976/assets/js/b27c3275.a5dbc455.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3690],{40497:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/docs/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/next/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/basics/confidential-containers.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"What is Contrast?","permalink":"/contrast/pr-preview/pr-976/next/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/next/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b3916dd3.30abb5e2.js b/pr-preview/pr-976/assets/js/b3916dd3.30abb5e2.js new file mode 100644 index 0000000000..315507a20c --- /dev/null +++ b/pr-preview/pr-976/assets/js/b3916dd3.30abb5e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[89],{34806:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"architecture/network-encryption/sidecar","title":"sidecar","description":"","source":"@site/versioned_docs/version-0.5/architecture/network-encryption/sidecar.md","sourceDirName":"architecture/network-encryption","slug":"/architecture/network-encryption/sidecar","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/network-encryption/sidecar.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Network Encryption","permalink":"/contrast/pr-preview/pr-976/0.5/category/network-encryption"},"next":{"title":"Protocols and Keys","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys"}}');var o=r(74848),c=r(28453);const s={},i=void 0,a={},p=[];function d(e){return(0,o.jsx)(o.Fragment,{})}function u(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d()}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>i});var n=r(96540);const o={},c=n.createContext(o);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b3a88889.ef306daa.js b/pr-preview/pr-976/assets/js/b3a88889.ef306daa.js new file mode 100644 index 0000000000..1044c903a2 --- /dev/null +++ b/pr-preview/pr-976/assets/js/b3a88889.ef306daa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9440],{37367:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"0.5","label":"0.5","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-0.5","isLast":false,"docsSidebars":{"docs":[{"type":"category","label":"What is Contrast?","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/0.5/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/"},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/0.5/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false},{"type":"link","label":"First steps","href":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps","docId":"getting-started/first-steps","unlisted":false}],"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/getting-started/"},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/examples/"},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/0.5/deployment","docId":"deployment","unlisted":false},{"type":"category","label":"Architecture","items":[{"type":"category","label":"Components","items":[{"type":"link","label":"Coordinator","href":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator","docId":"architecture/components/coordinator","unlisted":false},{"type":"link","label":"Init container","href":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container","docId":"architecture/components/init-container","unlisted":false},{"type":"link","label":"CLI","href":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli","docId":"architecture/components/cli","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/category/components"},{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers","docId":"architecture/confidential-containers","unlisted":false},{"type":"category","label":"Attestation","items":[{"type":"link","label":"Hardware","href":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware","docId":"architecture/attestation/hardware","unlisted":false},{"type":"link","label":"Pod VM","href":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm","docId":"architecture/attestation/pod-vm","unlisted":false},{"type":"link","label":"Runtime policies","href":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies","docId":"architecture/attestation/runtime-policies","unlisted":false},{"type":"link","label":"Manifest","href":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest","docId":"architecture/attestation/manifest","unlisted":false},{"type":"link","label":"Coordinator","href":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator","docId":"architecture/attestation/coordinator","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/category/attestation"},{"type":"category","label":"Certificates and Identities","items":[{"type":"link","label":"PKI","href":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki","docId":"architecture/certificates-and-identities/pki","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities"},{"type":"category","label":"Network Encryption","items":[{"type":"link","label":"Sidecar","href":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar","docId":"architecture/network-encryption/sidecar","unlisted":false},{"type":"link","label":"Protocols and Keys","href":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys","docId":"architecture/network-encryption/protocols-and-keys","unlisted":false}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/category/network-encryption"}],"collapsed":true,"collapsible":true,"href":"/contrast/pr-preview/pr-976/0.5/architecture/"}]},"docs":{"architecture/attestation/coordinator":{"id":"architecture/attestation/coordinator","title":"coordinator","description":"","sidebar":"docs"},"architecture/attestation/hardware":{"id":"architecture/attestation/hardware","title":"hardware","description":"","sidebar":"docs"},"architecture/attestation/manifest":{"id":"architecture/attestation/manifest","title":"manifest","description":"","sidebar":"docs"},"architecture/attestation/pod-vm":{"id":"architecture/attestation/pod-vm","title":"pod-vm","description":"","sidebar":"docs"},"architecture/attestation/runtime-policies":{"id":"architecture/attestation/runtime-policies","title":"runtime-policies","description":"","sidebar":"docs"},"architecture/certificates-and-identities/pki":{"id":"architecture/certificates-and-identities/pki","title":"pki","description":"","sidebar":"docs"},"architecture/components/cli":{"id":"architecture/components/cli","title":"cli","description":"","sidebar":"docs"},"architecture/components/coordinator":{"id":"architecture/components/coordinator","title":"coordinator","description":"","sidebar":"docs"},"architecture/components/init-container":{"id":"architecture/components/init-container","title":"init-container","description":"","sidebar":"docs"},"architecture/confidential-containers":{"id":"architecture/confidential-containers","title":"confidential-containers","description":"","sidebar":"docs"},"architecture/index":{"id":"architecture/index","title":"Architecture","description":"","sidebar":"docs"},"architecture/network-encryption/protocols-and-keys":{"id":"architecture/network-encryption/protocols-and-keys","title":"protocols-and-keys","description":"","sidebar":"docs"},"architecture/network-encryption/sidecar":{"id":"architecture/network-encryption/sidecar","title":"sidecar","description":"","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product Features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"security-benefits","description":"","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"examples/index":{"id":"examples/index","title":"Examples","description":"","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/first-steps":{"id":"getting-started/first-steps","title":"first-steps","description":"","sidebar":"docs"},"getting-started/index":{"id":"getting-started/index","title":"Getting started","description":"","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the bundle from the URL you received:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/b451d7c3.99a4d0de.js b/pr-preview/pr-976/assets/js/b451d7c3.99a4d0de.js new file mode 100644 index 0000000000..c5ec8f08e8 --- /dev/null +++ b/pr-preview/pr-976/assets/js/b451d7c3.99a4d0de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[234],{90961:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/bare-metal","title":"Prepare a bare-metal instance","description":"Hardware and firmware setup","source":"@site/versioned_docs/version-1.1/getting-started/bare-metal.md","sourceDirName":"getting-started","slug":"/getting-started/bare-metal","permalink":"/contrast/pr-preview/pr-976/getting-started/bare-metal","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/getting-started/bare-metal.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/getting-started/cluster-setup"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/examples/emojivoto"}}');var r=n(74848),a=n(28453);const i={},o="Prepare a bare-metal instance",l={},c=[{value:"Hardware and firmware setup",id:"hardware-and-firmware-setup",level:2},{value:"Kernel Setup",id:"kernel-setup",level:2},{value:"K3s Setup",id:"k3s-setup",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,a.R)(),...e.components},{TabItem:n,Tabs:s}=t;return n||u("TabItem",!0),s||u("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"prepare-a-bare-metal-instance",children:"Prepare a bare-metal instance"})}),"\n",(0,r.jsx)(t.h2,{id:"hardware-and-firmware-setup",children:"Hardware and firmware setup"}),"\n",(0,r.jsxs)(s,{queryString:"vendor",children:[(0,r.jsxs)(n,{value:"amd",label:"AMD SEV-SNP",children:[(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Update your BIOS to a version that supports AMD SEV-SNP. Updating to the latest available version is recommended as newer versions will likely contain security patches for AMD SEV-SNP."}),"\n",(0,r.jsx)(t.li,{children:"Enter BIOS setup to enable SMEE, IOMMU, RMP coverage, and SEV-SNP. Set the SEV-ES ASID Space Limit to a non-zero number (higher is better)."}),"\n",(0,r.jsxs)(t.li,{children:["Download the latest firmware version for your processor from ",(0,r.jsx)(t.a,{href:"https://www.amd.com/de/developer/sev.html",children:"AMD"}),", unpack it, and place it in ",(0,r.jsx)(t.code,{children:"/lib/firmware/amd"}),"."]}),"\n"]}),(0,r.jsxs)(t.p,{children:["Consult AMD's ",(0,r.jsx)(t.a,{href:"https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/tuning-guides/58207-using-sev-with-amd-epyc-processors.pdf",children:"Using SEV with AMD EPYC Processors user guide"})," for more information."]})]}),(0,r.jsx)(n,{value:"intel",label:"Intel TDX",children:(0,r.jsxs)(t.p,{children:["Follow Canonical's instructions on ",(0,r.jsx)(t.a,{href:"https://github.com/canonical/tdx?tab=readme-ov-file#43-enable-intel-tdx-in-the-hosts-bios",children:"setting up Intel TDX in the host's BIOS"}),"."]})})]}),"\n",(0,r.jsx)(t.h2,{id:"kernel-setup",children:"Kernel Setup"}),"\n",(0,r.jsxs)(s,{queryString:"vendor",children:[(0,r.jsx)(n,{value:"amd",label:"AMD SEV-SNP",children:(0,r.jsx)(t.p,{children:"Install a kernel with version 6.11 or greater. If you're following this guide before 6.11 has been released, use 6.11-rc3. Don't use 6.11-rc4 - 6.11-rc6 as they contain a regression. 6.11-rc7+ might work."})}),(0,r.jsx)(n,{value:"intel",label:"Intel TDX",children:(0,r.jsxs)(t.p,{children:["Follow Canonical's instructions on ",(0,r.jsx)(t.a,{href:"https://github.com/canonical/tdx?tab=readme-ov-file#41-install-ubuntu-2404-server-image",children:"setting up Intel TDX on Ubuntu 24.04"}),". Note that Contrast currently only supports Intel TDX with Ubuntu 24.04."]})})]}),"\n",(0,r.jsxs)(t.p,{children:["Increase the ",(0,r.jsx)(t.code,{children:"user.max_inotify_instances"})," sysctl limit by adding ",(0,r.jsx)(t.code,{children:"user.max_inotify_instances=8192"})," to ",(0,r.jsx)(t.code,{children:"/etc/sysctl.d/99-sysctl.conf"})," and running ",(0,r.jsx)(t.code,{children:"sysctl --system"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"k3s-setup",children:"K3s Setup"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["Follow the ",(0,r.jsx)(t.a,{href:"https://docs.k3s.io/",children:"K3s setup instructions"})," to create a cluster."]}),"\n",(0,r.jsxs)(t.li,{children:["Install a block storage provider such as ",(0,r.jsx)(t.a,{href:"https://docs.k3s.io/storage#setting-up-longhorn",children:"Longhorn"})," and mark it as the default storage class."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var s=n(96540);const r={},a=s.createContext(r);function i(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ba2406d8.4e6c54c4.js b/pr-preview/pr-976/assets/js/ba2406d8.4e6c54c4.js new file mode 100644 index 0000000000..8a41da300e --- /dev/null +++ b/pr-preview/pr-976/assets/js/ba2406d8.4e6c54c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2476],{56218:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-0.8/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/getting-started/cluster-setup.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.8/getting-started/install"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.8/examples/emojivoto"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which needs\nto have the permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a\nnon-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool."}),"\n",(0,t.jsx)(n.p,{children:"We'll first start by creating the non-CoCo cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "${azResourceGroup:?}" \\\n --name nodepool2 \\\n --cluster-name "${azClusterName:?}" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Optionally, we can now remove the non-CoCo node pool:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool delete \\\n --resource-group "${azResourceGroup:?}" \\\n --cluster-name "${azClusterName:?}" \\\n --name nodepool1\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/baef5027.95910e40.js b/pr-preview/pr-976/assets/js/baef5027.95910e40.js new file mode 100644 index 0000000000..822b69bcb6 --- /dev/null +++ b/pr-preview/pr-976/assets/js/baef5027.95910e40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9103],{67766:(e,t,n)=>{n.d(t,{A:()=>k});var r=n(96540),s=n(34164),o=n(85246),i=n(57880),c=n(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const g={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(74848);function j(e){let{href:t,children:n}=e;return(0,x.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",g.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,x.jsxs)(j,{href:t,children:[(0,x.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",g.cardTitle),title:r,children:[n," ",r]}),o&&(0,x.jsx)("p",{className:(0,s.A)("text--truncate",g.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,x.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function b(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(y,{item:t});case"category":return(0,x.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,x.jsx)(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,x.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(b,{item:e})},t)))})}},51760:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"getting-started/index","title":"Getting started","description":"","source":"@site/versioned_docs/version-0.5/getting-started/index.md","sourceDirName":"getting-started","slug":"/getting-started/","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/getting-started/index.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.5/basics/features"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.5/getting-started/install"}}');var s=n(74848),o=n(28453),i=n(67766);const c={},a="Getting started",l={},d=[];function u(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started",children:"Getting started"})}),"\n","\n",(0,s.jsx)(i.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/bced0f3c.110450d8.js b/pr-preview/pr-976/assets/js/bced0f3c.110450d8.js new file mode 100644 index 0000000000..bc75b95e7d --- /dev/null +++ b/pr-preview/pr-976/assets/js/bced0f3c.110450d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8001],{33221:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>s,metadata:()=>i,toc:()=>d});const i=JSON.parse('{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","source":"@site/versioned_docs/version-0.7/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/0.7/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/basics/security-benefits.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.7/basics/features"}}');var r=n(74848),a=n(28453);const s={},o="Contrast security overview",c={},d=[{value:"Confidential computing foundation",id:"confidential-computing-foundation",level:2},{value:"Components of a Contrast deployment",id:"components-of-a-contrast-deployment",level:2},{value:"Personas in a Contrast deployment",id:"personas-in-a-contrast-deployment",level:2},{value:"Threat model and mitigations",id:"threat-model-and-mitigations",level:2},{value:"Possible attacks",id:"possible-attacks",level:3},{value:"Attack surfaces",id:"attack-surfaces",level:3},{value:"Threats and mitigations",id:"threats-and-mitigations",level:3},{value:"Attacks on the confidential container environment",id:"attacks-on-the-confidential-container-environment",level:4},{value:"Attacks on the Coordinator attestation service",id:"attacks-on-the-coordinator-attestation-service",level:4},{value:"Attacks on workloads",id:"attacks-on-workloads",level:4},{value:"Examples of Contrast's threat model in practice",id:"examples-of-contrasts-threat-model-in-practice",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast-security-overview",children:"Contrast security overview"})}),"\n",(0,r.jsx)(t.p,{children:"This document outlines the security measures of Contrast and its capability to counter various threats.\nContrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership."}),"\n",(0,r.jsx)(t.p,{children:"Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging.\nThis is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance.\nIt allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider."}),"\n",(0,r.jsx)(t.h2,{id:"confidential-computing-foundation",children:"Confidential computing foundation"}),"\n",(0,r.jsx)(t.p,{children:"Leveraging Confidential Computing technology, Contrast provides three defining security properties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Encryption of data in use"}),": Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Workload isolation"}),": Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime.\nThe workload isolation and remote attestation involves two phases:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation."}),"\n",(0,r.jsx)(t.li,{children:"A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["For more details on confidential computing see our ",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"}),".\nThe ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation architecture"})," describes Contrast's attestation process and the resulting chain of trust in detail."]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-a-contrast-deployment",children:"Components of a Contrast deployment"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses the Kubernetes runtime of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",children:"Confidential Containers"})," project.\nConfidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment.\nThe TCB is the totality of elements in a computing environment that must be trusted not to be compromised.\nA smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the ",(0,r.jsx)(t.em,{children:"cloud & datacenter infrastructure"})," and the ",(0,r.jsx)(t.em,{children:"physical hosts"}),", including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red).\nIn the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB.\nTheir integrity is ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"verifiable through remote attestation"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Contrast uses ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",children:"hardware-based mechanisms"}),", specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload.\nThis implies that both the CPU and its microcode are integral components of the TCB.\nHowever, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"TCB comparison",src:n(80455).A+"",width:"4052",height:"1380"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast adds the following components to a deployment that become part of the TCB.\nThe components that are part of the TCB are:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The workload containers"}),": Container images that run the actual application."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"The runtime environment"})}),": The confidential micro-VM that acts as the container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"The sidecar containers"})}),": Containers that provide additional functionality such as ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-initializer",children:"initialization"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/policies",children:"The runtime policies"})}),": Policies that enforce the runtime environments for the workload containers during their lifetime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-manifest",children:"The manifest"})}),": A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-coordinator",children:"The Coordinator"})}),": An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"personas-in-a-contrast-deployment",children:"Personas in a Contrast deployment"}),"\n",(0,r.jsx)(t.p,{children:"In a Contrast deployment, there are three parties:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The container image provider"}),", who creates the container images that represent the application that has access to the protected data."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The workload operator"}),", who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"The data owner"}),", who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties."}),"\n",(0,r.jsx)(t.p,{children:"The following diagram shows the system components and parties."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Components and parties",src:n(78807).A+"",width:"3588",height:"2017"})}),"\n",(0,r.jsx)(t.h2,{id:"threat-model-and-mitigations",children:"Threat model and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"This section describes the threat vectors that Contrast helps to mitigate."}),"\n",(0,r.jsx)(t.p,{children:"The following attacks are out of scope for this document:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the application code itself, such as insufficient access controls."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the Confidential Computing hardware directly, such as side-channel attacks."}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the availability, such as denial-of-service (DOS) attacks."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"possible-attacks",children:"Possible attacks"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to defend against five possible attacks:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud insider"}),": malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious cloud co-tenant"}),': malicious cloud user ("hackers") may break out of their tenancy and access other tenants\' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the ',(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, without the physical access."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious workload operator"}),": malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the ",(0,r.jsx)(t.em,{children:"cloud insider access"})," scenario, with access to everything that's above the hypervisor level."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious attestation client"}),": this attacker connects to the attestation service and sends malformed request."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"A malicious container image provider"}),": a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"attack-surfaces",children:"Attack surfaces"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes the attack surfaces that are available to attackers."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Attacker"}),(0,r.jsx)(t.th,{children:"Target"}),(0,r.jsx)(t.th,{children:"Attack surface"}),(0,r.jsx)(t.th,{children:"Risks"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Physical memory"}),(0,r.jsx)(t.td,{children:"Attacker can dump the physical memory of the workloads."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk reads"}),(0,r.jsx)(t.td,{children:"Anything read from the disk is within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Disk writes"}),(0,r.jsx)(t.td,{children:"Anything written to disk is visible to an attacker."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Kubernetes Control Plane"}),(0,r.jsx)(t.td,{children:"Instance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Container Runtime"}),(0,r.jsx)(t.td,{children:'The attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.'})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Cloud insider, cloud hacker, workload operator"}),(0,r.jsx)(t.td,{children:"Confidential Container, Workload"}),(0,r.jsx)(t.td,{children:"Network"}),(0,r.jsx)(t.td,{children:"Intra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Attestation client"}),(0,r.jsx)(t.td,{children:"Coordinator attestation service"}),(0,r.jsx)(t.td,{children:"Attestation requests"}),(0,r.jsx)(t.td,{children:"The attestation service has complex, crypto-heavy logic that's challenging to write defensively."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Container image provider"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"Workload"}),(0,r.jsx)(t.td,{children:"This attacker might release an upgrade to the workload containing harmful changes, such as a backdoor."})]})]})]}),"\n",(0,r.jsx)(t.h3,{id:"threats-and-mitigations",children:"Threats and mitigations"}),"\n",(0,r.jsx)(t.p,{children:"Contrast shields a workload from the aforementioned threats with three main components:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"runtime environment"})," safeguards against the physical memory and disk attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/policies",children:"runtime policies"})," safeguard against the Kubernetes control plane and container runtime attack surface."]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh"})," safeguards against the network attack surface."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on the attestation service"}),"\n",(0,r.jsx)(t.li,{children:"Attacks on workloads"}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-confidential-container-environment",children:"Attacks on the confidential container environment"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to the confidential container environment."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection of the launcher or image repository."}),(0,r.jsx)(t.td,{children:"An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies the workload image on disk after it was downloaded and measured."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker modifies a container's runtime environment configuration in the Kubernetes control plane."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/policies",children:"runtime policies"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-the-coordinator-attestation-service",children:"Attacks on the Coordinator attestation service"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies to the attestation service."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol."}),(0,r.jsx)(t.td,{children:"Within the network between your workload and the Coordinator."})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process."}),(0,r.jsx)(t.td,{children:"This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-coordinator",children:"Coordinator"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack."}),(0,r.jsx)(t.td,{children:"In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/#the-coordinator",children:"Coordinator"})]})]})]})]}),"\n",(0,r.jsx)(t.h4,{id:"attacks-on-workloads",children:"Attacks on workloads"}),"\n",(0,r.jsx)(t.p,{children:"This table describes potential threats and mitigation strategies related to workloads."}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Threat"}),(0,r.jsx)(t.th,{children:"Mitigation"}),(0,r.jsx)(t.th,{children:"Mitigation implementation"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker intercepts the network connection between two workload containers."}),(0,r.jsx)(t.td,{children:"This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker reads or modifies data written to disk via persistent volumes."}),(0,r.jsx)(t.td,{children:"Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts."}),(0,r.jsxs)(t.td,{children:["Within the Contrast ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:"runtime environment"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"An attacker publishes a new image version containing malicious code."}),(0,r.jsx)(t.td,{children:"The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged."}),(0,r.jsxs)(t.td,{children:["Within the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation"})]})]})]})]}),"\n",(0,r.jsx)(t.h2,{id:"examples-of-contrasts-threat-model-in-practice",children:"Examples of Contrast's threat model in practice"}),"\n",(0,r.jsx)(t.p,{children:"The following table describes three example use cases and how they map to the defined threat model in this document:"}),"\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Use Case"}),(0,r.jsx)(t.th,{children:"Example Scenario"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Migrate sensitive workloads to the cloud"}),(0,r.jsxs)(t.td,{children:["TechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"attestation terminology"}),", they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Make your SaaS more trustworthy"}),(0,r.jsxs)(t.td,{children:["SaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",children:"relying party"})," is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator."]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:"Simplify regulatory compliance"}),(0,r.jsx)(t.td,{children:"HealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator."})]})]})]}),"\n",(0,r.jsx)(t.p,{children:"In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data."})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},78807:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/personas-0d51d0cc03b37c9f45b914bbea163646.svg"},80455:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/tcb-eebc94816125417eaf55b0e5e96bba37.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var i=n(96540);const r={},a=i.createContext(r);function s(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/bd029836.96853ab4.js b/pr-preview/pr-976/assets/js/bd029836.96853ab4.js new file mode 100644 index 0000000000..af6ae9b4fa --- /dev/null +++ b/pr-preview/pr-976/assets/js/bd029836.96853ab4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1047],{74283:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-1.0/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/1.0/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/components/policies.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/1.0/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/1.0/components/service-mesh"}}');var s=n(74848),o=n(28453);const r={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/bd625abb.43f2f678.js b/pr-preview/pr-976/assets/js/bd625abb.43f2f678.js new file mode 100644 index 0000000000..bdaddfabae --- /dev/null +++ b/pr-preview/pr-976/assets/js/bd625abb.43f2f678.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4415],{89939:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-1.0/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/architecture/attestation.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/1.0/components/service-mesh"},"next":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/secrets"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(84191).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(36546).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nOn AMD SEV-SNP the hash of the policy is then added to the attestation report via the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field by the hypervisor.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(95449).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/components/overview#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/1.0/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},95449:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},36546:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},84191:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/bde25e2b.2917f0f7.js b/pr-preview/pr-976/assets/js/bde25e2b.2917f0f7.js new file mode 100644 index 0000000000..9829af1f36 --- /dev/null +++ b/pr-preview/pr-976/assets/js/bde25e2b.2917f0f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5878],{51556:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"docs":[{"type":"link","label":"What is Contrast?","href":"/contrast/pr-preview/pr-976/next/","docId":"intro","unlisted":false},{"type":"category","label":"Basics","collapsed":false,"items":[{"type":"link","label":"Confidential Containers","href":"/contrast/pr-preview/pr-976/next/basics/confidential-containers","docId":"basics/confidential-containers","unlisted":false},{"type":"link","label":"Security benefits","href":"/contrast/pr-preview/pr-976/next/basics/security-benefits","docId":"basics/security-benefits","unlisted":false},{"type":"link","label":"Features","href":"/contrast/pr-preview/pr-976/next/basics/features","docId":"basics/features","unlisted":false}],"collapsible":true},{"type":"category","label":"Getting started","collapsed":false,"items":[{"type":"link","label":"Install","href":"/contrast/pr-preview/pr-976/next/getting-started/install","docId":"getting-started/install","unlisted":false},{"type":"link","label":"Cluster setup","href":"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup","docId":"getting-started/cluster-setup","unlisted":false},{"type":"link","label":"Bare metal setup","href":"/contrast/pr-preview/pr-976/next/getting-started/bare-metal","docId":"getting-started/bare-metal","unlisted":false}],"collapsible":true},{"type":"category","label":"Examples","items":[{"type":"link","label":"Confidential emoji voting","href":"/contrast/pr-preview/pr-976/next/examples/emojivoto","docId":"examples/emojivoto","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Workload deployment","href":"/contrast/pr-preview/pr-976/next/deployment","docId":"deployment","unlisted":false},{"type":"link","label":"Troubleshooting","href":"/contrast/pr-preview/pr-976/next/troubleshooting","docId":"troubleshooting","unlisted":false},{"type":"category","label":"Components","items":[{"type":"link","label":"Overview","href":"/contrast/pr-preview/pr-976/next/components/overview","docId":"components/overview","unlisted":false},{"type":"link","label":"Runtime","href":"/contrast/pr-preview/pr-976/next/components/runtime","docId":"components/runtime","unlisted":false},{"type":"link","label":"Policies","href":"/contrast/pr-preview/pr-976/next/components/policies","docId":"components/policies","unlisted":false},{"type":"link","label":"Service mesh","href":"/contrast/pr-preview/pr-976/next/components/service-mesh","docId":"components/service-mesh","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"category","label":"Architecture","items":[{"type":"link","label":"Attestation","href":"/contrast/pr-preview/pr-976/next/architecture/attestation","docId":"architecture/attestation","unlisted":false},{"type":"link","label":"Secrets & recovery","href":"/contrast/pr-preview/pr-976/next/architecture/secrets","docId":"architecture/secrets","unlisted":false},{"type":"link","label":"Certificate authority","href":"/contrast/pr-preview/pr-976/next/architecture/certificates","docId":"architecture/certificates","unlisted":false},{"type":"link","label":"Security considerations","href":"/contrast/pr-preview/pr-976/next/architecture/security-considerations","docId":"architecture/security-considerations","unlisted":false},{"type":"link","label":"Observability","href":"/contrast/pr-preview/pr-976/next/architecture/observability","docId":"architecture/observability","unlisted":false}],"collapsed":true,"collapsible":true},{"type":"link","label":"Planned features and limitations","href":"/contrast/pr-preview/pr-976/next/features-limitations","docId":"features-limitations","unlisted":false},{"type":"category","label":"About","items":[{"type":"link","label":"Telemetry","href":"/contrast/pr-preview/pr-976/next/about/telemetry","docId":"about/telemetry","unlisted":false}],"collapsed":true,"collapsible":true}]},"docs":{"about/telemetry":{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","sidebar":"docs"},"architecture/attestation":{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","sidebar":"docs"},"architecture/certificates":{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","sidebar":"docs"},"architecture/observability":{"id":"architecture/observability","title":"Observability","description":"The Contrast Coordinator can expose metrics in the","sidebar":"docs"},"architecture/secrets":{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","sidebar":"docs"},"architecture/security-considerations":{"id":"architecture/security-considerations","title":"Security Considerations","description":"Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits).","sidebar":"docs"},"basics/confidential-containers":{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","sidebar":"docs"},"basics/features":{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","sidebar":"docs"},"basics/security-benefits":{"id":"basics/security-benefits","title":"Contrast security overview","description":"This document outlines the security measures of Contrast and its capability to counter various threats.","sidebar":"docs"},"components/overview":{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","sidebar":"docs"},"components/policies":{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","sidebar":"docs"},"components/runtime":{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","sidebar":"docs"},"components/service-mesh":{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","sidebar":"docs"},"deployment":{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","sidebar":"docs"},"examples/emojivoto":{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","sidebar":"docs"},"features-limitations":{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","sidebar":"docs"},"getting-started/bare-metal":{"id":"getting-started/bare-metal","title":"Prepare a bare-metal instance","description":"Hardware and firmware setup","sidebar":"docs"},"getting-started/cluster-setup":{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","sidebar":"docs"},"getting-started/install":{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","sidebar":"docs"},"intro":{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","sidebar":"docs"},"troubleshooting":{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/bf823012.0ed024b4.js b/pr-preview/pr-976/assets/js/bf823012.0ed024b4.js new file mode 100644 index 0000000000..662141e1bb --- /dev/null +++ b/pr-preview/pr-976/assets/js/bf823012.0ed024b4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5225],{32615:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-0.7/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/getting-started/install.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup"}}');var r=n(74848),a=n(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.7.3/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,n)=>{n.d(e,{R:()=>o,x:()=>i});var s=n(96540);const r={},a=s.createContext(r);function o(t){const e=s.useContext(a);return s.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),s.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c09e49b9.9ff206ce.js b/pr-preview/pr-976/assets/js/c09e49b9.9ff206ce.js new file mode 100644 index 0000000000..9fe9072749 --- /dev/null +++ b/pr-preview/pr-976/assets/js/c09e49b9.9ff206ce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[390],{82693:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-0.6/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/architecture/certificates.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/attestation"},"next":{"title":"Known limitations","permalink":"/contrast/pr-preview/pr-976/0.6/known-limitations"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(59862).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},59862:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c1fac065.af80720c.js b/pr-preview/pr-976/assets/js/c1fac065.af80720c.js new file mode 100644 index 0000000000..eb6afb1278 --- /dev/null +++ b/pr-preview/pr-976/assets/js/c1fac065.af80720c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4206],{67766:(e,t,n)=>{n.d(t,{A:()=>k});var r=n(96540),s=n(34164),o=n(85246),i=n(57880),c=n(25792);const a=["zero","one","two","few","many","other"];function l(e){return a.filter((t=>e.includes(t)))}const d={locale:"en",pluralForms:l(["one","other"]),select:e=>1===e?"one":"other"};function u(){const{i18n:{currentLocale:e}}=(0,c.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:l(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),d}}),[e])}function m(){const e=u();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const g={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var x=n(74848);function j(e){let{href:t,children:n}=e;return(0,x.jsx)(i.A,{href:t,className:(0,s.A)("card padding--lg",g.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,x.jsxs)(j,{href:t,children:[(0,x.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",g.cardTitle),title:r,children:[n," ",r]}),o&&(0,x.jsx)("p",{className:(0,s.A)("text--truncate",g.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,x.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,x.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function b(e){let{item:t}=e;switch(t.type){case"link":return(0,x.jsx)(y,{item:t});case"category":return(0,x.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,x.jsx)(k,{items:n.items,className:t})}function k(e){const{items:t,className:n}=e;if(!t)return(0,x.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,x.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,x.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,x.jsx)(b,{item:e})},t)))})}},69006:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>r,toc:()=>d});const r=JSON.parse('{"id":"getting-started/index","title":"Getting started","description":"","source":"@site/versioned_docs/version-0.6/getting-started/index.md","sourceDirName":"getting-started","slug":"/getting-started/","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/getting-started/index.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.6/basics/features"},"next":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/install"}}');var s=n(74848),o=n(28453),i=n(67766);const c={},a="Getting started",l={},d=[];function u(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started",children:"Getting started"})}),"\n","\n",(0,s.jsx)(i.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const s={},o=r.createContext(s);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c2ce05d5.83575dcd.js b/pr-preview/pr-976/assets/js/c2ce05d5.83575dcd.js new file mode 100644 index 0000000000..7bed9edc00 --- /dev/null +++ b/pr-preview/pr-976/assets/js/c2ce05d5.83575dcd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8024],{94003:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","source":"@site/versioned_docs/version-1.0/troubleshooting.md","sourceDirName":".","slug":"/troubleshooting","permalink":"/contrast/pr-preview/pr-976/1.0/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/troubleshooting.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/1.0/deployment"},"next":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/1.0/components/overview"}}');var i=t(74848),s=t(28453);const a={},r="Troubleshooting",c={},l=[{value:"Logging",id:"logging",level:2},{value:"CLI",id:"cli",level:3},{value:"Coordinator and Initializer",id:"coordinator-and-initializer",level:3},{value:"Pod fails to start",id:"pod-fails-to-start",level:2},{value:"Regenerating the policies",id:"regenerating-the-policies",level:3},{value:"Pin container images",id:"pin-container-images",level:3},{value:"Validate Contrast components match",id:"validate-contrast-components-match",level:3}];function d(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section contains information on how to debug your Contrast deployment."}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"Collecting logs can be a good first step to identify problems in your\ndeployment. Both the CLI and the Contrast Coordinator as well as the Initializer\ncan be configured to emit additional logs."}),"\n",(0,i.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.p,{children:["The CLI logs can be configured with the ",(0,i.jsx)(n.code,{children:"--log-level"})," command-line flag, which\ncan be set to either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"})," or ",(0,i.jsx)(n.code,{children:"error"}),". The default is ",(0,i.jsx)(n.code,{children:"info"}),".\nSetting this to ",(0,i.jsx)(n.code,{children:"debug"})," can get more fine-grained information as to where the\nproblem lies."]}),"\n",(0,i.jsx)(n.h3,{id:"coordinator-and-initializer",children:"Coordinator and Initializer"}),"\n",(0,i.jsxs)(n.p,{children:["The logs from the Coordinator and the Initializer can be configured via the\nenvironment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"}),", ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," and\n",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"})," can be set to one of either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"}),", or\n",(0,i.jsx)(n.code,{children:"error"}),", similar to the CLI (defaults to ",(0,i.jsx)(n.code,{children:"info"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," can be set to ",(0,i.jsx)(n.code,{children:"text"})," or ",(0,i.jsx)(n.code,{children:"json"}),", determining the output\nformat (defaults to ",(0,i.jsx)(n.code,{children:"text"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," is a comma-seperated list of subsystems that should\nbe enabled for logging, which are disabled by default. Subsystems include:\n",(0,i.jsx)(n.code,{children:"kds-getter"}),", ",(0,i.jsx)(n.code,{children:"issuer"})," and ",(0,i.jsx)(n.code,{children:"validator"}),".\nTo enable all subsystems, use ",(0,i.jsx)(n.code,{children:"*"})," as the value for this environment variable.\nWarnings and error messages from subsystems get printed regardless of whether\nthe subsystem is listed in the ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," environment variable."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"To configure debug logging with all subsystems for your Coordinator, add the\nfollowing variables to your container definition."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n containers:\n image: "ghcr.io/edgelesssys/contrast/coordinator:v1.0.0@sha256:36766ae51dbafa4ef5e90c3e24698bdfbb3b4d765e13c14bdee190a1a7638c35"\n name: coordinator\n env:\n - name: CONTRAST_LOG_LEVEL\n value: debug\n - name: CONTRAST_LOG_SUBSYSTEMS\n value: "*"\n # ...\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["While the Contrast Coordinator has a policy that allows certain configurations,\nthe Initializer and service mesh don't. When changing environment variables of other\nparts than the Coordinator, ensure to rerun ",(0,i.jsx)(n.code,{children:"contrast generate"})," to update the policy."]})}),"\n",(0,i.jsxs)(n.p,{children:["To access the logs generated by the Coordinator, you can use ",(0,i.jsx)(n.code,{children:"kubectl"})," with the\nfollowing command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl logs <coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"pod-fails-to-start",children:"Pod fails to start"}),"\n",(0,i.jsxs)(n.p,{children:["If the Coordinator or a workload pod fails to even start, it can be helpful to\nlook at the events of the pod during the startup process using the ",(0,i.jsx)(n.code,{children:"describe"}),"\ncommand."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> events --for pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'LAST SEEN TYPE REASON OBJECT MESSAGE\n32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"A common error, as in this example, is that the container creation was blocked by the\npolicy. Potential reasons are a modification of the deployment YAML without updating\nthe policies afterward, or a version mismatch between Contrast components."}),"\n",(0,i.jsx)(n.h3,{id:"regenerating-the-policies",children:"Regenerating the policies"}),"\n",(0,i.jsx)(n.p,{children:"To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated\npolicies, rerun"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast generate\n"})}),"\n",(0,i.jsx)(n.p,{children:"on your deployment. If any of the policy annotations change, re-deploy with the updated policies."}),"\n",(0,i.jsx)(n.h3,{id:"pin-container-images",children:"Pin container images"}),"\n",(0,i.jsx)(n.p,{children:"When generating the policies, Contrast will download the images specified in your deployment\nYAML and include their cryptographic identity. If the image tag is moved to another\ncontainer image after the policy has been generated, the image downloaded at deploy time\nwill differ from the one at generation time, and the policy enforcement won't allow the\ncontainer to be started in the pod VM."}),"\n",(0,i.jsxs)(n.p,{children:["To ensure the correct image is always used, pin the container image to a fixed ",(0,i.jsx)(n.code,{children:"sha256"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This way, the same image will still be pulled when the container tag (",(0,i.jsx)(n.code,{children:"22.04"}),") is moved\nto another image."]}),"\n",(0,i.jsx)(n.h3,{id:"validate-contrast-components-match",children:"Validate Contrast components match"}),"\n",(0,i.jsx)(n.p,{children:"A version mismatch between Contrast components can cause policy validation or attestation\nto fail. Each Contrast runtime is identifiable based on its (shortened) measurement value\nused to name the runtime class version."}),"\n",(0,i.jsx)(n.p,{children:"First, analyze which runtime class is currently installed in your cluster by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl get runtimeclasses\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give you output similar to the following one."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"NAME HANDLER AGE\ncontrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h\nkata-cc-isolation kata-cc 45d\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided\nby the AKS CoCo preview, which isn't used by Contrast)."}),"\n",(0,i.jsx)(n.p,{children:"Next, check if the pod that won't start has the correct runtime class configured, and the\nCoordinator uses the exact same runtime:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>\nkubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output should list the runtime class the pod is using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast-cc-aks-clh-snp-7173acb5\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Version information about the currently used CLI can be obtained via the ",(0,i.jsx)(n.code,{children:"version"})," flag:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast --version\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast version v0.X.0\n\n runtime handler: contrast-cc-aks-clh-snp-7173acb5\n launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35\n genpolicy version: 3.2.0.azl1.genpolicy0\n image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...\n ghcr.io/edgelesssys/contrast/initializer@sha256:...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c3a9f66a.6efdd9fb.js b/pr-preview/pr-976/assets/js/c3a9f66a.6efdd9fb.js new file mode 100644 index 0000000000..3028873530 --- /dev/null +++ b/pr-preview/pr-976/assets/js/c3a9f66a.6efdd9fb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[7832],{8032:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/versioned_docs/version-0.9/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/0.9/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/components/service-mesh.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/0.9/components/policies"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/attestation"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"CONTRAST_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"CONTRAST_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"<name>#<port>#false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:"<name>"})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"<name>#<port>#true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: CONTRAST_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v0.9.0@sha256:d97397770b8ea13082eab96099629f971688508e5b0cc1596df07aa5510d5972"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-tls-certs\n mountPath: /tls-config\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"<name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port>"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:"<name>"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.9/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c4b4ced0.cc4aaa5d.js b/pr-preview/pr-976/assets/js/c4b4ced0.cc4aaa5d.js new file mode 100644 index 0000000000..ee832172fc --- /dev/null +++ b/pr-preview/pr-976/assets/js/c4b4ced0.cc4aaa5d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2564],{58505:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"components/runtime","title":"Contrast Runtime","description":"The Contrast runtime is responsible for starting pods as confidential virtual machines.","source":"@site/docs/components/runtime.md","sourceDirName":"components","slug":"/components/runtime","permalink":"/contrast/pr-preview/pr-976/next/components/runtime","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/components/runtime.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/next/components/overview"},"next":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/next/components/policies"}}');var i=t(74848),r=t(28453);const a={},o="Contrast Runtime",d={},c=[{value:"Node-level components",id:"node-level-components",level:2},{value:"Containerd shim",id:"containerd-shim",level:3},{value:"Virtual machine manager (VMM)",id:"virtual-machine-manager-vmm",level:3},{value:"Snapshotters",id:"snapshotters",level:3},{value:"Pod-VM image",id:"pod-vm-image",level:3},{value:"Node installer DaemonSet",id:"node-installer-daemonset",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"contrast-runtime",children:"Contrast Runtime"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast runtime is responsible for starting pods as confidential virtual machines.\nThis works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver.\nThe ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource defines a name for referencing the class and\na handler used by the container runtime (",(0,i.jsx)(n.code,{children:"containerd"}),") to identify the class."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: node.k8s.io/v1\nkind: RuntimeClass\nmetadata:\n # This name is used by pods in the runtimeClassName field\n name: contrast-cc-abcdef\n# This name is used by the\n# container runtime interface implementation (containerd)\nhandler: contrast-cc-abcdef\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Confidential pods that are part of a Contrast deployment need to specify the\nsame runtime class in the ",(0,i.jsx)(n.code,{children:"runtimeClassName"})," field, so Kubernetes uses the\nContrast runtime instead of the default ",(0,i.jsx)(n.code,{children:"containerd"})," / ",(0,i.jsx)(n.code,{children:"runc"})," handler."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"apiVersion: v1\nkind: Pod\nspec:\n runtimeClassName: contrast-cc-abcdef\n # ...\n"})}),"\n",(0,i.jsx)(n.h2,{id:"node-level-components",children:"Node-level components"}),"\n",(0,i.jsxs)(n.p,{children:["The runtime consists of additional software components that need to be installed\nand configured on every SEV-SNP-enabled/TDX-enabled worker node.\nThis installation is performed automatically by the ",(0,i.jsxs)(n.a,{href:"#node-installer-daemonset",children:[(0,i.jsx)(n.code,{children:"node-installer"})," DaemonSet"]}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Runtime components",src:t(30487).A+"",width:"3814",height:"1669"})}),"\n",(0,i.jsx)(n.h3,{id:"containerd-shim",children:"Containerd shim"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"handler"})," field in the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," instructs containerd not to use the default ",(0,i.jsx)(n.code,{children:"runc"})," implementation.\nInstead, containerd invokes a custom plugin called ",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),".\nThis shim is described in more detail in the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/tree/3.4.0/src/runtime",children:"upstream source repository"})," and in the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md",children:"containerd documentation"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"virtual-machine-manager-vmm",children:"Virtual machine manager (VMM)"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"containerd"})," shim uses a virtual machine monitor to create a confidential virtual machine for every pod.\nOn AKS, Contrast uses ",(0,i.jsx)(n.a,{href:"https://www.cloudhypervisor.org",children:(0,i.jsx)(n.code,{children:"cloud-hypervisor"})}),".\nOn bare metal, Contrast uses ",(0,i.jsx)(n.a,{href:"https://www.qemu.org/",children:(0,i.jsx)(n.code,{children:"QEMU"})}),".\nThe appropriate files are installed on every node by the ",(0,i.jsx)(n.a,{href:"#node-installer-daemonset",children:(0,i.jsx)(n.code,{children:"node-installer"})}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"snapshotters",children:"Snapshotters"}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses ",(0,i.jsxs)(n.a,{href:"https://github.com/containerd/containerd/tree/v1.7.16/docs/snapshotters/README.md",children:[(0,i.jsx)(n.code,{children:"containerd"})," snapshotters"]})," to provide container images to the pod-VM.\nEach snapshotter consists of a host component that pulls container images and a guest component used to mount/pull container images."]}),"\n",(0,i.jsxs)(n.p,{children:["On AKS, Contrast uses the ",(0,i.jsx)(n.a,{href:"https://github.com/kata-containers/tardev-snapshotter",children:(0,i.jsx)(n.code,{children:"tardev"})})," snapshotter to provide container images as block devices to the pod-VM.\nThe ",(0,i.jsx)(n.code,{children:"tardev"})," snapshotter uses ",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/admin-guide/device-mapper/verity.html",children:(0,i.jsx)(n.code,{children:"dm-verity"})})," to protect the integrity of container images.\nExpected ",(0,i.jsx)(n.code,{children:"dm-verity"})," container image hashes are part of Contrast runtime policies and are enforced by the kata-agent.\nThis enables workload attestation by specifying the allowed container image as part of the policy. Read ",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/components/policies",children:"the chapter on policies"})," for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["On bare metal, Contrast uses the ",(0,i.jsx)(n.a,{href:"https://github.com/containerd/nydus-snapshotter",children:(0,i.jsx)(n.code,{children:"nydus"})})," snapshotter to store metadata about the images. This metadata is communicated to the guest, so that it can pull the images itself."]}),"\n",(0,i.jsx)(n.h3,{id:"pod-vm-image",children:"Pod-VM image"}),"\n",(0,i.jsx)(n.p,{children:"Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem.\nThe IGVM file describes the initial memory contents of a pod-VM and consists of:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Linux kernel image"}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"initrd"})}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"kernel commandline"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem.\nThe root filesystem contains systemd as the init system, and the kata agent for managing the pod."}),"\n",(0,i.jsx)(n.p,{children:"This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime."}),"\n",(0,i.jsx)(n.h2,{id:"node-installer-daemonset",children:"Node installer DaemonSet"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"RuntimeClass"})," resource above registers the runtime with the Kubernetes api.\nThe node-level installation is carried out by the Contrast node-installer\n",(0,i.jsx)(n.code,{children:"DaemonSet"})," that ships with every Contrast release."]}),"\n",(0,i.jsx)(n.p,{children:"After deploying the installer, it performs the following steps on each node:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Install the Contrast containerd shim (",(0,i.jsx)(n.code,{children:"containerd-shim-contrast-cc-v2"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:["Install ",(0,i.jsx)(n.code,{children:"cloud-hypervisor"})," or ",(0,i.jsx)(n.code,{children:"QEMU"})," as the virtual machine manager (VMM)"]}),"\n",(0,i.jsx)(n.li,{children:"Install an IGVM file or separate firmware and kernel files for pod-VMs of this class"}),"\n",(0,i.jsx)(n.li,{children:"Install a read only root filesystem disk image for the pod-VMs of this class"}),"\n",(0,i.jsxs)(n.li,{children:["Reconfigure ",(0,i.jsx)(n.code,{children:"containerd"})," by adding a runtime plugin that corresponds to the ",(0,i.jsx)(n.code,{children:"handler"})," field of the Kubernetes ",(0,i.jsx)(n.code,{children:"RuntimeClass"})]}),"\n",(0,i.jsxs)(n.li,{children:["Restart ",(0,i.jsx)(n.code,{children:"containerd"})," to make it aware of the new plugin"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},30487:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/runtime-c41c29928f42a90474f03213074a5f97.svg"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/c7462af2.8edc4250.js b/pr-preview/pr-976/assets/js/c7462af2.8edc4250.js new file mode 100644 index 0000000000..92ef1ca71a --- /dev/null +++ b/pr-preview/pr-976/assets/js/c7462af2.8edc4250.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2540],{56473:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/policies","title":"Policies","description":"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.","source":"@site/versioned_docs/version-0.9/components/policies.md","sourceDirName":"components","slug":"/components/policies","permalink":"/contrast/pr-preview/pr-976/0.9/components/policies","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/components/policies.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/0.9/components/runtime"},"next":{"title":"Service mesh","permalink":"/contrast/pr-preview/pr-976/0.9/components/service-mesh"}}');var s=n(74848),o=n(28453);const r={},a="Policies",c={},l=[{value:"Structure",id:"structure",level:2},{value:"Generation",id:"generation",level:2},{value:"Evaluation",id:"evaluation",level:2},{value:"Guarantees",id:"guarantees",level:2},{value:"Trust",id:"trust",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"policies",children:"Policies"})}),"\n",(0,s.jsx)(t.p,{children:"Kata runtime policies are an integral part of the Confidential Containers preview on AKS.\nThey prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM.\nIn Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment.\nVerification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations."}),"\n",(0,s.jsx)(t.h2,{id:"structure",children:"Structure"}),"\n",(0,s.jsxs)(t.p,{children:["The Kata agent running in the confidential micro-VM exposes an RPC service ",(0,s.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers/blob/e5e0983/src/libs/protocols/protos/agent.proto#L21-L76",children:(0,s.jsx)(t.code,{children:"AgentService"})})," to the Kata runtime.\nThis service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy."]}),"\n",(0,s.jsxs)(t.p,{children:["Kata runtime policies are written in the policy language ",(0,s.jsx)(t.a,{href:"https://www.openpolicyagent.org/docs/latest/policy-language/",children:"Rego"}),".\nThey specify what ",(0,s.jsx)(t.code,{children:"AgentService"})," methods can be called, and the permissible parameters for each call."]}),"\n",(0,s.jsxs)(t.p,{children:["Policies consist of two parts: a list of rules and a data section.\nWhile the list of rules is static, the data section is populated with information from the ",(0,s.jsx)(t.code,{children:"PodSpec"})," and other sources."]}),"\n",(0,s.jsx)(t.h2,{id:"generation",children:"Generation"}),"\n",(0,s.jsxs)(t.p,{children:["Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI.\nThe ",(0,s.jsx)(t.code,{children:"generate"})," subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent.\nThere are two important integrity checks: container image checksums and OCI runtime parameters."]}),"\n",(0,s.jsxs)(t.p,{children:["For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic ",(0,s.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," checksum.\nThese checksums are the basis for the policy's ",(0,s.jsx)(t.em,{children:"storage data"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The CLI combines information from the ",(0,s.jsx)(t.code,{children:"PodSpec"}),", ",(0,s.jsx)(t.code,{children:"ConfigMaps"}),", and ",(0,s.jsx)(t.code,{children:"Secrets"})," in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables.\nThese constitute the policy's ",(0,s.jsx)(t.em,{children:"OCI data"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"evaluation",children:"Evaluation"}),"\n",(0,s.jsxs)(t.p,{children:["The generated policy document is annotated to the pod definitions in Base64 encoding.\nThis annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," for the confidential micro-VM."]}),"\n",(0,s.jsxs)(t.p,{children:["After the VM launched, the runtime calls the agent's ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method with the full policy document.\nIf the policy doesn't match the checksum in ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),", the agent rejects the policy.\nOtherwise, it applies the policy to all future ",(0,s.jsx)(t.code,{children:"AgentService"})," requests."]}),"\n",(0,s.jsx)(t.h2,{id:"guarantees",children:"Guarantees"}),"\n",(0,s.jsx)(t.p,{children:"The policy evaluation provides the following guarantees for pods launched with the correct generated policy:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Command and its arguments are set as specified in the resources."}),"\n",(0,s.jsx)(t.li,{children:"There are no unexpected additional environment variables."}),"\n",(0,s.jsx)(t.li,{children:"The container image layers correspond to the layers observed at policy generation time.\nThus, only the expected workload image can be instantiated."}),"\n",(0,s.jsx)(t.li,{children:"Executing additional processes in a container is prohibited."}),"\n",(0,s.jsx)(t.li,{children:"Sending data to a container's standard input is prohibited."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The current implementation of policy checking has some blind spots:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Containers can be started in any order, or be omitted entirely."}),"\n",(0,s.jsx)(t.li,{children:"Environment variables may be missing."}),"\n",(0,s.jsxs)(t.li,{children:["Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ",(0,s.jsx)(t.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(t.code,{children:"Secrets"}),")."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"trust",children:"Trust"}),"\n",(0,s.jsx)(t.p,{children:"Contrast verifies its confidential containers following these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"The Contrast CLI generates a policy and attaches it to the pod definition."}),"\n",(0,s.jsx)(t.li,{children:"Kubernetes schedules the pod on a node with the confidential computing runtime."}),"\n",(0,s.jsx)(t.li,{children:"Containerd invokes the Kata runtime to create the pod sandbox."}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime starts a CVM with the policy's digest as ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata runtime sets the policy using the ",(0,s.jsx)(t.code,{children:"SetPolicy"})," method."]}),"\n",(0,s.jsxs)(t.li,{children:["The Kata agent verifies that the incoming policy's digest matches ",(0,s.jsx)(t.code,{children:"HOSTDATA"}),"."]}),"\n",(0,s.jsx)(t.li,{children:"The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies."}),"\n",(0,s.jsx)(t.li,{children:"The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate."}),"\n",(0,s.jsxs)(t.li,{children:["The Contrast Coordinator verifies that the started pod has a permitted policy hash in its ",(0,s.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(96540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ca5b6702.a3b16546.js b/pr-preview/pr-976/assets/js/ca5b6702.a3b16546.js new file mode 100644 index 0000000000..1dff1225d4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/ca5b6702.a3b16546.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5945],{95477:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>h});const s=JSON.parse('{"id":"components/service-mesh","title":"Service mesh","description":"The Contrast service mesh secures the communication of the workload by automatically","source":"@site/docs/components/service-mesh.md","sourceDirName":"components","slug":"/components/service-mesh","permalink":"/contrast/pr-preview/pr-976/next/components/service-mesh","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/components/service-mesh.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Policies","permalink":"/contrast/pr-preview/pr-976/next/components/policies"},"next":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/next/architecture/attestation"}}');var i=t(74848),r=t(28453);const o={},c="Service mesh",a={},h=[{value:"Configuring the proxy",id:"configuring-the-proxy",level:2},{value:"Ingress",id:"ingress",level:3},{value:"Egress",id:"egress",level:3}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"service-mesh",children:"Service mesh"})}),"\n",(0,i.jsxs)(n.p,{children:["The Contrast service mesh secures the communication of the workload by automatically\nwrapping the network traffic inside mutual TLS (mTLS) connections. The\nverification of the endpoints in the connection establishment is based on\ncertificates that are part of the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates",children:"PKI of the Coordinator"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The service mesh can be enabled on a per-workload basis by adding a service mesh\nconfiguration to the workload's object annotations. During the ",(0,i.jsx)(n.code,{children:"contrast generate"}),"\nstep, the service mesh is added as a ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/",children:"sidecar\ncontainer"})," to\nall workloads which have a specified configuration. The service mesh container first\nsets up ",(0,i.jsx)(n.code,{children:"iptables"})," rules based on its configuration and then starts\n",(0,i.jsx)(n.a,{href:"https://www.envoyproxy.io/",children:"Envoy"})," for TLS origination and termination."]}),"\n",(0,i.jsx)(n.h2,{id:"configuring-the-proxy",children:"Configuring the proxy"}),"\n",(0,i.jsx)(n.p,{children:"The service mesh container can be configured using the following object annotations:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," to configure ingress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," to configure egress."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-admin-interface-port"})," to configure the Envoy\nadmin interface. If not specified, no admin interface will be started."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you aren't using the automatic service mesh injection and want to configure the\nservice mesh manually, set the environment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_INGRESS_PROXY_CONFIG"}),",\n",(0,i.jsx)(n.code,{children:"CONTRAST_EGRESS_PROXY_CONFIG"})," and ",(0,i.jsx)(n.code,{children:"CONTRAST_ADMIN_PORT"})," in the service mesh sidecar directly."]}),"\n",(0,i.jsx)(n.h3,{id:"ingress",children:"Ingress"}),"\n",(0,i.jsxs)(n.p,{children:["All TCP ingress traffic is routed over Envoy by default. Since we use\n",(0,i.jsx)(n.a,{href:"https://docs.kernel.org/networking/tproxy.html",children:"TPROXY"}),", the destination address\nremains the same throughout the packet handling."]}),"\n",(0,i.jsxs)(n.p,{children:["Any incoming connection is required to present a client certificate signed by the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nEnvoy presents a certificate chain of the mesh\ncertificate of the workload and the intermediate CA certificate as the server certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["If the deployment contains workloads which should be reachable from outside the\nService Mesh, while still handing out the certificate chain, disable client\nauthentication by setting the annotation ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-ingress"})," as\n",(0,i.jsx)(n.code,{children:"<name>#<port>#false"}),". Separate multiple entries with ",(0,i.jsx)(n.code,{children:"##"}),". You can choose any\ndescriptive string identifying the service on the given port for the ",(0,i.jsx)(n.code,{children:"<name>"})," field,\nas it's only informational."]}),"\n",(0,i.jsxs)(n.p,{children:["Disable redirection and TLS termination altogether by specifying\n",(0,i.jsx)(n.code,{children:"<name>#<port>#true"}),". This can be beneficial if the workload itself handles TLS\non that port or if the information exposed on this port is non-sensitive."]}),"\n",(0,i.jsx)(n.p,{children:"The following example workload exposes a web service on port 8080 and metrics on\nport 7890. The web server is exposed to a 3rd party end-user which wants to\nverify the deployment, therefore it's still required that the server hands out\nit certificate chain signed by the mesh CA certificate. The metrics should be\nexposed via TCP without TLS."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: web-svc\n image: ghcr.io/edgelesssys/frontend:v1.2.3@...\n ports:\n - containerPort: 8080\n name: web\n - containerPort: 7890\n name: metrics\n'})}),"\n",(0,i.jsxs)(n.p,{children:["When invoking ",(0,i.jsx)(n.code,{children:"contrast generate"}),", the resulting deployment will be injected with the\nContrast service mesh as an init container."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'# ...\n initContainers:\n - env:\n - name: CONTRAST_INGRESS_PROXY_CONFIG\n value: "web#8080#false##metrics#7890#true"\n image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:latest"\n name: contrast-service-mesh\n restartPolicy: Always\n securityContext:\n capabilities:\n add:\n - NET_ADMIN\n privileged: true\n volumeMounts:\n - name: contrast-secrets\n mountPath: /contrast\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Note, that changing the environment variables of the sidecar container directly will\nonly have an effect if the workload isn't configured to automatically generate a\nservice mesh component on ",(0,i.jsx)(n.code,{children:"contrast generate"}),". Otherwise, the service mesh sidecar\ncontainer will be regenerated on every invocation of the command."]}),"\n",(0,i.jsx)(n.h3,{id:"egress",children:"Egress"}),"\n",(0,i.jsx)(n.p,{children:"To be able to route the egress traffic of the workload through Envoy, the remote\nendpoints' IP address and port must be configurable."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Choose an IP address inside the ",(0,i.jsx)(n.code,{children:"127.0.0.0/8"})," CIDR and a port not yet in use\nby the pod."]}),"\n",(0,i.jsx)(n.li,{children:"Configure the workload to connect to this IP address and port."}),"\n",(0,i.jsxs)(n.li,{children:["Set ",(0,i.jsx)(n.code,{children:"<name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port>"}),"\nas the ",(0,i.jsx)(n.code,{children:"contrast.edgeless.systems/servicemesh-egress"})," workload annotation. Separate multiple\nentries with ",(0,i.jsx)(n.code,{children:"##"}),". Choose any string identifying the service on the given port as\n",(0,i.jsx)(n.code,{children:"<name>"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This redirects the traffic over Envoy. The endpoint must present a valid\ncertificate chain which must be verifiable with the\n",(0,i.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/next/architecture/certificates#usage-of-the-different-certificates",children:"mesh CA certificate"}),".\nFurthermore, Envoy uses a certificate chain with the mesh certificate of the workload\nand the intermediate CA certificate as the client certificate."]}),"\n",(0,i.jsxs)(n.p,{children:["The following example workload has no ingress connections and two egress\nconnection to different microservices. The microservices are part\nof the confidential deployment. One is reachable under ",(0,i.jsx)(n.code,{children:"billing-svc:8080"})," and\nthe other under ",(0,i.jsx)(n.code,{children:"cart-svc:8080"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'apiVersion: apps/v1\nkind: Deployment\nmetadata:\n name: web\n annotations:\n contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"\nspec:\n replicas: 1\n template:\n spec:\n runtimeClassName: contrast-cc\n containers:\n - name: currency-conversion\n image: ghcr.io/edgelesssys/conversion:v1.2.3@...\n'})})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/cdb2b1a5.cee59a12.js b/pr-preview/pr-976/assets/js/cdb2b1a5.cee59a12.js new file mode 100644 index 0000000000..c9397d29d1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/cdb2b1a5.cee59a12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9119],{67766:(e,t,n)=>{n.d(t,{A:()=>b});var r=n(96540),s=n(34164),o=n(85246),c=n(57880),i=n(25792);const l=["zero","one","two","few","many","other"];function a(e){return l.filter((t=>e.includes(t)))}const u={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function d(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,r.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),u}}),[e])}function m(){const e=d();return{selectMessage:(t,n)=>function(e,t,n){const r=e.split("|");if(1===r.length)return r[0];r.length>n.pluralForms.length&&console.error(`For locale=${n.locale}, a maximum of ${n.pluralForms.length} plural forms are expected (${n.pluralForms.join(",")}), but the message contains ${r.length}: ${e}`);const s=n.select(t),o=n.pluralForms.indexOf(s);return r[Math.min(o,r.length-1)]}(n,t,e)}}var p=n(77056),f=n(32032),h=n(98445);const x={cardContainer:"cardContainer_fWXF",cardTitle:"cardTitle_rnsV",cardDescription:"cardDescription_PWke"};var g=n(74848);function j(e){let{href:t,children:n}=e;return(0,g.jsx)(c.A,{href:t,className:(0,s.A)("card padding--lg",x.cardContainer),children:n})}function v(e){let{href:t,icon:n,title:r,description:o}=e;return(0,g.jsxs)(j,{href:t,children:[(0,g.jsxs)(h.A,{as:"h2",className:(0,s.A)("text--truncate",x.cardTitle),title:r,children:[n," ",r]}),o&&(0,g.jsx)("p",{className:(0,s.A)("text--truncate",x.cardDescription),title:o,children:o})]})}function w(e){let{item:t}=e;const n=(0,o.Nr)(t),r=function(){const{selectMessage:e}=m();return t=>e(t,(0,f.T)({message:"1 item|{count} items",id:"theme.docs.DocCard.categoryDescription.plurals",description:"The default description for a category card in the generated index about how many items this category includes"},{count:t}))}();return n?(0,g.jsx)(v,{href:n,icon:"\ud83d\uddc3\ufe0f",title:t.label,description:t.description??r(t.items.length)}):null}function y(e){let{item:t}=e;const n=(0,p.A)(t.href)?"\ud83d\udcc4\ufe0f":"\ud83d\udd17",r=(0,o.cC)(t.docId??void 0);return(0,g.jsx)(v,{href:t.href,icon:n,title:t.label,description:t.description??r?.description})}function C(e){let{item:t}=e;switch(t.type){case"link":return(0,g.jsx)(y,{item:t});case"category":return(0,g.jsx)(w,{item:t});default:throw new Error(`unknown item type ${JSON.stringify(t)}`)}}function N(e){let{className:t}=e;const n=(0,o.$S)();return(0,g.jsx)(b,{items:n.items,className:t})}function b(e){const{items:t,className:n}=e;if(!t)return(0,g.jsx)(N,{...e});const r=(0,o.d1)(t);return(0,g.jsx)("section",{className:(0,s.A)("row",n),children:r.map(((e,t)=>(0,g.jsx)("article",{className:"col col--6 margin-bottom--lg",children:(0,g.jsx)(C,{item:e})},t)))})}},78496:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>l,default:()=>m,frontMatter:()=>i,metadata:()=>r,toc:()=>u});const r=JSON.parse('{"id":"examples/index","title":"Examples","description":"","source":"@site/versioned_docs/version-0.6/examples/index.md","sourceDirName":"examples","slug":"/examples/","permalink":"/contrast/pr-preview/pr-976/0.6/examples/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/examples/index.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto"}}');var s=n(74848),o=n(28453),c=n(67766);const i={},l="Examples",a={},u=[];function d(e){const t={h1:"h1",header:"header",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"examples",children:"Examples"})}),"\n","\n",(0,s.jsx)(c.A,{})]})}function m(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>i});var r=n(96540);const s={},o=r.createContext(s);function c(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/cf49aa2b.89d9d490.js b/pr-preview/pr-976/assets/js/cf49aa2b.89d9d490.js new file mode 100644 index 0000000000..e6ddbec5d6 --- /dev/null +++ b/pr-preview/pr-976/assets/js/cf49aa2b.89d9d490.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4703],{18803:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>c});const r=JSON.parse('{"id":"getting-started/bare-metal","title":"Prepare a bare-metal instance","description":"Hardware and firmware setup","source":"@site/docs/getting-started/bare-metal.md","sourceDirName":"getting-started","slug":"/getting-started/bare-metal","permalink":"/contrast/pr-preview/pr-976/next/getting-started/bare-metal","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/getting-started/bare-metal.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/next/examples/emojivoto"}}');var s=n(74848),a=n(28453);const i={},o="Prepare a bare-metal instance",l={},c=[{value:"Hardware and firmware setup",id:"hardware-and-firmware-setup",level:2},{value:"Kernel Setup",id:"kernel-setup",level:2},{value:"K3s Setup",id:"k3s-setup",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,a.R)(),...e.components},{TabItem:n,Tabs:r}=t;return n||u("TabItem",!0),r||u("Tabs",!0),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"prepare-a-bare-metal-instance",children:"Prepare a bare-metal instance"})}),"\n",(0,s.jsx)(t.h2,{id:"hardware-and-firmware-setup",children:"Hardware and firmware setup"}),"\n",(0,s.jsxs)(r,{queryString:"vendor",children:[(0,s.jsxs)(n,{value:"amd",label:"AMD SEV-SNP",children:[(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Update your BIOS to a version that supports AMD SEV-SNP. Updating to the latest available version is recommended as newer versions will likely contain security patches for AMD SEV-SNP."}),"\n",(0,s.jsx)(t.li,{children:"Enter BIOS setup to enable SMEE, IOMMU, RMP coverage, and SEV-SNP. Set the SEV-ES ASID Space Limit to a non-zero number (higher is better)."}),"\n",(0,s.jsxs)(t.li,{children:["Download the latest firmware version for your processor from ",(0,s.jsx)(t.a,{href:"https://www.amd.com/de/developer/sev.html",children:"AMD"}),", unpack it, and place it in ",(0,s.jsx)(t.code,{children:"/lib/firmware/amd"}),"."]}),"\n"]}),(0,s.jsxs)(t.p,{children:["Consult AMD's ",(0,s.jsx)(t.a,{href:"https://www.amd.com/content/dam/amd/en/documents/epyc-technical-docs/tuning-guides/58207-using-sev-with-amd-epyc-processors.pdf",children:"Using SEV with AMD EPYC Processors user guide"})," for more information."]})]}),(0,s.jsx)(n,{value:"intel",label:"Intel TDX",children:(0,s.jsxs)(t.p,{children:["Follow Canonical's instructions on ",(0,s.jsx)(t.a,{href:"https://github.com/canonical/tdx?tab=readme-ov-file#43-enable-intel-tdx-in-the-hosts-bios",children:"setting up Intel TDX in the host's BIOS"}),"."]})})]}),"\n",(0,s.jsx)(t.h2,{id:"kernel-setup",children:"Kernel Setup"}),"\n",(0,s.jsxs)(r,{queryString:"vendor",children:[(0,s.jsx)(n,{value:"amd",label:"AMD SEV-SNP",children:(0,s.jsx)(t.p,{children:"Install a kernel with version 6.11 or greater. If you're following this guide before 6.11 has been released, use 6.11-rc3. Don't use 6.11-rc4 - 6.11-rc6 as they contain a regression. 6.11-rc7+ might work."})}),(0,s.jsx)(n,{value:"intel",label:"Intel TDX",children:(0,s.jsxs)(t.p,{children:["Follow Canonical's instructions on ",(0,s.jsx)(t.a,{href:"https://github.com/canonical/tdx?tab=readme-ov-file#41-install-ubuntu-2404-server-image",children:"setting up Intel TDX on Ubuntu 24.04"}),". Note that Contrast currently only supports Intel TDX with Ubuntu 24.04."]})})]}),"\n",(0,s.jsxs)(t.p,{children:["Increase the ",(0,s.jsx)(t.code,{children:"user.max_inotify_instances"})," sysctl limit by adding ",(0,s.jsx)(t.code,{children:"user.max_inotify_instances=8192"})," to ",(0,s.jsx)(t.code,{children:"/etc/sysctl.d/99-sysctl.conf"})," and running ",(0,s.jsx)(t.code,{children:"sysctl --system"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"k3s-setup",children:"K3s Setup"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Follow the ",(0,s.jsx)(t.a,{href:"https://docs.k3s.io/",children:"K3s setup instructions"})," to create a cluster."]}),"\n",(0,s.jsxs)(t.li,{children:["Install a block storage provider such as ",(0,s.jsx)(t.a,{href:"https://docs.k3s.io/storage#setting-up-longhorn",children:"Longhorn"})," and mark it as the default storage class."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}function u(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var r=n(96540);const s={},a=r.createContext(s);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/d1a11e04.8df8afb2.js b/pr-preview/pr-976/assets/js/d1a11e04.8df8afb2.js new file mode 100644 index 0000000000..6c5dfb4cb0 --- /dev/null +++ b/pr-preview/pr-976/assets/js/d1a11e04.8df8afb2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8902],{97232:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/versioned_docs/version-0.8/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/0.8/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.8/features-limitations.md","tags":[],"version":"0.8","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.8/architecture/observability"},"next":{"title":"Telemetry","permalink":"/contrast/pr-preview/pr-976/0.8/about/telemetry"}}');var r=t(74848),s=t(28453);const o={},a="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2},{value:"Automatic recovery and high availability",id:"automatic-recovery-and-high-availability",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,r.jsx)(n.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,r.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,r.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Bare-metal support"}),": Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Persistent volumes"}),": Contrast only supports volumes with ",(0,r.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-mode",children:(0,r.jsx)(n.code,{children:"volumeMode: Block"})}),". These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Port forwarding"}),": This feature ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,r.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,r.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,r.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,r.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,r.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,r.jsx)(n.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"automatic-recovery-and-high-availability",children:"Automatic recovery and high availability"}),"\n",(0,r.jsx)(n.p,{children:"The Contrast Coordinator is a singleton and can't be scaled to more than one instance.\nWhen this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually.\nIn a future release, we plan to support distributed Coordinator instances that can recover automatically."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const r={},s=i.createContext(r);function o(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/d2630e76.be1d4782.js b/pr-preview/pr-976/assets/js/d2630e76.be1d4782.js new file mode 100644 index 0000000000..f6c561ef87 --- /dev/null +++ b/pr-preview/pr-976/assets/js/d2630e76.be1d4782.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[9634],{22846:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>n,toc:()=>p});const n=JSON.parse('{"id":"architecture/network-encryption/protocols-and-keys","title":"protocols-and-keys","description":"","source":"@site/versioned_docs/version-0.5/architecture/network-encryption/protocols-and-keys.md","sourceDirName":"architecture/network-encryption","slug":"/architecture/network-encryption/protocols-and-keys","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/network-encryption/protocols-and-keys.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Sidecar","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar"}}');var o=r(74848),c=r(28453);const s={},i=void 0,a={},p=[];function d(e){return(0,o.jsx)(o.Fragment,{})}function u(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d()}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>i});var n=r(96540);const o={},c=n.createContext(o);function s(e){const t=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/d580a1fd.d3605f1d.js b/pr-preview/pr-976/assets/js/d580a1fd.d3605f1d.js new file mode 100644 index 0000000000..4feba7b525 --- /dev/null +++ b/pr-preview/pr-976/assets/js/d580a1fd.d3605f1d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1734],{42533:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>p});const r=JSON.parse('{"id":"architecture/components/init-container","title":"init-container","description":"","source":"@site/versioned_docs/version-0.5/architecture/components/init-container.md","sourceDirName":"architecture/components","slug":"/architecture/components/init-container","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/components/init-container.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator"},"next":{"title":"CLI","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli"}}');var o=n(74848),c=n(28453);const i={},s=void 0,a={},p=[];function u(t){return(0,o.jsx)(o.Fragment,{})}function d(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,o.jsx)(e,{...t,children:(0,o.jsx)(u,{...t})}):u()}},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>s});var r=n(96540);const o={},c=r.createContext(o);function i(t){const e=r.useContext(c);return r.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function s(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(o):t.components||o:i(t.components),r.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/d77304ba.f1bec1ec.js b/pr-preview/pr-976/assets/js/d77304ba.f1bec1ec.js new file mode 100644 index 0000000000..2282192ed4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/d77304ba.f1bec1ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4233],{15796:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-1.0/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/basics/confidential-containers.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"What is Contrast?","permalink":"/contrast/pr-preview/pr-976/1.0/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/1.0/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/dacf14a0.c33c9e89.js b/pr-preview/pr-976/assets/js/dacf14a0.c33c9e89.js new file mode 100644 index 0000000000..48c15103da --- /dev/null +++ b/pr-preview/pr-976/assets/js/dacf14a0.c33c9e89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[101],{48763:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-0.9/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/getting-started/install.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.9/basics/features"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup"}}');var r=s(74848),a=s(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v0.9.0/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>o,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function o(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/de615ffd.ef11da9f.js b/pr-preview/pr-976/assets/js/de615ffd.ef11da9f.js new file mode 100644 index 0000000000..6a71a3a7ab --- /dev/null +++ b/pr-preview/pr-976/assets/js/de615ffd.ef11da9f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1321],{85230:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"deployment","title":"Workload deployment","description":"The following instructions will guide you through the process of making an existing Kubernetes deployment","source":"@site/versioned_docs/version-0.7/deployment.md","sourceDirName":".","slug":"/deployment","permalink":"/contrast/pr-preview/pr-976/0.7/deployment","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/deployment.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.7/examples/emojivoto"},"next":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.7/components/"}}');var r=t(74848),i=t(28453);const o={},a="Workload deployment",c={},l=[{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:2},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:2},{value:"Prepare your Kubernetes resources",id:"prepare-your-kubernetes-resources",level:2},{value:"RuntimeClass",id:"runtimeclass",level:3},{value:"Handling TLS",id:"handling-tls",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:2},{value:"Apply the resources",id:"apply-the-resources",level:2},{value:"Connect to the Contrast Coordinator",id:"connect-to-the-contrast-coordinator",level:2},{value:"Set the manifest",id:"set-the-manifest",level:2},{value:"Verify the Coordinator",id:"verify-the-coordinator",level:2},{value:"Communicate with workloads",id:"communicate-with-workloads",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components},{TabItem:t,Tabs:s}=n;return t||p("TabItem",!0),s||p("Tabs",!0),(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"workload-deployment",children:"Workload deployment"})}),"\n",(0,r.jsx)(n.p,{children:"The following instructions will guide you through the process of making an existing Kubernetes deployment\nconfidential and deploying it together with Contrast."}),"\n",(0,r.jsxs)(n.p,{children:["A running CoCo-enabled cluster is required for these steps, see the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup",children:"setup guide"})," on how to set it up."]}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,r.jsxs)(n.p,{children:["Contrast depends on a ",(0,r.jsxs)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/runtime",children:["custom Kubernetes ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," (",(0,r.jsx)(n.code,{children:"contrast-cc"}),")"]}),",\nwhich needs to be installed in the cluster prior to the Coordinator or any confidential workloads.\nThis consists of a ",(0,r.jsx)(n.code,{children:"RuntimeClass"})," resource and a ",(0,r.jsx)(n.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/runtime.yml\n"})}),"\n",(0,r.jsx)(n.h2,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"Install the latest Contrast Coordinator release, comprising a single replica deployment and a\nLoadBalancer service, into your cluster."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v0.7.3/coordinator.yml\n"})}),"\n",(0,r.jsx)(n.h2,{id:"prepare-your-kubernetes-resources",children:"Prepare your Kubernetes resources"}),"\n",(0,r.jsx)(n.p,{children:"Your Kubernetes resources need some modifications to run as Confidential Containers.\nThis section guides you through the process and outlines the necessary changes."}),"\n",(0,r.jsx)(n.h3,{id:"runtimeclass",children:"RuntimeClass"}),"\n",(0,r.jsx)(n.p,{children:"Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files\nunchanged, you can copy the files into a separate local directory.\nYou can also generate files from a Helm chart or from a Kustomization."}),"\n",(0,r.jsxs)(s,{groupId:"yaml-source",children:[(0,r.jsx)(t,{value:"kustomize",label:"kustomize",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nkustomize build $MY_RESOURCE_DIR > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"helm",label:"helm",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"mkdir resources\nhelm template $RELEASE_NAME $CHART_NAME > resources/all.yml\n"})})}),(0,r.jsx)(t,{value:"copy",label:"copy",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"cp -R $MY_RESOURCE_DIR resources/\n"})})})]}),"\n",(0,r.jsxs)(n.p,{children:["To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers,\nadd ",(0,r.jsx)(n.code,{children:"runtimeClassName: contrast-cc"})," to the pod spec (pod definition or template).\nThis is a placeholder name that will be replaced by a versioned ",(0,r.jsx)(n.code,{children:"runtimeClassName"})," when generating policies."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"spec: # v1.PodSpec\n runtimeClassName: contrast-cc\n"})}),"\n",(0,r.jsx)(n.h3,{id:"handling-tls",children:"Handling TLS"}),"\n",(0,r.jsxs)(n.p,{children:["In the initialization process, the ",(0,r.jsx)(n.code,{children:"contrast-tls-certs"})," shared volume is populated with X.509 certificates for your workload.\nThese certificates are used by the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"Contrast Service Mesh"}),", but can also be used by your application directly.\nThe following tab group explains the setup for both scenarios."]}),"\n",(0,r.jsxs)(s,{groupId:"tls",children:[(0,r.jsxs)(t,{value:"mesh",label:"Drop-in service mesh",children:[(0,r.jsx)(n.p,{children:"Contrast can be configured to handle TLS in a sidecar container.\nThis is useful for workloads that are hard to configure with custom certificates, like Java applications."}),(0,r.jsx)(n.p,{children:"Configuration of the sidecar depends heavily on the application.\nThe following example is for an application with these properties:"}),(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication."}),"\n",(0,r.jsx)(n.li,{children:"The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text."}),"\n",(0,r.jsx)(n.li,{children:"All other endpoints require client authentication."}),"\n",(0,r.jsxs)(n.li,{children:["The app connects to a Kubernetes service ",(0,r.jsx)(n.code,{children:"backend.default:4001"}),", which requires client authentication."]}),"\n"]}),(0,r.jsx)(n.p,{children:"Add the following annotations to your workload:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"\n contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"\n'})}),(0,r.jsxs)(n.p,{children:["During the ",(0,r.jsx)(n.code,{children:"generate"})," step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically.\nThe only change required to the app itself is to let it connect to ",(0,r.jsx)(n.code,{children:"127.0.0.2:4001"})," to reach the backend service.\nYou can find more detailed documentation in the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"Service Mesh chapter"}),"."]})]}),(0,r.jsxs)(t,{value:"go",label:"Go integration",children:[(0,r.jsxs)(n.p,{children:["The mesh certificate contained in ",(0,r.jsx)(n.code,{children:"certChain.pem"})," authenticates this workload, while the mesh CA certificate ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," authenticates its peers.\nYour app should turn on client authentication to ensure peers are running as confidential containers, too.\nSee the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/architecture/certificates",children:"Certificate Authority"})," section for detailed information about these certificates."]}),(0,r.jsx)(n.p,{children:"The following example shows how to configure a Golang app, with error handling omitted for clarity."}),(0,r.jsxs)(s,{groupId:"golang-tls-setup",children:[(0,r.jsx)(t,{value:"client",label:"Client",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n RootCAs: caCerts,\n}\n'})})}),(0,r.jsx)(t,{value:"server",label:"Server",children:(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-go",children:'caCerts := x509.NewCertPool()\ncaCert, _ := os.ReadFile("/tls-config/mesh-ca.pem")\ncaCerts.AppendCertsFromPEM(caCert)\ncert, _ := tls.LoadX509KeyPair("/tls-config/certChain.pem", "/tls-config/key.pem")\ncfg := &tls.Config{\n Certificates: []tls.Certificate{cert},\n ClientAuth: tls.RequireAndVerifyClientCert,\n ClientCAs: caCerts,\n}\n'})})})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,r.jsxs)(n.p,{children:["Run the ",(0,r.jsx)(n.code,{children:"generate"})," command to add the necessary components to your deployment files.\nThis will add the Contrast Initializer to every workload with the specified ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class\nand the Contrast Service Mesh to all workloads that have a specified configuration.\nAfter that, it will generate the execution policies and add them as annotations to your deployment files.\nA ",(0,r.jsx)(n.code,{children:"manifest.json"})," with the reference values of your deployment will be created."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate resources/\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"warning",children:(0,r.jsxs)(n.p,{children:["Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the ",(0,r.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/features-limitations#runtime-policies",children:"current limitations"})," for more details."]})}),"\n",(0,r.jsx)(n.p,{children:"If you don't want the Contrast Initializer to automatically be added to your\nworkloads, there are two ways you can skip the Initializer injection step,\ndepending on how you want to customize your deployment."}),"\n",(0,r.jsxs)(s,{groupId:"injection",children:[(0,r.jsxs)(t,{value:"flag",label:"Command-line flag",children:[(0,r.jsxs)(n.p,{children:["You can disable the Initializer injection completely by specifying the\n",(0,r.jsx)(n.code,{children:"--skip-initializer"})," flag in the ",(0,r.jsx)(n.code,{children:"generate"})," command."]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"contrast generate --skip-initializer resources/\n"})})]}),(0,r.jsxs)(t,{value:"annotation",label:"Per-workload annotation",children:[(0,r.jsxs)(n.p,{children:["If you want to disable the Initializer injection for a specific workload with\nthe ",(0,r.jsx)(n.code,{children:"contrast-cc"})," runtime class, you can do so by adding an annotation to the workload."]}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...\n annotations:\n contrast.edgeless.systems/skip-initializer: "true"\n'})})]})]}),"\n",(0,r.jsxs)(n.p,{children:["When disabling the automatic Initializer injection, you can manually add the\nInitializer as a sidecar container to your workload before generating the\npolicies. Configure the workload to use the certificates written to the\n",(0,r.jsx)(n.code,{children:"contrast-tls-certs"})," ",(0,r.jsx)(n.code,{children:"volumeMount"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:'# v1.PodSpec\nspec:\n initContainers:\n - env:\n - name: COORDINATOR_HOST\n value: coordinator\n image: "ghcr.io/edgelesssys/contrast/initializer:v0.7.3@sha256:55475365c8177420ff3b27ad48bb0f38f8a92bfe754f50f1ed97f50f17ee23b8"\n name: contrast-initializer\n volumeMounts:\n - mountPath: /tls-config\n name: contrast-tls-certs\n volumes:\n - emptyDir: {}\n name: contrast-tls-certs\n'})}),"\n",(0,r.jsx)(n.h2,{id:"apply-the-resources",children:"Apply the resources"}),"\n",(0,r.jsx)(n.p,{children:"Apply the resources to the cluster. Your workloads will block in the initialization phase until a\nmanifest is set at the Coordinator."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl apply -f resources/\n"})}),"\n",(0,r.jsx)(n.h2,{id:"connect-to-the-contrast-coordinator",children:"Connect to the Contrast Coordinator"}),"\n",(0,r.jsx)(n.p,{children:"For the next steps, we will need to connect to the Coordinator. The released Coordinator resource\nincludes a LoadBalancer definition we can use."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Port-forwarding of Confidential Containers",type:"info",children:[(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"kubectl port-forward"})," uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim.\nIf you can't use a public load balancer, you can deploy a ",(0,r.jsx)(n.a,{href:"https://github.com/edgelesssys/contrast/blob/ddc371b/deployments/emojivoto/portforwarder.yml",children:"port-forwarder"}),".\nThe port-forwarder relays traffic from a CoCo pod and can be accessed via ",(0,r.jsx)(n.code,{children:"kubectl port-forward"}),"."]}),(0,r.jsxs)(n.p,{children:["Upstream tracking issue: ",(0,r.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"https://github.com/kata-containers/kata-containers/issues/1693"}),"."]})]}),"\n",(0,r.jsx)(n.h2,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,r.jsx)(n.p,{children:"Attest the Coordinator and set the manifest:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" resources/\n'})}),"\n",(0,r.jsx)(n.p,{children:"After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container\nwill fetch a certificate for the workload and the workload is started."}),"\n",(0,r.jsx)(n.h2,{id:"verify-the-coordinator",children:"Verify the Coordinator"}),"\n",(0,r.jsxs)(n.p,{children:["An end user (data owner) can verify the Contrast deployment using the ",(0,r.jsx)(n.code,{children:"verify"})," command."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313"\n'})}),"\n",(0,r.jsxs)(n.p,{children:["The CLI will attest the Coordinator using embedded reference values. The CLI will write the service mesh\nroot certificate and the history of manifests into the ",(0,r.jsx)(n.code,{children:"verify/"})," directory. In addition, the policies referenced\nin the manifest are also written to the directory."]}),"\n",(0,r.jsx)(n.h2,{id:"communicate-with-workloads",children:"Communicate with workloads"}),"\n",(0,r.jsxs)(n.p,{children:["You can securely connect to the workloads using the Coordinator's ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"})," as a trusted CA certificate.\nFirst, expose the service on a public IP address via a LoadBalancer service:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"kubectl patch svc ${MY_SERVICE} -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'\nkubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}\nlbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho $lbip\n"})}),"\n",(0,r.jsxs)(n.admonition,{title:"Subject alternative names and LoadBalancer IP",type:"info",children:[(0,r.jsx)(n.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field.\nValidation fails since the certificate contains no IP entries as a subject alternative name (SAN).\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Using ",(0,r.jsx)(n.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,r.jsx)(n.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}function p(e,n){throw new Error("Expected "+(n?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/dfd9c366.af676094.js b/pr-preview/pr-976/assets/js/dfd9c366.af676094.js new file mode 100644 index 0000000000..90043f59e7 --- /dev/null +++ b/pr-preview/pr-976/assets/js/dfd9c366.af676094.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2454],{29026:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"basics/features","title":"Product features","description":"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.","source":"@site/versioned_docs/version-0.6/basics/features.md","sourceDirName":"basics","slug":"/basics/features","permalink":"/contrast/pr-preview/pr-976/0.6/basics/features","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/basics/features.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits"},"next":{"title":"Getting started","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/"}}');var r=n(74848),i=n(28453);const o={},a="Product features",c={},l=[];function d(e){const t={a:"a",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"product-features",children:"Product features"})}),"\n",(0,r.jsx)(t.p,{children:"Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment."}),"\n",(0,r.jsxs)(t.p,{children:["From a security perspective, Contrast employs the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",children:"Confidential Containers"})," concept and provides ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"security benefits"})," that go beyond individual containers, shielding your entire deployment from the underlying infrastructure."]}),"\n",(0,r.jsx)(t.p,{children:"From an operational perspective, Contrast provides the following key features:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Managed Kubernetes compatibility"}),": Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Lightweight installation"}),": Contrast can be integrated as a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/deployment",children:"day-2 operation"})," within existing clusters, adding minimal ",(0,r.jsx)(t.a,{href:"../architecture",children:"components"})," to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Remote attestation"}),": Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation\u2019s validity."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Service mesh"}),": Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the ",(0,r.jsx)(t.a,{href:"https://www.envoyproxy.io/",children:"envoy proxy"})," to ensure secure communications within your Kubernetes cluster."]}),"\n"]}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e1e441c9.d7ad6ed8.js b/pr-preview/pr-976/assets/js/e1e441c9.d7ad6ed8.js new file mode 100644 index 0000000000..aacb54bac5 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e1e441c9.d7ad6ed8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2623],{54794:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>i,toc:()=>h});const i=JSON.parse('{"id":"architecture/attestation","title":"Attestation in Contrast","description":"This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334.","source":"@site/versioned_docs/version-0.6/architecture/attestation.md","sourceDirName":"architecture","slug":"/architecture/attestation","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/attestation","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/architecture/attestation.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Architecture","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/0.6/architecture/certificates"}}');var r=n(74848),s=n(28453);const a={},o="Attestation in Contrast",c={},h=[{value:"Attestation architecture",id:"attestation-architecture",level:2},{value:"Components of Contrast's attestation",id:"components-of-contrasts-attestation",level:2},{value:"Attester: Application Pods",id:"attester-application-pods",level:3},{value:"Verifier: Coordinator and CLI",id:"verifier-coordinator-and-cli",level:3},{value:"Relying Party: Data owner",id:"relying-party-data-owner",level:3},{value:"Evidence generation and appraisal",id:"evidence-generation-and-appraisal",level:2},{value:"Evidence types and formats",id:"evidence-types-and-formats",level:3},{value:"Appraisal policies for evidence",id:"appraisal-policies-for-evidence",level:3},{value:"Frequently asked questions about attestation in Contrast",id:"frequently-asked-questions-about-attestation-in-contrast",level:2},{value:"What's the purpose of remote attestation in Contrast?",id:"whats-the-purpose-of-remote-attestation-in-contrast",level:3},{value:"How does Contrast ensure the security of the attestation process?",id:"how-does-contrast-ensure-the-security-of-the-attestation-process",level:3},{value:"What security benefits does attestation provide?",id:"what-security-benefits-does-attestation-provide",level:3},{value:"How can you verify the authenticity of attestation results?",id:"how-can-you-verify-the-authenticity-of-attestation-results",level:3},{value:"How are attestation results used by relying parties?",id:"how-are-attestation-results-used-by-relying-parties",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"attestation-in-contrast",children:"Attestation in Contrast"})}),"\n",(0,r.jsxs)(t.p,{children:["This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html",children:"RFC 9334"}),".\nThe following gives a detailed description of Contrast's attestation architecture.\nAt the end of this document, we included an ",(0,r.jsx)(t.a,{href:"#frequently-asked-questions-about-attestation-in-contrast",children:"FAQ"})," that answers the most common questions regarding attestation in hindsight of the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"security benefits"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"attestation-architecture",children:"Attestation architecture"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including ",(0,r.jsx)(t.em,{children:"Attesters"}),", ",(0,r.jsx)(t.em,{children:"Verifiers"}),", and ",(0,r.jsx)(t.em,{children:"Relying Parties"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Conceptual attestation architecture",src:n(45890).A+"",width:"592",height:"377"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 1: Conceptual attestation architecture. Taken from ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-1",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Attester"}),": Assigned to entities that are responsible for creating ",(0,r.jsx)(t.em,{children:"Evidence"})," which is then sent to a ",(0,r.jsx)(t.em,{children:"Verifier"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Verifier"}),": These entities utilize the ",(0,r.jsx)(t.em,{children:"Evidence"}),", ",(0,r.jsx)(t.em,{children:"Reference Values"}),", and ",(0,r.jsx)(t.em,{children:"Endorsements"}),". They assess the trustworthiness of the ",(0,r.jsx)(t.em,{children:"Attester"})," by applying an ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"}),". Following this assessment, ",(0,r.jsx)(t.em,{children:"Verifiers"})," generate ",(0,r.jsx)(t.em,{children:"Attestation Results"})," for use by ",(0,r.jsx)(t.em,{children:"Relying Parties"}),". The ",(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Evidence"})," may be provided by the ",(0,r.jsx)(t.em,{children:"Verifier Owner"}),", programmed into the ",(0,r.jsx)(t.em,{children:"Verifier"}),", or acquired through other means."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"Relying Party"}),": Assigned to entities that utilize ",(0,r.jsx)(t.em,{children:"Attestation Results"}),', applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The ',(0,r.jsx)(t.em,{children:"Appraisal Policy"})," for ",(0,r.jsx)(t.em,{children:"Attestation Results"})," might be sourced from the ",(0,r.jsx)(t.em,{children:"Relying Party Owner"}),", configured by the owner, embedded in the ",(0,r.jsx)(t.em,{children:"Relying Party"}),", or obtained through other protocols or mechanisms."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"components-of-contrasts-attestation",children:"Components of Contrast's attestation"}),"\n",(0,r.jsx)(t.p,{children:"The key components involved in the attestation process of Contrast are detailed below:"}),"\n",(0,r.jsx)(t.h3,{id:"attester-application-pods",children:"Attester: Application Pods"}),"\n",(0,r.jsxs)(t.p,{children:["This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state.\nTheir evidence is rooted in the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",children:"hardware measurements"})," from the CPU and their ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"confidential VM environment"}),".\nThe details of this evidence are given below in the section on ",(0,r.jsx)(t.a,{href:"#evidence-generation-and-appraisal",children:"evidence generation and appraisal"}),"."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Attestation flow of a confidential pod",src:n(83451).A+"",width:"608",height:"697"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-3",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["Pods run in Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/runtime",children:"runtime environment"})," (B), effectively within a confidential VM.\nDuring launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence.\nThe image is in ",(0,r.jsx)(t.a,{href:"https://github.com/microsoft/igvm",children:"IGVM format"}),", encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline.\nThe kernel cmdline contains the root hash for ",(0,r.jsx)(t.a,{href:"https://www.kernel.org/doc/html/latest/admin-guide/device-mapper/verity.html",children:"dm-verity"})," that ensures the integrity of the root filesystem.\nThe root filesystem contains all components of the container's runtime environment including the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers#kata-containers",children:"guest agent"})," (C)."]}),"\n",(0,r.jsxs)(t.p,{children:["In the userland, the guest agent takes care of enforcing the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#runtime-policies",children:"runtime policy"})," of the pod.\nWhile the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements.\nDuring the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/deployment#generate-policy-annotations-and-manifest",children:"deployment"})," the policy is annotated to the Kubernetes Pod resources.\nOn AMD SEV-SNP the hash of the policy is then added to the attestation report via the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field by the hypervisor.\nWhen provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the ",(0,r.jsx)(t.code,{children:"HOSTDATA"})," field."]}),"\n",(0,r.jsx)(t.p,{children:"In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy."}),"\n",(0,r.jsx)(t.h3,{id:"verifier-coordinator-and-cli",children:"Verifier: Coordinator and CLI"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-coordinator",children:"Coordinator"})," acts as a verifier within the Contrast deployment, configured with a ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-manifest",children:"Manifest"})," that defines the reference values and serves as an appraisal policy for all pods in the deployment.\nIt also pulls endorsements from hardware vendors to verify the hardware claims.\nThe Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester.\nIn RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods.\nIt collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy."]}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Deployment attestation as a composite device",src:n(54302).A+"",width:"576",height:"393"})}),"\n",(0,r.jsxs)(t.p,{children:["Figure 3: Contrast deployment as a composite device. Based on the composite device in ",(0,r.jsx)(t.a,{href:"https://www.rfc-editor.org/rfc/rfc9334.html#figure-4",children:"RFC 9334"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/components/#the-cli-command-line-interface",children:"CLI"})," serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors.\nThese reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds."]}),"\n",(0,r.jsx)(t.h3,{id:"relying-party-data-owner",children:"Relying Party: Data owner"}),"\n",(0,r.jsxs)(t.p,{children:["A relying party in the Contrast scenario could be, for example, the ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"data owner"})," that interacts with the application.\nThe relying party can use the CLI to obtain the attestation results and Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates",children:"CA certificates"})," bound to these results.\nThe CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections."]}),"\n",(0,r.jsx)(t.h2,{id:"evidence-generation-and-appraisal",children:"Evidence generation and appraisal"}),"\n",(0,r.jsx)(t.h3,{id:"evidence-types-and-formats",children:"Evidence types and formats"}),"\n",(0,r.jsx)(t.p,{children:"In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The hardware attestation report"}),": This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The launch measurements"}),": Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The runtime policy hash"}),": Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"appraisal-policies-for-evidence",children:"Appraisal policies for evidence"}),"\n",(0,r.jsx)(t.p,{children:"The appraisal of this evidence in Contrast is governed by two main components:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The Manifest"}),": A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.strong,{children:"The CLI's appraisal policy"}),": This policy encompasses expected values of the Coordinator\u2019s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"frequently-asked-questions-about-attestation-in-contrast",children:"Frequently asked questions about attestation in Contrast"}),"\n",(0,r.jsx)(t.h3,{id:"whats-the-purpose-of-remote-attestation-in-contrast",children:"What's the purpose of remote attestation in Contrast?"}),"\n",(0,r.jsx)(t.p,{children:"Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment.\nThis process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment.\nBy validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with."}),"\n",(0,r.jsx)(t.h3,{id:"how-does-contrast-ensure-the-security-of-the-attestation-process",children:"How does Contrast ensure the security of the attestation process?"}),"\n",(0,r.jsx)(t.p,{children:"Contrast leverages hardware-rooted security features such as AMD SEV-SNP to generate cryptographic evidence of a pod\u2019s current state and configuration.\nThis evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment."}),"\n",(0,r.jsx)(t.h3,{id:"what-security-benefits-does-attestation-provide",children:"What security benefits does attestation provide?"}),"\n",(0,r.jsxs)(t.p,{children:["Attestation confirms the integrity of the runtime environment and the identity of the workloads.\nIt plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime.\nThe attestation provides integrity and authenticity guarantees, enabling relying parties\u2014such as workload operators or data owners\u2014to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators.\nMore details on the specific security benefits can be found ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-you-verify-the-authenticity-of-attestation-results",children:"How can you verify the authenticity of attestation results?"}),"\n",(0,r.jsx)(t.p,{children:"Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself.\nThese proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering.\nFor further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code."}),"\n",(0,r.jsx)(t.h3,{id:"how-are-attestation-results-used-by-relying-parties",children:"How are attestation results used by relying parties?"}),"\n",(0,r.jsxs)(t.p,{children:["Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity.\nThereafter, the use of Contrast's ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/architecture/certificates",children:"CA certificates in TLS connections"})," provides a practical approach to communicate securely with the application."]}),"\n",(0,r.jsx)(t.h2,{id:"summary",children:"Summary"}),"\n",(0,r.jsx)(t.p,{children:"In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy.\nThis comprehensive approach allows Contrast to provide a high level of security assurance to its users."})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},54302:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-composite-device-b91e917a07f0f2bb082989317a9b053f.svg"},83451:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-pod-af4fc34dd97b1fdc20f66ecfa4fdeb1a.svg"},45890:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/attestation-rats-architecture-1a05fc2165e5c75a171e7b7832186bc3.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e277c26a.364edfbf.js b/pr-preview/pr-976/assets/js/e277c26a.364edfbf.js new file mode 100644 index 0000000000..82c768aa46 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e277c26a.364edfbf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1632],{78335:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-0.7/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/architecture/certificates.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/attestation"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/observability"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(46241).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},46241:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e2b3b970.151dea1f.js b/pr-preview/pr-976/assets/js/e2b3b970.151dea1f.js new file mode 100644 index 0000000000..0dbe324063 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e2b3b970.151dea1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2841],{6428:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"features-limitations","title":"Planned features and limitations","description":"This section lists planned features and current limitations of Contrast.","source":"@site/versioned_docs/version-0.7/features-limitations.md","sourceDirName":".","slug":"/features-limitations","permalink":"/contrast/pr-preview/pr-976/0.7/features-limitations","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/features-limitations.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.7/architecture/observability"},"next":{"title":"About","permalink":"/contrast/pr-preview/pr-976/0.7/about/"}}');var s=t(74848),r=t(28453);const o={},a="Planned features and limitations",l={},c=[{value:"Availability",id:"availability",level:2},{value:"Kubernetes features",id:"kubernetes-features",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"Tooling integration",id:"tooling-integration",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"planned-features-and-limitations",children:"Planned features and limitations"})}),"\n",(0,s.jsx)(n.p,{children:"This section lists planned features and current limitations of Contrast."}),"\n",(0,s.jsx)(n.h2,{id:"availability",children:"Availability"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Platform support"}),": At present, Contrast is exclusively available on Azure AKS, supported by the ",(0,s.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"Confidential Container preview for AKS"}),". Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Bare-metal support"}),": Support for running Contrast on bare-metal Kubernetes will be available soon for AMD SEV and Intel TDX."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"kubernetes-features",children:"Kubernetes features"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Persistent volumes"}),": Not currently supported within Confidential Containers."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Port forwarding"}),": This feature ",(0,s.jsx)(n.a,{href:"https://github.com/kata-containers/kata-containers/issues/1693",children:"isn't yet supported by Kata Containers"}),". You can ",(0,s.jsx)(n.a,{href:"https://docs.edgeless.systems/contrast/deployment#connect-to-the-contrast-coordinator",children:"deploy a port-forwarder"})," as a workaround."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Resource limits"}),": There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Coverage"}),": While the enforcement of workload policies generally functions well, ",(0,s.jsx)(n.a,{href:"https://github.com/microsoft/kata-containers/releases/tag/3.2.0.azl0.genpolicy",children:"there are scenarios not yet fully covered"}),". It's crucial to review deployments specifically for these edge cases."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Order of events"}),": The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh sidecar"})," container runs ",(0,s.jsx)(n.em,{children:"before"})," the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Absence of events"}),": Policies can't ensure certain events have happened. A container, such as the ",(0,s.jsx)(n.a,{href:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",children:"service mesh sidecar"}),", can be omitted entirely. Environment variables may be missing."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Volume integrity checks"}),": While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ",(0,s.jsx)(n.code,{children:"ConfigMaps"})," and ",(0,s.jsx)(n.code,{children:"Secrets"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsx)(n.p,{children:"The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly."})}),"\n",(0,s.jsx)(n.h2,{id:"tooling-integration",children:"Tooling integration"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"CLI availability"}),": The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var i=t(96540);const s={},r=i.createContext(s);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e446d98f.5906d2b8.js b/pr-preview/pr-976/assets/js/e446d98f.5906d2b8.js new file mode 100644 index 0000000000..2eb4330280 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e446d98f.5906d2b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[221],{43008:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>a,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>o,toc:()=>p});const o=JSON.parse('{"id":"architecture/components/coordinator","title":"coordinator","description":"","source":"@site/versioned_docs/version-0.5/architecture/components/coordinator.md","sourceDirName":"architecture/components","slug":"/architecture/components/coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/architecture/components/coordinator.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Components","permalink":"/contrast/pr-preview/pr-976/0.5/category/components"},"next":{"title":"Init container","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container"}}');var r=n(74848),c=n(28453);const s={},i=void 0,a={},p=[];function d(t){return(0,r.jsx)(r.Fragment,{})}function u(t={}){const{wrapper:e}={...(0,c.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d()}},28453:(t,e,n)=>{n.d(e,{R:()=>s,x:()=>i});var o=n(96540);const r={},c=o.createContext(r);function s(t){const e=o.useContext(c);return o.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:s(t.components),o.createElement(c.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e55aefba.57f034d8.js b/pr-preview/pr-976/assets/js/e55aefba.57f034d8.js new file mode 100644 index 0000000000..1c3a9bd3c3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e55aefba.57f034d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[4113],{69732:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"basics/confidential-containers","title":"Confidential Containers","description":"Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level.","source":"@site/versioned_docs/version-0.9/basics/confidential-containers.md","sourceDirName":"basics","slug":"/basics/confidential-containers","permalink":"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/basics/confidential-containers.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"What is Contrast?","permalink":"/contrast/pr-preview/pr-976/0.9/"},"next":{"title":"Security benefits","permalink":"/contrast/pr-preview/pr-976/0.9/basics/security-benefits"}}');var i=t(74848),o=t(28453);const r={},a="Confidential Containers",c={},d=[{value:"Kubernetes RuntimeClass",id:"kubernetes-runtimeclass",level:2},{value:"Kata Containers",id:"kata-containers",level:2},{value:"AKS CoCo preview",id:"aks-coco-preview",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"confidential-containers",children:"Confidential Containers"})}),"\n",(0,i.jsxs)(n.p,{children:["Contrast uses some building blocks from ",(0,i.jsx)(n.a,{href:"https://confidentialcontainers.org",children:"Confidential Containers"})," (CoCo), a ",(0,i.jsx)(n.a,{href:"https://www.cncf.io/projects/confidential-containers/",children:"CNCF Sandbox project"})," that aims to standardize confidential computing at the pod level.\nThe project is under active development and many of the high-level features are still in flux.\nContrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime."]}),"\n",(0,i.jsx)(n.h2,{id:"kubernetes-runtimeclass",children:"Kubernetes RuntimeClass"}),"\n",(0,i.jsxs)(n.p,{children:["Kubernetes can be extended to use more than one container runtime with ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:(0,i.jsx)(n.code,{children:"RuntimeClass"})})," objects.\nThe ",(0,i.jsx)(n.a,{href:"https://kubernetes.io/docs/concepts/architecture/cri/",children:"Container Runtime Interface"})," (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate ",(0,i.jsx)(n.code,{children:"RuntimeClass"}),".\n",(0,i.jsx)(n.code,{children:"RuntimeClass"})," implementations are usually based on an ",(0,i.jsx)(n.a,{href:"https://github.com/opencontainers/runtime-spec",children:"OCI runtime"}),", such as ",(0,i.jsx)(n.code,{children:"runc"}),", ",(0,i.jsx)(n.code,{children:"runsc"})," or ",(0,i.jsx)(n.code,{children:"crun"}),".\nIn CoCo's case, the runtime is Kata Containers with added confidential computing capabilities."]}),"\n",(0,i.jsx)(n.h2,{id:"kata-containers",children:"Kata Containers"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://katacontainers.io/",children:"Kata Containers"})," is an OCI runtime that runs pods in VMs.\nThe pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host.\nThere are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs.\nUsing local VMs requires either bare-metal servers or VMs with support for nested virtualization.\nLocal VMs communicate with the host over a virtual socket.\nFor remote VMs, host-to-agent communication is tunnelled through the cloud provider's network."]}),"\n",(0,i.jsxs)(n.p,{children:["Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure.\nIn confidential mode, the guest agent is configured with an ",(0,i.jsx)(n.a,{href:"https://www.openpolicyagent.org/",children:"Open Policy Agent"})," (OPA) policy to authorize API calls from the host.\nThis policy also contains checksums for the expected container images.\nIt's derived from Kubernetes resource definitions and its checksum is included in the attestation report."]}),"\n",(0,i.jsx)(n.h2,{id:"aks-coco-preview",children:"AKS CoCo preview"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/",children:"Azure Kubernetes Service"})," (AKS) provides CoCo-enabled node pools as a ",(0,i.jsx)(n.a,{href:"https://learn.microsoft.com/en-us/azure/aks/confidential-containers-overview",children:"preview offering"}),".\nThese node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed.\nContrast can be deployed directly into a CoCo-enabled AKS cluster."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var s=t(96540);const i={},o=s.createContext(i);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e8480491.72a2b553.js b/pr-preview/pr-976/assets/js/e8480491.72a2b553.js new file mode 100644 index 0000000000..74dbd042f4 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e8480491.72a2b553.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1362],{14920:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-1.0/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/architecture/certificates.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/secrets"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/observability"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(63063).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},63063:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/e9dbdd13.305d71e2.js b/pr-preview/pr-976/assets/js/e9dbdd13.305d71e2.js new file mode 100644 index 0000000000..44623b6f41 --- /dev/null +++ b/pr-preview/pr-976/assets/js/e9dbdd13.305d71e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1647],{35121:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"troubleshooting","title":"Troubleshooting","description":"This section contains information on how to debug your Contrast deployment.","source":"@site/versioned_docs/version-1.1/troubleshooting.md","sourceDirName":".","slug":"/troubleshooting","permalink":"/contrast/pr-preview/pr-976/troubleshooting","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/troubleshooting.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/deployment"},"next":{"title":"Overview","permalink":"/contrast/pr-preview/pr-976/components/overview"}}');var i=t(74848),s=t(28453);const a={},r="Troubleshooting",c={},l=[{value:"Logging",id:"logging",level:2},{value:"CLI",id:"cli",level:3},{value:"Coordinator and Initializer",id:"coordinator-and-initializer",level:3},{value:"Pod fails to start",id:"pod-fails-to-start",level:2},{value:"Regenerating the policies",id:"regenerating-the-policies",level:3},{value:"Pin container images",id:"pin-container-images",level:3},{value:"Validate Contrast components match",id:"validate-contrast-components-match",level:3}];function d(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"troubleshooting",children:"Troubleshooting"})}),"\n",(0,i.jsx)(n.p,{children:"This section contains information on how to debug your Contrast deployment."}),"\n",(0,i.jsx)(n.h2,{id:"logging",children:"Logging"}),"\n",(0,i.jsx)(n.p,{children:"Collecting logs can be a good first step to identify problems in your\ndeployment. Both the CLI and the Contrast Coordinator as well as the Initializer\ncan be configured to emit additional logs."}),"\n",(0,i.jsx)(n.h3,{id:"cli",children:"CLI"}),"\n",(0,i.jsxs)(n.p,{children:["The CLI logs can be configured with the ",(0,i.jsx)(n.code,{children:"--log-level"})," command-line flag, which\ncan be set to either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"})," or ",(0,i.jsx)(n.code,{children:"error"}),". The default is ",(0,i.jsx)(n.code,{children:"info"}),".\nSetting this to ",(0,i.jsx)(n.code,{children:"debug"})," can get more fine-grained information as to where the\nproblem lies."]}),"\n",(0,i.jsx)(n.h3,{id:"coordinator-and-initializer",children:"Coordinator and Initializer"}),"\n",(0,i.jsxs)(n.p,{children:["The logs from the Coordinator and the Initializer can be configured via the\nenvironment variables ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"}),", ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," and\n",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_LEVEL"})," can be set to one of either ",(0,i.jsx)(n.code,{children:"debug"}),", ",(0,i.jsx)(n.code,{children:"info"}),", ",(0,i.jsx)(n.code,{children:"warn"}),", or\n",(0,i.jsx)(n.code,{children:"error"}),", similar to the CLI (defaults to ",(0,i.jsx)(n.code,{children:"info"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_FORMAT"})," can be set to ",(0,i.jsx)(n.code,{children:"text"})," or ",(0,i.jsx)(n.code,{children:"json"}),", determining the output\nformat (defaults to ",(0,i.jsx)(n.code,{children:"text"}),")."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," is a comma-seperated list of subsystems that should\nbe enabled for logging, which are disabled by default. Subsystems include:\n",(0,i.jsx)(n.code,{children:"kds-getter"}),", ",(0,i.jsx)(n.code,{children:"issuer"})," and ",(0,i.jsx)(n.code,{children:"validator"}),".\nTo enable all subsystems, use ",(0,i.jsx)(n.code,{children:"*"})," as the value for this environment variable.\nWarnings and error messages from subsystems get printed regardless of whether\nthe subsystem is listed in the ",(0,i.jsx)(n.code,{children:"CONTRAST_LOG_SUBSYSTEMS"})," environment variable."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"To configure debug logging with all subsystems for your Coordinator, add the\nfollowing variables to your container definition."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:'spec: # v1.PodSpec\n containers:\n image: "ghcr.io/edgelesssys/contrast/coordinator:v1.1.0@sha256:9147d7a83021cd11848c6bf28bb8a58652e28ac43be946bfe3996a2d020dbc57"\n name: coordinator\n env:\n - name: CONTRAST_LOG_LEVEL\n value: debug\n - name: CONTRAST_LOG_SUBSYSTEMS\n value: "*"\n # ...\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["While the Contrast Coordinator has a policy that allows certain configurations,\nthe Initializer and service mesh don't. When changing environment variables of other\nparts than the Coordinator, ensure to rerun ",(0,i.jsx)(n.code,{children:"contrast generate"})," to update the policy."]})}),"\n",(0,i.jsxs)(n.p,{children:["To access the logs generated by the Coordinator, you can use ",(0,i.jsx)(n.code,{children:"kubectl"})," with the\nfollowing command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl logs <coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.h2,{id:"pod-fails-to-start",children:"Pod fails to start"}),"\n",(0,i.jsxs)(n.p,{children:["If the Coordinator or a workload pod fails to even start, it can be helpful to\nlook at the events of the pod during the startup process using the ",(0,i.jsx)(n.code,{children:"describe"}),"\ncommand."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> events --for pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"Example output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:'LAST SEEN TYPE REASON OBJECT MESSAGE\n32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...\n'})}),"\n",(0,i.jsx)(n.p,{children:"A common error, as in this example, is that the container creation was blocked by the\npolicy. Potential reasons are a modification of the deployment YAML without updating\nthe policies afterward, or a version mismatch between Contrast components."}),"\n",(0,i.jsx)(n.h3,{id:"regenerating-the-policies",children:"Regenerating the policies"}),"\n",(0,i.jsx)(n.p,{children:"To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated\npolicies, rerun"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast generate\n"})}),"\n",(0,i.jsx)(n.p,{children:"on your deployment. If any of the policy annotations change, re-deploy with the updated policies."}),"\n",(0,i.jsx)(n.h3,{id:"pin-container-images",children:"Pin container images"}),"\n",(0,i.jsx)(n.p,{children:"When generating the policies, Contrast will download the images specified in your deployment\nYAML and include their cryptographic identity. If the image tag is moved to another\ncontainer image after the policy has been generated, the image downloaded at deploy time\nwill differ from the one at generation time, and the policy enforcement won't allow the\ncontainer to be started in the pod VM."}),"\n",(0,i.jsxs)(n.p,{children:["To ensure the correct image is always used, pin the container image to a fixed ",(0,i.jsx)(n.code,{children:"sha256"}),":"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-yaml",children:"image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This way, the same image will still be pulled when the container tag (",(0,i.jsx)(n.code,{children:"22.04"}),") is moved\nto another image."]}),"\n",(0,i.jsx)(n.h3,{id:"validate-contrast-components-match",children:"Validate Contrast components match"}),"\n",(0,i.jsx)(n.p,{children:"A version mismatch between Contrast components can cause policy validation or attestation\nto fail. Each Contrast runtime is identifiable based on its (shortened) measurement value\nused to name the runtime class version."}),"\n",(0,i.jsx)(n.p,{children:"First, analyze which runtime class is currently installed in your cluster by running"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl get runtimeclasses\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should give you output similar to the following one."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"NAME HANDLER AGE\ncontrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h\nkata-cc-isolation kata-cc 45d\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided\nby the AKS CoCo preview, which isn't used by Contrast)."}),"\n",(0,i.jsx)(n.p,{children:"Next, check if the pod that won't start has the correct runtime class configured, and the\nCoordinator uses the exact same runtime:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>\nkubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>\n"})}),"\n",(0,i.jsx)(n.p,{children:"The output should list the runtime class the pod is using:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast-cc-aks-clh-snp-7173acb5\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Version information about the currently used CLI can be obtained via the ",(0,i.jsx)(n.code,{children:"version"})," flag:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast --version\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-sh",children:"contrast version v0.X.0\n\n runtime handler: contrast-cc-aks-clh-snp-7173acb5\n launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35\n genpolicy version: 3.2.0.azl1.genpolicy0\n image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...\n ghcr.io/edgelesssys/contrast/initializer@sha256:...\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var o=t(96540);const i={},s=o.createContext(i);function a(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/edcfcef8.efca5aef.js b/pr-preview/pr-976/assets/js/edcfcef8.efca5aef.js new file mode 100644 index 0000000000..a3239703e1 --- /dev/null +++ b/pr-preview/pr-976/assets/js/edcfcef8.efca5aef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3133],{81779:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>l});const i=JSON.parse('{"id":"components/overview","title":"Components","description":"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.","source":"@site/versioned_docs/version-1.1/components/overview.md","sourceDirName":"components","slug":"/components/overview","permalink":"/contrast/pr-preview/pr-976/components/overview","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/components/overview.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Troubleshooting","permalink":"/contrast/pr-preview/pr-976/troubleshooting"},"next":{"title":"Runtime","permalink":"/contrast/pr-preview/pr-976/components/runtime"}}');var o=n(74848),r=n(28453);const s={},a="Components",c={},l=[{value:"The CLI (Command Line Interface)",id:"the-cli-command-line-interface",level:2},{value:"The Coordinator",id:"the-coordinator",level:2},{value:"The Manifest",id:"the-manifest",level:2},{value:"Runtime policies",id:"runtime-policies",level:2},{value:"The Initializer",id:"the-initializer",level:2},{value:"The Contrast runtime",id:"the-contrast-runtime",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"components",children:"Components"})}),"\n",(0,o.jsx)(t.p,{children:"Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments.\nThis page provides an overview of the core components essential for deploying and managing Contrast."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"components overview",src:n(51003).A+"",width:"3387",height:"1866"})}),"\n",(0,o.jsx)(t.h2,{id:"the-cli-command-line-interface",children:"The CLI (Command Line Interface)"}),"\n",(0,o.jsx)(t.p,{children:"The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster."}),"\n",(0,o.jsx)(t.li,{children:"Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest."}),"\n",(0,o.jsx)(t.li,{children:"Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest."}),"\n",(0,o.jsx)(t.li,{children:"Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"the-coordinator",children:"The Coordinator"}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator is the central remote attestation service of a Contrast deployment.\nIt runs inside a confidential container inside your cluster.\nThe Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained.\nThe Coordinator is configured with a ",(0,o.jsx)(t.em,{children:"manifest"}),", a configuration file containing the reference attestation values of your deployment.\nIt ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment.\nThe Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure.\nYour workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA.\nAs your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment."]}),"\n",(0,o.jsx)(t.p,{children:"To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment.\nA third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity."}),"\n",(0,o.jsx)(t.h2,{id:"the-manifest",children:"The Manifest"}),"\n",(0,o.jsx)(t.p,{children:"The manifest is the configuration file for the Coordinator, defining your confidential deployment.\nIt's automatically generated from your deployment by the Contrast CLI.\nIt currently consists of the following parts:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Policies"}),": The identities of your Pods, represented by the hashes of their respective runtime policies."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"Reference Values"}),": The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.em,{children:"WorkloadOwnerKeyDigest"}),": The workload owner's public key digest. Used for authenticating subsequent manifest updates."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"runtime-policies",children:"Runtime policies"}),"\n",(0,o.jsx)(t.p,{children:"Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers.\nThey allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files.\nThe runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA.\nThe Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests.\nThe Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA."}),"\n",(0,o.jsx)(t.h2,{id:"the-initializer",children:"The Initializer"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast provides an Initializer that handles the remote attestation on the workload side transparently and\nfetches the workload certificate. The Initializer runs as an init container before your workload is started.\nIt provides the workload container and the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/components/service-mesh",children:"service mesh sidecar"})," with the workload certificates."]}),"\n",(0,o.jsx)(t.h2,{id:"the-contrast-runtime",children:"The Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a Kubernetes ",(0,o.jsx)(t.a,{href:"https://kubernetes.io/docs/concepts/containers/runtime-class/",children:"runtime class"}),", which is installed\nby the ",(0,o.jsx)(t.code,{children:"node-installer"})," DaemonSet.\nThis runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS).\nThe installer takes care of provisioning every node in the cluster so it provides this runtime class."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},51003:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/components-ea3fb9800d5718d6ab96607ee817c104.svg"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>a});var i=n(96540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/ee8b52db.b69e4030.js b/pr-preview/pr-976/assets/js/ee8b52db.b69e4030.js new file mode 100644 index 0000000000..4838b41df5 --- /dev/null +++ b/pr-preview/pr-976/assets/js/ee8b52db.b69e4030.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[5316],{51076:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>u});const n=JSON.parse('{"id":"basics/security-benefits","title":"security-benefits","description":"","source":"@site/versioned_docs/version-0.5/basics/security-benefits.md","sourceDirName":"basics","slug":"/basics/security-benefits","permalink":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/basics/security-benefits.md","tags":[],"version":"0.5","frontMatter":{},"sidebar":"docs","previous":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers"},"next":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/0.5/basics/features"}}');var r=s(74848),i=s(28453);const o={},c=void 0,a={},u=[];function d(e){return(0,r.jsx)(r.Fragment,{})}function p(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d()}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var n=s(96540);const r={},i=n.createContext(r);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f2348f57.3db099bc.js b/pr-preview/pr-976/assets/js/f2348f57.3db099bc.js new file mode 100644 index 0000000000..ca2ea4babf --- /dev/null +++ b/pr-preview/pr-976/assets/js/f2348f57.3db099bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8772],{74153:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","source":"@site/versioned_docs/version-1.1/architecture/secrets.md","sourceDirName":"architecture","slug":"/architecture/secrets","permalink":"/contrast/pr-preview/pr-976/architecture/secrets","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.1/architecture/secrets.md","tags":[],"version":"1.1","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/architecture/attestation"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/architecture/certificates"}}');var n=r(74848),i=r(28453);const o={},a="Secrets & recovery",d={},c=[{value:"Persistence",id:"persistence",level:2},{value:"Recovery",id:"recovery",level:2},{value:"Workload Secrets",id:"workload-secrets",level:2}];function h(e){const t={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"secrets--recovery",children:"Secrets & recovery"})}),"\n",(0,n.jsx)(t.p,{children:"When the Coordinator is configured with the initial manifest, it generates a random secret seed.\nFrom this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history.\nThis derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state."}),"\n",(0,n.jsxs)(t.p,{children:["The secret seed is returned to the user on the first call to ",(0,n.jsx)(t.code,{children:"contrast set"}),", encrypted with the user's public seed share owner key.\nIf no seed share owner key is provided, a key is generated and stored in the working directory."]}),"\n",(0,n.jsx)(t.h2,{id:"persistence",children:"Persistence"}),"\n",(0,n.jsxs)(t.p,{children:["The Coordinator runs as a ",(0,n.jsx)(t.code,{children:"StatefulSet"})," with a dynamically provisioned persistent volume.\nThis volume stores the manifest history and the associated runtime policies.\nThe manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads.\nHowever, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users.\nThus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed."]}),"\n",(0,n.jsx)(t.h2,{id:"recovery",children:"Recovery"}),"\n",(0,n.jsxs)(t.p,{children:["When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests.\nIt needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures.\nThis procedure is called recovery and is initiated by the workload owner.\nThe CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the ",(0,n.jsx)(t.code,{children:"Recover"})," method.\nThe Coordinator recovers its key material and verifies the manifest history signature."]}),"\n",(0,n.jsx)(t.h2,{id:"workload-secrets",children:"Workload Secrets"}),"\n",(0,n.jsxs)(t.p,{children:["The Coordinator provides each workload a secret seed during attestation. This secret can be used by the workload to derive additional secrets for example to\nencrypt persistent data. Like the workload certificates it's mounted in the shared Kubernetes volume ",(0,n.jsx)(t.code,{children:"contrast-secrets"})," in the path ",(0,n.jsx)(t.code,{children:"<mountpoint>/secrets/workload-secret-seed"}),"."]}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsx)(t.p,{children:"The workload owner can decrypt data encrypted with secrets derived from the workload secret.\nThe workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner.\nIf the data owner and the workload owner is the same entity, then they can safely use the workload secrets."})})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var s=r(96540);const n={},i=s.createContext(n);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f31967d8.71b71235.js b/pr-preview/pr-976/assets/js/f31967d8.71b71235.js new file mode 100644 index 0000000000..588eed8fc3 --- /dev/null +++ b/pr-preview/pr-976/assets/js/f31967d8.71b71235.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6733],{89400:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"about/telemetry","title":"CLI telemetry","description":"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.","source":"@site/versioned_docs/version-0.7/about/telemetry.md","sourceDirName":"about","slug":"/about/telemetry","permalink":"/contrast/pr-preview/pr-976/0.7/about/telemetry","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.7/about/telemetry.md","tags":[],"version":"0.7","frontMatter":{},"sidebar":"docs","previous":{"title":"About","permalink":"/contrast/pr-preview/pr-976/0.7/about/"}}');var r=s(74848),o=s(28453);const i={},a="CLI telemetry",c={},d=[];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"cli-telemetry",children:"CLI telemetry"})}),"\n",(0,r.jsx)(t.p,{children:"The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands.\nThis allows to understand how Contrast is used and to improve it."}),"\n",(0,r.jsx)(t.p,{children:"The CLI sends the following data:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"The CLI version"}),"\n",(0,r.jsx)(t.li,{children:"The CLI target OS and architecture (GOOS and GOARCH)"}),"\n",(0,r.jsx)(t.li,{children:"The command that was run"}),"\n",(0,r.jsx)(t.li,{children:"The kind of error that occurred (if any)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The CLI ",(0,r.jsx)(t.em,{children:"doesn't"})," collect sensitive information.\nThe implementation is open-source and can be reviewed."]}),"\n",(0,r.jsx)(t.p,{children:"IP addresses may be processed or stored for security purposes."}),"\n",(0,r.jsxs)(t.p,{children:["The data that the CLI collects adheres to the Edgeless Systems ",(0,r.jsx)(t.a,{href:"https://www.edgeless.systems/privacy",children:"privacy policy"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["You can disable telemetry by setting the environment variable ",(0,r.jsx)(t.code,{children:"DO_NOT_TRACK=1"})," before running the CLI."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>a});var n=s(96540);const r={},o=n.createContext(r);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f36abd57.48e08f44.js b/pr-preview/pr-976/assets/js/f36abd57.48e08f44.js new file mode 100644 index 0000000000..5a510560d2 --- /dev/null +++ b/pr-preview/pr-976/assets/js/f36abd57.48e08f44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6711],{8624:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>i});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-0.9/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/getting-started/cluster-setup.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.9/getting-started/install"},"next":{"title":"Confidential emoji voting","permalink":"/contrast/pr-preview/pr-976/0.9/examples/emojivoto"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which needs\nto have the permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First, we need to create an AKS cluster. We can't directly create a CoCo-enabled cluster, so we'll need to create a\nnon-CoCo cluster first, and then add a CoCo node pool, optionally replacing the non-CoCo node pool."}),"\n",(0,t.jsx)(n.p,{children:"We'll first start by creating the non-CoCo cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "${azResourceGroup:?}" \\\n --name nodepool2 \\\n --cluster-name "${azClusterName:?}" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Optionally, we can now remove the non-CoCo node pool:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool delete \\\n --resource-group "${azResourceGroup:?}" \\\n --cluster-name "${azClusterName:?}" \\\n --name nodepool1\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f47dd6e5.ecf0ed95.js b/pr-preview/pr-976/assets/js/f47dd6e5.ecf0ed95.js new file mode 100644 index 0000000000..5cb53e322b --- /dev/null +++ b/pr-preview/pr-976/assets/js/f47dd6e5.ecf0ed95.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[6408],{99851:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-0.5/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/0.5/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.5/intro.md","tags":[],"version":"0.5","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.5/getting-started/",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f5272de0.78413199.js b/pr-preview/pr-976/assets/js/f5272de0.78413199.js new file mode 100644 index 0000000000..7b509eeaed --- /dev/null +++ b/pr-preview/pr-976/assets/js/f5272de0.78413199.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[564],{11324:t=>{t.exports=JSON.parse('{"categoryGeneratedIndex":{"title":"Certificates and Identities","slug":"/category/certificates-and-identities","permalink":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities","sidebar":"docs","navigation":{"previous":{"title":"Coordinator","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator"},"next":{"title":"PKI","permalink":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki"}}}}')}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f593d43a.93a070a0.js b/pr-preview/pr-976/assets/js/f593d43a.93a070a0.js new file mode 100644 index 0000000000..ff5e093d9b --- /dev/null +++ b/pr-preview/pr-976/assets/js/f593d43a.93a070a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1956],{60558:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});const s=JSON.parse('{"id":"intro","title":"Contrast","description":"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.","source":"@site/versioned_docs/version-0.6/intro.md","sourceDirName":".","slug":"/","permalink":"/contrast/pr-preview/pr-976/0.6/","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/intro.md","tags":[],"version":"0.6","frontMatter":{"slug":"/","id":"intro"},"sidebar":"docs","next":{"title":"Confidential Containers","permalink":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers"}}');var r=n(74848),i=n(28453);const o={slug:"/",id:"intro"},a="Contrast",c={},d=[{value:"Goal",id:"goal",level:2},{value:"Use Cases",id:"use-cases",level:2},{value:"Next steps",id:"next-steps",level:2}];function l(e){const t={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"contrast",children:"Contrast"})}),"\n",(0,r.jsx)(t.p,{children:"Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale."}),"\n",(0,r.jsxs)(t.p,{children:["Contrast is based on the ",(0,r.jsx)(t.a,{href:"https://github.com/kata-containers/kata-containers",children:"Kata Containers"})," and\n",(0,r.jsx)(t.a,{href:"https://github.com/confidential-containers",children:"Confidential Containers"})," projects.\nConfidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment.\nThis works with unmodified containers in a lift-and-shift approach.\nContrast currently targets the ",(0,r.jsx)(t.a,{href:"https://learn.microsoft.com/en-us/azure/confidential-computing/confidential-containers-on-aks-preview",children:"CoCo preview on AKS"}),"."]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["See the \ud83d\udcc4",(0,r.jsx)(t.a,{href:"https://content.edgeless.systems/hubfs/Confidential%20Computing%20Whitepaper.pdf",children:"whitepaper"})," for more information on confidential computing."]})}),"\n",(0,r.jsx)(t.h2,{id:"goal",children:"Goal"}),"\n",(0,r.jsx)(t.p,{children:"Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges."}),"\n",(0,r.jsx)(t.p,{children:"Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow."}),"\n",(0,r.jsx)(t.h2,{id:"use-cases",children:"Use Cases"}),"\n",(0,r.jsxs)(t.p,{children:["Contrast provides unique security ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/features",children:"features"})," and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"benefits"}),". The core use cases are:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Increasing the security of your containers"}),"\n",(0,r.jsx)(t.li,{children:"Moving sensitive workloads from on-prem to the cloud with Confidential Computing"}),"\n",(0,r.jsx)(t.li,{children:"Shielding the code and data even from the own cluster administrators"}),"\n",(0,r.jsx)(t.li,{children:"Increasing the trustworthiness of your SaaS offerings"}),"\n",(0,r.jsx)(t.li,{children:"Simplifying regulatory compliance"}),"\n",(0,r.jsx)(t.li,{children:"Multi-party computation for data collaboration"}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"next-steps",children:"Next steps"}),"\n",(0,r.jsxs)(t.p,{children:["You can learn more about the concept of ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",children:"Confidential Containers"}),", ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/features",children:"features"}),", and ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",children:"security benefits"})," of Contrast in this section. To jump right into the action head to ",(0,r.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/0.6/getting-started/",children:(0,r.jsx)(t.em,{children:"Getting started"})}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const r={},i=s.createContext(r);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/f65fea7a.7a92e4f1.js b/pr-preview/pr-976/assets/js/f65fea7a.7a92e4f1.js new file mode 100644 index 0000000000..74b826f848 --- /dev/null +++ b/pr-preview/pr-976/assets/js/f65fea7a.7a92e4f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2472],{27115:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});const i=JSON.parse('{"id":"examples/emojivoto","title":"Confidential emoji voting","description":"screenshot of the emojivoto UI","source":"@site/docs/examples/emojivoto.md","sourceDirName":"examples","slug":"/examples/emojivoto","permalink":"/contrast/pr-preview/pr-976/next/examples/emojivoto","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/docs/examples/emojivoto.md","tags":[],"version":"current","frontMatter":{},"sidebar":"docs","previous":{"title":"Bare metal setup","permalink":"/contrast/pr-preview/pr-976/next/getting-started/bare-metal"},"next":{"title":"Workload deployment","permalink":"/contrast/pr-preview/pr-976/next/deployment"}}');var o=n(74848),s=n(28453);const a={},r="Confidential emoji voting",l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps to deploy emojivoto with Contrast",id:"steps-to-deploy-emojivoto-with-contrast",level:2},{value:"Download the deployment files",id:"download-the-deployment-files",level:3},{value:"Deploy the Contrast runtime",id:"deploy-the-contrast-runtime",level:3},{value:"Deploy the Contrast Coordinator",id:"deploy-the-contrast-coordinator",level:3},{value:"Generate policy annotations and manifest",id:"generate-policy-annotations-and-manifest",level:3},{value:"Set the manifest",id:"set-the-manifest",level:3},{value:"Deploy emojivoto",id:"deploy-emojivoto",level:3},{value:"Verifying the deployment as a user",id:"verifying-the-deployment-as-a-user",level:2},{value:"Verifying the Coordinator",id:"verifying-the-coordinator",level:3},{value:"Auditing the manifest history and artifacts",id:"auditing-the-manifest-history-and-artifacts",level:3},{value:"Connecting securely to the application",id:"connecting-securely-to-the-application",level:3},{value:"Updating the certificate SAN and the manifest (optional)",id:"updating-the-certificate-san-and-the-manifest-optional",level:2},{value:"Configuring the service SAN in the manifest",id:"configuring-the-service-san-in-the-manifest",level:3},{value:"Updating the manifest",id:"updating-the-manifest",level:3},{value:"Rolling out the update",id:"rolling-out-the-update",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components},{TabItem:i,Tabs:a}=t;return i||p("TabItem",!0),a||p("Tabs",!0),(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"confidential-emoji-voting",children:"Confidential emoji voting"})}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{alt:"screenshot of the emojivoto UI",src:n(72866).A+"",width:"1503",height:"732"})}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsxs)(t.strong,{children:["This tutorial guides you through deploying ",(0,o.jsx)(t.a,{href:"https://github.com/BuoyantIO/emojivoto",children:"emojivoto"})," as a\nconfidential Contrast deployment and validating the deployment from a voter's perspective."]})}),"\n",(0,o.jsxs)(t.p,{children:["Emojivoto is an example app allowing users to vote for different emojis and view votes\non a leader board. It has a microservice architecture consisting of a\nweb frontend (",(0,o.jsx)(t.code,{children:"web"}),"), a gRPC backend for listing available emojis (",(0,o.jsx)(t.code,{children:"emoji"}),"), and a backend for\nthe voting and leader board logic (",(0,o.jsx)(t.code,{children:"voting"}),"). The ",(0,o.jsx)(t.code,{children:"vote-bot"})," simulates user traffic by submitting\nvotes to the frontend."]}),"\n",(0,o.jsx)(t.p,{children:"Emojivoto can be seen as a lighthearted example of an app dealing with sensitive data.\nContrast protects emojivoto in two ways. First, it shields emojivoto as a whole from the infrastructure, for example, Azure.\nSecond, it can be configured to also prevent data access even from the administrator of the app. In the case of emojivoto, this gives assurance to users that their votes remain secret."}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:"https://raw.githubusercontent.com/BuoyantIO/emojivoto/e490d5789086e75933a474b22f9723fbfa0b29ba/assets/emojivoto-topology.png",alt:"emojivoto components topology"})}),"\n",(0,o.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Installed Contrast CLI"}),"\n",(0,o.jsxs)(t.li,{children:["A running Kubernetes cluster with support for confidential containers, either on ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup",children:"AKS"})," or on ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/getting-started/bare-metal",children:"bare metal"}),"."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"steps-to-deploy-emojivoto-with-contrast",children:"Steps to deploy emojivoto with Contrast"}),"\n",(0,o.jsx)(t.h3,{id:"download-the-deployment-files",children:"Download the deployment files"}),"\n",(0,o.jsx)(t.p,{children:"The emojivoto deployment files are part of the Contrast release. You can download them by running:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"curl -fLO https://github.com/edgelesssys/contrast/releases/latest/download/emojivoto-demo.yml --create-dirs --output-dir deployment\n"})}),"\n",(0,o.jsx)(t.h3,{id:"deploy-the-contrast-runtime",children:"Deploy the Contrast runtime"}),"\n",(0,o.jsxs)(t.p,{children:["Contrast depends on a ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/runtime",children:"custom Kubernetes RuntimeClass"}),",\nwhich needs to be installed to the cluster initially.\nThis consists of a ",(0,o.jsx)(t.code,{children:"RuntimeClass"})," resource and a ",(0,o.jsx)(t.code,{children:"DaemonSet"})," that performs installation on worker nodes.\nThis step is only required once for each version of the runtime.\nIt can be shared between Contrast deployments."]}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-aks-clh-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-k3s-qemu-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-the-contrast-coordinator",children:"Deploy the Contrast Coordinator"}),"\n",(0,o.jsx)(t.p,{children:"Deploy the Contrast Coordinator, comprising a single replica deployment and a\nLoadBalancer service, into your cluster:"}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-aks-clh-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-k3s-qemu-snp.yml\n"})})}),(0,o.jsx)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-k3s-qemu-tdx.yml\n"})})})]}),"\n",(0,o.jsx)(t.h3,{id:"generate-policy-annotations-and-manifest",children:"Generate policy annotations and manifest"}),"\n",(0,o.jsxs)(t.p,{children:["Run the ",(0,o.jsx)(t.code,{children:"generate"})," command to generate the execution policies and add them as\nannotations to your deployment files. A ",(0,o.jsx)(t.code,{children:"manifest.json"})," file with the reference values\nof your deployment will be created:"]}),"\n",(0,o.jsxs)(a,{queryString:"platform",children:[(0,o.jsx)(i,{value:"aks-clh-snp",label:"AKS",default:!0,children:(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values aks-clh-snp deployment/\n"})})}),(0,o.jsxs)(i,{value:"k3s-qemu-snp",label:"Bare metal (SEV-SNP)",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-snp deployment/\n"})}),(0,o.jsx)(t.admonition,{title:"Missing TCB values",type:"note",children:(0,o.jsxs)(t.p,{children:["On bare-metal SEV-SNP, ",(0,o.jsx)(t.code,{children:"contrast generate"})," is unable to fill in the ",(0,o.jsx)(t.code,{children:"MinimumTCB"})," values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,o.jsx)(t.code,{children:'{"BootloaderVersion":255,"TEEVersion":255,"SNPVersion":255,"MicrocodeVersion":255}'})," and observe the real values in the error messages in the following steps. This should only be done in a secure environment. Note that the values will differ between CPU models."]})})]}),(0,o.jsxs)(i,{value:"k3s-qemu-tdx",label:"Bare metal (TDX)",children:[(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"contrast generate --reference-values k3s-qemu-tdx deployment/\n"})}),(0,o.jsx)(t.admonition,{title:"Missing TCB values",type:"note",children:(0,o.jsxs)(t.p,{children:["On bare-metal TDX, ",(0,o.jsx)(t.code,{children:"contrast generate"})," is unable to fill in the ",(0,o.jsx)(t.code,{children:"MinimumTeeTcbSvn"})," and ",(0,o.jsx)(t.code,{children:"MrSeam"})," TCB values as they can vary between platforms.\nThey will have to be filled in manually.\nIf you don't know the correct values use ",(0,o.jsx)(t.code,{children:"ffffffffffffffffffffffffffffffff"})," and ",(0,o.jsx)(t.code,{children:"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"})," respectively and observe the real values in the error messages in the following steps. This should only be done in a secure environment."]})})]})]}),"\n",(0,o.jsxs)(t.admonition,{title:"Runtime class and Initializer",type:"note",children:[(0,o.jsxs)(t.p,{children:["The deployment YAML shipped for this demo is already configured to be used with Contrast.\nA ",(0,o.jsx)(t.a,{href:"https://docs.edgeless.systems/contrast/components/runtime",children:"runtime class"})," ",(0,o.jsx)(t.code,{children:"contrast-cc-<platform>-<runtime-hash>"}),"\nwas added to the pods to signal they should be run as Confidential Containers. During the generation process,\nthe Contrast ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/overview#the-initializer",children:"Initializer"})," will be added as an init container to these\nworkloads to facilitate the attestation and certificate pulling before the actual workload is started."]}),(0,o.jsxs)(t.p,{children:["Further, the deployment YAML is also configured with the Contrast ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/service-mesh",children:"service mesh"}),".\nThe configured service mesh proxy provides transparent protection for the communication between\nthe different components of emojivoto."]})]}),"\n",(0,o.jsx)(t.h3,{id:"set-the-manifest",children:"Set the manifest"}),"\n",(0,o.jsx)(t.p,{children:"Configure the coordinator with a manifest. It might take up to a few minutes\nfor the load balancer to be created and the Coordinator being available."}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'coordinator=$(kubectl get svc coordinator -o=jsonpath=\'{.status.loadBalancer.ingress[0].ip}\')\necho "The user API of your Contrast Coordinator is available at $coordinator:1313"\ncontrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,o.jsx)(t.p,{children:"The CLI will use the reference values from the manifest to attest the Coordinator deployment\nduring the TLS handshake. If the connection succeeds, it's ensured that the Coordinator\ndeployment hasn't been tampered with."}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"deploy-emojivoto",children:"Deploy emojivoto"}),"\n",(0,o.jsx)(t.p,{children:"Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload,\nwe can deploy the application:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl apply -f deployment/\n"})}),"\n",(0,o.jsx)(t.admonition,{title:"Inter-deployment communication",type:"note",children:(0,o.jsxs)(t.p,{children:["The Contrast Coordinator issues mesh certificates after successfully validating workloads.\nThese certificates can be used for secure inter-deployment communication. The Initializer\nsends an attestation report to the Coordinator, retrieves certificates and a private key in return\nand writes them to a ",(0,o.jsx)(t.code,{children:"volumeMount"}),". The service mesh sidecar is configured to use the credentials\nfrom the ",(0,o.jsx)(t.code,{children:"volumeMount"})," when communicating with other parts of the deployment over mTLS.\nThe public facing frontend for voting uses the mesh certificate without client authentication."]})}),"\n",(0,o.jsx)(t.h2,{id:"verifying-the-deployment-as-a-user",children:"Verifying the deployment as a user"}),"\n",(0,o.jsx)(t.p,{children:"In different scenarios, users of an app may want to verify its security and identity before sharing data, for example, before casting a vote.\nWith Contrast, a user only needs a single remote-attestation step to verify the deployment - regardless of the size or scale of the deployment.\nContrast is designed such that, by verifying the Coordinator, the user transitively verifies those systems the Coordinator has already verified or will verify in the future.\nSuccessful verification of the Coordinator means that the user can be sure that the given manifest will be enforced."}),"\n",(0,o.jsx)(t.h3,{id:"verifying-the-coordinator",children:"Verifying the Coordinator"}),"\n",(0,o.jsx)(t.p,{children:"A user can verify the Contrast deployment using the verify\ncommand:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'contrast verify -c "${coordinator}:1313" -m manifest.json\n'})}),"\n",(0,o.jsxs)(t.p,{children:["The CLI will verify the Coordinator via remote attestation using the reference values from a given manifest. This manifest needs\nto be communicated out of band to everyone wanting to verify the deployment, as the ",(0,o.jsx)(t.code,{children:"verify"})," command checks\nif the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds,\nthe Coordinator deployment was successfully verified to be running in the expected Confidential\nComputing environment with the expected code version. The Coordinator will then return its\nconfiguration over the established TLS channel. The CLI will store this information, namely the root\ncertificate of the mesh (",(0,o.jsx)(t.code,{children:"mesh-ca.pem"}),") and the history of manifests, into the ",(0,o.jsx)(t.code,{children:"verify/"})," directory.\nIn addition, the policies referenced in the manifest history are also written into the same directory."]}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"auditing-the-manifest-history-and-artifacts",children:"Auditing the manifest history and artifacts"}),"\n",(0,o.jsxs)(t.p,{children:["In the next step, the Coordinator configuration that was written by the ",(0,o.jsx)(t.code,{children:"verify"})," command needs to be audited.\nA potential voter should inspect the manifest and the referenced policies. They could delegate\nthis task to an entity they trust."]}),"\n",(0,o.jsx)(t.h3,{id:"connecting-securely-to-the-application",children:"Connecting securely to the application"}),"\n",(0,o.jsxs)(t.p,{children:["After ensuring the configuration of the Coordinator fits the expectation, the user can securely connect\nto the application using the Coordinator's ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"})," as a trusted CA certificate."]}),"\n",(0,o.jsx)(t.p,{children:"To access the web frontend, expose the service on a public IP address via a LoadBalancer service:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')\necho \"Frontend is available at https://$frontendIP, you can visit it in your browser.\"\n"})}),"\n",(0,o.jsxs)(t.p,{children:["Using ",(0,o.jsx)(t.code,{children:"openssl"}),", the certificate of the service can be validated with the ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"}),":"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null\n"})}),"\n",(0,o.jsx)(t.h2,{id:"updating-the-certificate-san-and-the-manifest-optional",children:"Updating the certificate SAN and the manifest (optional)"}),"\n",(0,o.jsx)(t.p,{children:"By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed\nvia load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field.\nValidation fails since the certificate contains no IP entries as a SAN.\nFor example, a connection attempt using the curl and the mesh CA certificate with throw the following error:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"$ curl --cacert ./verify/mesh-ca.pem \"https://${frontendIP}:443\"\ncurl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'\n"})}),"\n",(0,o.jsx)(t.h3,{id:"configuring-the-service-san-in-the-manifest",children:"Configuring the service SAN in the manifest"}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.code,{children:"Policies"})," section of the manifest maps policy hashes to a list of SANs. To enable certificate verification\nof the web frontend with tools like curl, edit the policy with your favorite editor and add the ",(0,o.jsx)(t.code,{children:"frontendIP"})," to\nthe list that already contains the ",(0,o.jsx)(t.code,{children:'"web"'})," DNS entry:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-diff",children:' "Policies": {\n ...\n "99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {\n "SANs": [\n "web",\n- "*"\n+ "*",\n+ "203.0.113.34"\n ],\n "WorkloadSecretID": "web"\n },\n'})}),"\n",(0,o.jsx)(t.h3,{id:"updating-the-manifest",children:"Updating the manifest"}),"\n",(0,o.jsx)(t.p,{children:"Next, set the changed manifest at the coordinator with:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'contrast set -c "${coordinator}:1313" deployment/\n'})}),"\n",(0,o.jsxs)(t.p,{children:["The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued\nafter the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain\nwon't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures\nthat parts of the deployment that received a security update won't be infected by parts of the deployment at an older\npatch level that may have been compromised. The ",(0,o.jsx)(t.code,{children:"mesh-ca.pem"})," is updated with the new CA certificate chain."]}),"\n",(0,o.jsx)(t.admonition,{type:"warning",children:(0,o.jsxs)(t.p,{children:["On bare metal, the ",(0,o.jsx)(t.a,{href:"/contrast/pr-preview/pr-976/next/components/policies#platform-differences",children:"coordinator policy hash"})," must be overwritten using ",(0,o.jsx)(t.code,{children:"--coordinator-policy-hash"}),"."]})}),"\n",(0,o.jsx)(t.h3,{id:"rolling-out-the-update",children:"Rolling out the update"}),"\n",(0,o.jsx)(t.p,{children:"The Coordinator has the new manifest set, but the different containers of the app are still\nusing the older certificate authority. The Contrast Initializer terminates after the initial attestation\nflow and won't pull new certificates on manifest updates."}),"\n",(0,o.jsx)(t.p,{children:"To roll out the update, use:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:"kubectl rollout restart deployment/emoji\nkubectl rollout restart deployment/vote-bot\nkubectl rollout restart deployment/voting\nkubectl rollout restart deployment/web\n"})}),"\n",(0,o.jsx)(t.p,{children:"After the update has been rolled out, connecting to the frontend using curl will successfully validate\nthe service certificate and return the HTML document of the voting site:"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-sh",children:'curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}function p(e,t){throw new Error("Expected "+(t?"component":"object")+" `"+e+"` to be defined: you likely forgot to import, pass, or provide it.")}},72866:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/emoijvoto-3fb48da575d6d4adf76cc90caa35d762.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const o={},s=i.createContext(o);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/fbad2ec0.afc757e3.js b/pr-preview/pr-976/assets/js/fbad2ec0.afc757e3.js new file mode 100644 index 0000000000..1404da712f --- /dev/null +++ b/pr-preview/pr-976/assets/js/fbad2ec0.afc757e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[1658],{6784:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>l});const s=JSON.parse('{"id":"getting-started/cluster-setup","title":"Create a cluster","description":"Prerequisites","source":"@site/versioned_docs/version-0.6/getting-started/cluster-setup.md","sourceDirName":"getting-started","slug":"/getting-started/cluster-setup","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.6/getting-started/cluster-setup.md","tags":[],"version":"0.6","frontMatter":{},"sidebar":"docs","previous":{"title":"Install","permalink":"/contrast/pr-preview/pr-976/0.6/getting-started/install"},"next":{"title":"Examples","permalink":"/contrast/pr-preview/pr-976/0.6/examples/"}}');var t=r(74848),a=r(28453);const o={},c="Create a cluster",i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Prepare using the AKS preview",id:"prepare-using-the-aks-preview",level:2},{value:"Create resource group",id:"create-resource-group",level:2},{value:"Create AKS cluster",id:"create-aks-cluster",level:2},{value:"Cleanup",id:"cleanup",level:2}];function u(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"create-a-cluster",children:"Create a cluster"})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.p,{children:["Install the latest version of the ",(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/",children:"Azure CLI"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.microsoft.com/en-us/cli/azure/authenticate-azure-cli",children:"Login to your account"}),", which needs\nto have the permissions to create an AKS cluster, by executing:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az login\n"})}),"\n",(0,t.jsx)(n.h2,{id:"prepare-using-the-aks-preview",children:"Prepare using the AKS preview"}),"\n",(0,t.jsxs)(n.p,{children:["CoCo on AKS is currently in preview. An extension for the ",(0,t.jsx)(n.code,{children:"az"})," CLI is needed to create such a cluster.\nAdd the extension with the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"az extension add \\\n --name aks-preview \\\n --allow-preview true\naz extension update \\\n --name aks-preview \\\n --allow-preview true\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then register the required feature flags in your subscription to allow access to the public preview:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az feature register \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The registration can take a few minutes. The status of the operation can be checked with the following\ncommand, which should show the registration state as ",(0,t.jsx)(n.code,{children:"Registered"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az feature show \\\n --namespace "Microsoft.ContainerService" \\\n --name "KataCcIsolationPreview" \\\n --output table\n'})}),"\n",(0,t.jsx)(n.p,{children:"Afterward, refresh the registration of the ContainerService provider:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az provider register \\\n --namespace "Microsoft.ContainerService"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-resource-group",children:"Create resource group"}),"\n",(0,t.jsx)(n.p,{children:"The AKS with CoCo preview is currently available in the following locations:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"CentralIndia\neastus\nEastUS2EUAP\nGermanyWestCentral\njapaneast\nnortheurope\nSwitzerlandNorth\nUAENorth\nwesteurope\nwestus\n"})}),"\n",(0,t.jsx)(n.p,{children:"Set the name of the resource group you want to use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azResourceGroup="ContrastDemo"\n'})}),"\n",(0,t.jsx)(n.p,{children:"You can either use an existing one or create a new resource group with the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'azLocation="westus" # Select a location from the list above\n\naz group create \\\n --name "${azResourceGroup:?}" \\\n --location "${azLocation:?}"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"create-aks-cluster",children:"Create AKS cluster"}),"\n",(0,t.jsx)(n.p,{children:"First create an AKS cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'# Select the name for your AKS cluster\nazClusterName="ContrastDemo"\n\naz aks create \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}" \\\n --kubernetes-version 1.29 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --node-count 1 \\\n --generate-ssh-keys\n'})}),"\n",(0,t.jsx)(n.p,{children:"We then add a second node pool with CoCo support:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks nodepool add \\\n --resource-group "${azResourceGroup:?}" \\\n --name nodepool2 \\\n --cluster-name "${azClusterName:?}" \\\n --node-count 1 \\\n --os-sku AzureLinux \\\n --node-vm-size Standard_DC4as_cc_v5 \\\n --workload-runtime KataCcIsolation\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, update your kubeconfig with the credentials to access the cluster:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'az aks get-credentials \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"For validation, list the available nodes using kubectl:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"kubectl get nodes\n"})}),"\n",(0,t.jsx)(n.p,{children:"It should show two nodes:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NAME STATUS ROLES AGE VERSION\naks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0\naks-nodepool2-32238657-vmss000000 Ready <none> 45s v1.29.0\n"})}),"\n",(0,t.jsx)(n.h2,{id:"cleanup",children:"Cleanup"}),"\n",(0,t.jsx)(n.p,{children:"After trying out Contrast, you might want to clean up the cloud resources created in this step.\nIn case you've created a new resource group, you can just delete that group with"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az group delete \\\n --name "${azResourceGroup:?}"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Deleting the resource group will also delete the cluster and all other related resources."}),"\n",(0,t.jsx)(n.p,{children:"To only cleanup the AKS cluster and node pools, run"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-sh",children:'az aks delete \\\n --resource-group "${azResourceGroup:?}" \\\n --name "${azClusterName:?}"\n'})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(u,{...e})}):u(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/fbad79f4.6e49be6a.js b/pr-preview/pr-976/assets/js/fbad79f4.6e49be6a.js new file mode 100644 index 0000000000..a728052d44 --- /dev/null +++ b/pr-preview/pr-976/assets/js/fbad79f4.6e49be6a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[2590],{98707:(t,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>n,toc:()=>c});const n=JSON.parse('{"id":"getting-started/install","title":"Installation","description":"Download the Contrast CLI from the latest release:","source":"@site/versioned_docs/version-1.0/getting-started/install.md","sourceDirName":"getting-started","slug":"/getting-started/install","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/install","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/getting-started/install.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Features","permalink":"/contrast/pr-preview/pr-976/1.0/basics/features"},"next":{"title":"Cluster setup","permalink":"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup"}}');var r=s(74848),a=s(28453);const o={},i="Installation",l={},c=[];function d(t){const e={code:"code",h1:"h1",header:"header",p:"p",pre:"pre",...(0,a.R)(),...t.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"installation",children:"Installation"})}),"\n",(0,r.jsx)(e.p,{children:"Download the Contrast CLI from the latest release:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v1.0.0/contrast\n"})}),"\n",(0,r.jsx)(e.p,{children:"After that, install the Contrast CLI in your PATH, e.g.:"}),"\n",(0,r.jsx)(e.pre,{children:(0,r.jsx)(e.code,{className:"language-bash",children:"sudo install contrast /usr/local/bin/contrast\n"})})]})}function p(t={}){const{wrapper:e}={...(0,a.R)(),...t.components};return e?(0,r.jsx)(e,{...t,children:(0,r.jsx)(d,{...t})}):d(t)}},28453:(t,e,s)=>{s.d(e,{R:()=>o,x:()=>i});var n=s(96540);const r={},a=n.createContext(r);function o(t){const e=n.useContext(a);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function i(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(r):t.components||r:o(t.components),n.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/fbcf0d59.08f1ee86.js b/pr-preview/pr-976/assets/js/fbcf0d59.08f1ee86.js new file mode 100644 index 0000000000..6a8bb3df7d --- /dev/null +++ b/pr-preview/pr-976/assets/js/fbcf0d59.08f1ee86.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[3970],{18012:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>s,metadata:()=>r,toc:()=>h});const r=JSON.parse('{"id":"architecture/certificates","title":"Certificate authority","description":"The Coordinator acts as a certificate authority (CA) for the workloads","source":"@site/versioned_docs/version-0.9/architecture/certificates.md","sourceDirName":"architecture","slug":"/architecture/certificates","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/certificates","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-0.9/architecture/certificates.md","tags":[],"version":"0.9","frontMatter":{},"sidebar":"docs","previous":{"title":"Secrets & recovery","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/secrets"},"next":{"title":"Observability","permalink":"/contrast/pr-preview/pr-976/0.9/architecture/observability"}}');var n=i(74848),a=i(28453);const s={},o="Certificate authority",c={},h=[{value:"Public key infrastructure",id:"public-key-infrastructure",level:2},{value:"Certificate rotation",id:"certificate-rotation",level:2},{value:"Usage of the different certificates",id:"usage-of-the-different-certificates",level:2}];function d(e){const t={em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"certificate-authority",children:"Certificate authority"})}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator acts as a certificate authority (CA) for the workloads\ndefined in the manifest.\nAfter a workload pod's attestation has been verified by the Coordinator,\nit receives a mesh certificate and the mesh CA certificate.\nThe mesh certificate can be used for example in a TLS connection as the server or\nclient certificate to proof to the other party that the workload has been\nverified by the Coordinator. The other party can verify the mesh certificate\nwith the mesh CA certificate. While the certificates can be used by the workload\ndeveloper in different ways, they're automatically used in Contrast's service\nmesh to establish mTLS connections between workloads in the same deployment."}),"\n",(0,n.jsx)(t.h2,{id:"public-key-infrastructure",children:"Public key infrastructure"}),"\n",(0,n.jsx)(t.p,{children:"The Coordinator establishes a public key infrastructure (PKI) for all workloads\ncontained in the manifest. The Coordinator holds three certificates: the root CA\ncertificate, the intermediate CA certificate, and the mesh CA certificate.\nThe root CA certificate is a long-lasting certificate and its private key signs\nthe intermediate CA certificate. The intermediate CA certificate and the mesh CA\ncertificate share the same private key. This intermediate private key is used\nto sign the mesh certificates. Moreover, the intermediate private key and\ntherefore the intermediate CA certificate and the mesh CA certificate are\nrotated when setting a new manifest."}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"PKI certificate chain",src:i(19979).A+""})}),"\n",(0,n.jsx)(t.h2,{id:"certificate-rotation",children:"Certificate rotation"}),"\n",(0,n.jsx)(t.p,{children:"Depending on the configuration of the first manifest, it allows the workload\nowner to update the manifest and, therefore, the deployment.\nWorkload owners and data owners can be mutually untrusted parties.\nTo protect against the workload owner silently introducing malicious containers,\nthe Coordinator rotates the intermediate private key every time the manifest is\nupdated and, therefore, the\nintermediate CA certificate and mesh CA certificate. If the user doesn't\ntrust the workload owner, they use the mesh CA certificate obtained when they\nverified the Coordinator and the manifest. This ensures that the user only\nconnects to workloads defined in the manifest they verified since only those\nworkloads' certificates are signed with this intermediate private key."}),"\n",(0,n.jsx)(t.p,{children:"Similarly, the service mesh also uses the mesh CA certificate obtained when the\nworkload was started, so the workload only trusts endpoints that have been\nverified by the Coordinator based on the same manifest. Consequently, a\nmanifest update requires a fresh rollout of the services in the service mesh."}),"\n",(0,n.jsx)(t.h2,{id:"usage-of-the-different-certificates",children:"Usage of the different certificates"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"root CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis should only be used if the data owner trusts all future updates to the\nmanifest and workloads. This is, for instance, the case when the workload owner is\nthe same entity as the data owner."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh CA certificate"})," is returned when verifying the Coordinator.\nThe data owner can use it to verify the mesh certificates of the workloads.\nThis certificate is bound to the manifest set when the Coordinator is verified.\nIf the manifest is updated, the mesh CA certificate changes.\nNew workloads will receive mesh certificates signed by the ",(0,n.jsx)(t.em,{children:"new"})," mesh CA certificate.\nThe Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate.\nThe service mesh also uses the mesh CA certificate to verify the mesh certificates."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"intermediate CA certificate"})," links the root CA certificate to the\nmesh certificate so that the mesh certificate can be verified with the root CA\ncertificate. It's part of the certificate chain handed out by\nendpoints in the service mesh."]}),"\n",(0,n.jsxs)(t.li,{children:["The ",(0,n.jsx)(t.strong,{children:"mesh certificate"})," is part of the certificate chain handed out by\nendpoints in the service mesh. During the startup of a pod, the Initializer\nrequests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully\nverifies the workload. The mesh certificate\ncontains X.509 extensions with information from the workloads attestation\ndocument."]}),"\n"]})]})}function f(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},19979:(e,t,i)=>{i.d(t,{A:()=>r});const r=i.p+"assets/images/contrast_pki.drawio-a2442a1eeb081612c5ad587a58589ad4.svg"},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var r=i(96540);const n={},a=r.createContext(n);function s(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:s(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/fda633d9.f148ee0b.js b/pr-preview/pr-976/assets/js/fda633d9.f148ee0b.js new file mode 100644 index 0000000000..3d867c6d09 --- /dev/null +++ b/pr-preview/pr-976/assets/js/fda633d9.f148ee0b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[827],{29598:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"architecture/secrets","title":"Secrets & recovery","description":"When the Coordinator is configured with the initial manifest, it generates a random secret seed.","source":"@site/versioned_docs/version-1.0/architecture/secrets.md","sourceDirName":"architecture","slug":"/architecture/secrets","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/secrets","draft":false,"unlisted":false,"editUrl":"https://github.com/edgelesssys/contrast/edit/main/docs/versioned_docs/version-1.0/architecture/secrets.md","tags":[],"version":"1.0","frontMatter":{},"sidebar":"docs","previous":{"title":"Attestation","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/attestation"},"next":{"title":"Certificate authority","permalink":"/contrast/pr-preview/pr-976/1.0/architecture/certificates"}}');var n=r(74848),i=r(28453);const o={},a="Secrets & recovery",d={},c=[{value:"Persistence",id:"persistence",level:2},{value:"Recovery",id:"recovery",level:2},{value:"Workload Secrets",id:"workload-secrets",level:2}];function h(e){const t={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"secrets--recovery",children:"Secrets & recovery"})}),"\n",(0,n.jsx)(t.p,{children:"When the Coordinator is configured with the initial manifest, it generates a random secret seed.\nFrom this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history.\nThis derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state."}),"\n",(0,n.jsxs)(t.p,{children:["The secret seed is returned to the user on the first call to ",(0,n.jsx)(t.code,{children:"contrast set"}),", encrypted with the user's public seed share owner key.\nIf no seed share owner key is provided, a key is generated and stored in the working directory."]}),"\n",(0,n.jsx)(t.h2,{id:"persistence",children:"Persistence"}),"\n",(0,n.jsxs)(t.p,{children:["The Coordinator runs as a ",(0,n.jsx)(t.code,{children:"StatefulSet"})," with a dynamically provisioned persistent volume.\nThis volume stores the manifest history and the associated runtime policies.\nThe manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads.\nHowever, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users.\nThus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed."]}),"\n",(0,n.jsx)(t.h2,{id:"recovery",children:"Recovery"}),"\n",(0,n.jsxs)(t.p,{children:["When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests.\nIt needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures.\nThis procedure is called recovery and is initiated by the workload owner.\nThe CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the ",(0,n.jsx)(t.code,{children:"Recover"})," method.\nThe Coordinator recovers its key material and verifies the manifest history signature."]}),"\n",(0,n.jsx)(t.h2,{id:"workload-secrets",children:"Workload Secrets"}),"\n",(0,n.jsxs)(t.p,{children:["The Coordinator provides each workload a secret seed during attestation. This secret can be used by the workload to derive additional secrets for example to\nencrypt persistent data. Like the workload certificates it's mounted in the shared Kubernetes volume ",(0,n.jsx)(t.code,{children:"contrast-secrets"})," in the path ",(0,n.jsx)(t.code,{children:"<mountpoint>/secrets/workload-secret-seed"}),"."]}),"\n",(0,n.jsx)(t.admonition,{type:"warning",children:(0,n.jsx)(t.p,{children:"The workload owner can decrypt data encrypted with secrets derived from the workload secret.\nThe workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner.\nIf the data owner and the workload owner is the same entity, then they can safely use the workload secrets."})})]})}function l(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>a});var s=r(96540);const n={},i=s.createContext(n);function o(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/main.bd30bfc7.js b/pr-preview/pr-976/assets/js/main.bd30bfc7.js new file mode 100644 index 0000000000..1d96d18115 --- /dev/null +++ b/pr-preview/pr-976/assets/js/main.bd30bfc7.js @@ -0,0 +1,2 @@ +/*! For license information please see main.bd30bfc7.js.LICENSE.txt */ +(self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[]).push([[8792],{38858:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(53259),o=n.n(r),a=n(84054);const i={"014daffb":[()=>n.e(1955).then(n.bind(n,89204)),"@site/docs/architecture/secrets.md",89204],"018595b3":[()=>Promise.all([n.e(1869),n.e(3876)]).then(n.bind(n,59763)),"@site/versioned_docs/version-0.5/examples/index.md",59763],"04102e85":[()=>n.e(1158).then(n.bind(n,30612)),"@site/versioned_docs/version-0.5/architecture/attestation/hardware.md",30612],"06354bbe":[()=>n.e(8204).then(n.bind(n,18733)),"@site/versioned_docs/version-0.9/components/overview.md",18733],"06eada7a":[()=>n.e(6470).then(n.bind(n,28601)),"@site/versioned_docs/version-0.7/components/policies.md",28601],"078f57bf":[()=>n.e(1690).then(n.bind(n,30569)),"@site/versioned_docs/version-0.9/architecture/observability.md",30569],"098bf236":[()=>n.e(8259).then(n.bind(n,32284)),"@site/versioned_docs/version-0.8/intro.md",32284],"0a09f1f2":[()=>n.e(7e3).then(n.bind(n,35787)),"@site/versioned_docs/version-1.1/deployment.md",35787],"0a7a212e":[()=>n.e(3702).then(n.bind(n,4949)),"@site/versioned_docs/version-0.8/basics/confidential-containers.md",4949],"0b1c872d":[()=>n.e(3188).then(n.bind(n,25776)),"@site/versioned_docs/version-1.1/components/policies.md",25776],"0ba7602a":[()=>n.e(7368).then(n.bind(n,37154)),"@site/versioned_docs/version-0.9/features-limitations.md",37154],"0c24bc66":[()=>n.e(6739).then(n.bind(n,73521)),"@site/versioned_docs/version-0.6/basics/security-benefits.md",73521],"0e384e19":[()=>n.e(3976).then(n.bind(n,73700)),"@site/docs/intro.md",73700],"10257d90":[()=>n.e(3477).then(n.bind(n,45013)),"@site/versioned_docs/version-1.1/basics/security-benefits.md",45013],"1057c3b3":[()=>n.e(5811).then(n.bind(n,26033)),"@site/versioned_docs/version-1.1/basics/confidential-containers.md",26033],"137fbf80":[()=>n.e(7664).then(n.t.bind(n,97086,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-8-ed3.json",97086],"14a9ce33":[()=>n.e(7924).then(n.bind(n,50499)),"@site/versioned_docs/version-0.8/architecture/attestation.md",50499],"14eb3368":[()=>Promise.all([n.e(1869),n.e(6969)]).then(n.bind(n,6893)),"@theme/DocCategoryGeneratedIndexPage",6893],"15b9bf06":[()=>n.e(5388).then(n.bind(n,12988)),"@site/versioned_docs/version-0.5/architecture/confidential-containers.md",12988],"173fd1a8":[()=>n.e(1514).then(n.bind(n,71144)),"@site/versioned_docs/version-0.7/basics/features.md",71144],17896441:[()=>Promise.all([n.e(1869),n.e(6912),n.e(8401)]).then(n.bind(n,71350)),"@theme/DocItem",71350],"1ab97833":[()=>n.e(985).then(n.bind(n,29083)),"@site/versioned_docs/version-1.0/components/overview.md",29083],"1c9b88ee":[()=>n.e(1560).then(n.bind(n,62538)),"@site/versioned_docs/version-0.6/getting-started/install.md",62538],"1e7c9753":[()=>n.e(3391).then(n.bind(n,99028)),"@site/versioned_docs/version-1.1/basics/features.md",99028],"1ea8f7a3":[()=>n.e(4555).then(n.t.bind(n,48376,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-6-9c2.json",48376],"20382dd7":[()=>n.e(3357).then(n.bind(n,33961)),"@site/versioned_docs/version-0.5/architecture/attestation/runtime-policies.md",33961],"207bb774":[()=>Promise.all([n.e(1869),n.e(430)]).then(n.bind(n,50880)),"@site/versioned_docs/version-0.6/about/index.md",50880],"20e0cfa9":[()=>n.e(8403).then(n.bind(n,69107)),"@site/versioned_docs/version-0.7/basics/confidential-containers.md",69107],"21d7c4d4":[()=>n.e(5390).then(n.bind(n,50728)),"@site/versioned_docs/version-0.6/examples/emojivoto.md",50728],"2496d21b":[()=>n.e(995).then(n.bind(n,83495)),"@site/docs/about/telemetry.md",83495],"250ffcdd":[()=>n.e(2343).then(n.bind(n,30106)),"@site/versioned_docs/version-0.8/troubleshooting.md",30106],"259f95a2":[()=>n.e(8630).then(n.t.bind(n,83337,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-c22.json",83337],"26742c3b":[()=>n.e(3108).then(n.bind(n,45694)),"@site/versioned_docs/version-0.9/architecture/secrets.md",45694],"27004ef7":[()=>n.e(2154).then(n.bind(n,23003)),"@site/versioned_docs/version-1.1/features-limitations.md",23003],"270470f6":[()=>n.e(8671).then(n.bind(n,67669)),"@site/versioned_docs/version-1.0/components/service-mesh.md",67669],"27a940ba":[()=>n.e(5279).then(n.bind(n,85360)),"@site/versioned_docs/version-1.0/components/runtime.md",85360],"27d05faa":[()=>n.e(7697).then(n.bind(n,12346)),"@site/versioned_docs/version-0.6/about/telemetry.md",12346],"2a2a0c40":[()=>n.e(7292).then(n.bind(n,48672)),"@site/docs/getting-started/install.md",48672],"2dbe31cc":[()=>n.e(2700).then(n.bind(n,18856)),"@site/versioned_docs/version-0.7/components/service-mesh.md",18856],"2df6ad32":[()=>n.e(1597).then(n.bind(n,92258)),"@site/versioned_docs/version-1.0/deployment.md",92258],"2e82b444":[()=>n.e(6232).then(n.bind(n,91313)),"@site/versioned_docs/version-0.9/architecture/attestation.md",91313],"327db732":[()=>n.e(1751).then(n.bind(n,59414)),"@site/versioned_docs/version-0.5/getting-started/first-steps.md",59414],"327e592d":[()=>n.e(388).then(n.bind(n,17160)),"@site/versioned_docs/version-0.9/basics/security-benefits.md",17160],"35dd9928":[()=>n.e(95).then(n.bind(n,90087)),"@site/docs/features-limitations.md",90087],"3683601e":[()=>n.e(2987).then(n.bind(n,85863)),"@site/versioned_docs/version-0.9/deployment.md",85863],"39db4684":[()=>Promise.all([n.e(1869),n.e(3459)]).then(n.bind(n,56860)),"@site/versioned_docs/version-0.7/about/index.md",56860],"3a77bb3e":[()=>n.e(1889).then(n.bind(n,34690)),"@site/versioned_docs/version-0.5/getting-started/cluster-setup.md",34690],"3d96af17":[()=>n.e(4506).then(n.bind(n,78016)),"@site/versioned_docs/version-1.1/getting-started/cluster-setup.md",78016],"3d9be0cc":[()=>n.e(5310).then(n.bind(n,51550)),"@site/versioned_docs/version-0.5/examples/emojivoto.md",51550],"3e02a241":[()=>n.e(8117).then(n.bind(n,28072)),"@site/versioned_docs/version-0.5/architecture/certificates-and-identities/pki.md",28072],"41b31679":[()=>n.e(4714).then(n.bind(n,65324)),"@site/versioned_docs/version-0.9/troubleshooting.md",65324],"44b49990":[()=>n.e(9652).then(n.bind(n,40820)),"@site/versioned_docs/version-0.9/intro.md",40820],"45c98560":[()=>n.e(9361).then(n.bind(n,70687)),"@site/versioned_docs/version-0.6/components/index.md",70687],"48f2f8ef":[()=>n.e(2020).then(n.bind(n,80401)),"@site/versioned_docs/version-1.1/architecture/attestation.md",80401],"4ce6baab":[()=>n.e(455).then(n.bind(n,57718)),"@site/versioned_docs/version-1.0/about/telemetry.md",57718],"4cf3063f":[()=>n.e(8364).then(n.bind(n,53881)),"@site/versioned_docs/version-1.0/basics/features.md",53881],"4eec459c":[()=>n.e(2639).then(n.bind(n,13204)),"@site/versioned_docs/version-1.1/components/runtime.md",13204],"4f453872":[()=>n.e(8170).then(n.bind(n,80786)),"@site/versioned_docs/version-0.5/architecture/attestation/pod-vm.md",80786],"4fb24623":[()=>n.e(2550).then(n.bind(n,17364)),"@site/docs/architecture/certificates.md",17364],"50474e10":[()=>n.e(7061).then(n.bind(n,63297)),"@site/versioned_docs/version-0.6/basics/confidential-containers.md",63297],"51513a8d":[()=>n.e(3859).then(n.bind(n,12241)),"@site/versioned_docs/version-1.0/architecture/observability.md",12241],"54c6367b":[()=>n.e(5999).then(n.bind(n,84608)),"@site/versioned_docs/version-0.6/components/service-mesh.md",84608],"567e04ee":[()=>n.e(6440).then(n.bind(n,71871)),"@site/versioned_docs/version-0.6/components/policies.md",71871],"5aa90309":[()=>n.e(1381).then(n.t.bind(n,3189,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-5-category-attestation-d3c.json",3189],"5c6fa5d3":[()=>n.e(722).then(n.bind(n,30014)),"@site/versioned_docs/version-1.1/examples/emojivoto.md",30014],"5e95c892":[()=>n.e(9647).then(n.bind(n,27591)),"@theme/DocsRoot",27591],"5eab7755":[()=>Promise.all([n.e(1869),n.e(2772)]).then(n.bind(n,80601)),"@site/versioned_docs/version-0.7/getting-started/index.md",80601],"5ecc20d3":[()=>n.e(1954).then(n.bind(n,71417)),"@site/versioned_docs/version-1.1/architecture/certificates.md",71417],"5f998a2f":[()=>n.e(941).then(n.bind(n,67785)),"@site/versioned_docs/version-1.1/intro.md",67785],"6009a9aa":[()=>n.e(8212).then(n.bind(n,80621)),"@site/versioned_docs/version-0.9/components/runtime.md",80621],"6100b425":[()=>n.e(3129).then(n.bind(n,11768)),"@site/versioned_docs/version-0.9/basics/features.md",11768],"640cb024":[()=>n.e(7682).then(n.bind(n,8381)),"@site/docs/basics/security-benefits.md",8381],"642ed902":[()=>n.e(5541).then(n.bind(n,48162)),"@site/docs/architecture/attestation.md",48162],"6478b99f":[()=>n.e(3506).then(n.bind(n,56468)),"@site/versioned_docs/version-0.6/known-limitations.md",56468],"64d58a39":[()=>n.e(2005).then(n.bind(n,4463)),"@site/versioned_docs/version-0.5/architecture/attestation/coordinator.md",4463],"6507182a":[()=>n.e(9079).then(n.bind(n,90915)),"@site/versioned_docs/version-1.1/architecture/security-considerations.md",90915],"68be920e":[()=>n.e(7294).then(n.bind(n,11080)),"@site/versioned_docs/version-1.1/architecture/observability.md",11080],"6903d0da":[()=>n.e(594).then(n.bind(n,43980)),"@site/versioned_docs/version-0.5/basics/features.md",43980],"69ec948c":[()=>n.e(3712).then(n.bind(n,75778)),"@site/versioned_docs/version-0.5/deployment.md",75778],"6a46f748":[()=>n.e(6240).then(n.bind(n,42508)),"@site/versioned_docs/version-0.8/architecture/observability.md",42508],"6fc50b39":[()=>n.e(4213).then(n.bind(n,3669)),"@site/versioned_docs/version-0.8/getting-started/install.md",3669],"75100f0d":[()=>Promise.all([n.e(1869),n.e(7882)]).then(n.bind(n,82094)),"@site/versioned_docs/version-0.6/architecture/index.md",82094],"75d659e1":[()=>n.e(8597).then(n.bind(n,5004)),"@site/versioned_docs/version-0.6/deployment.md",5004],"7680d80e":[()=>n.e(9025).then(n.bind(n,88205)),"@site/versioned_docs/version-0.7/examples/emojivoto.md",88205],"790f17e8":[()=>n.e(5242).then(n.bind(n,27808)),"@site/versioned_docs/version-0.8/components/service-mesh.md",27808],"7bd8db71":[()=>n.e(1606).then(n.bind(n,57378)),"@site/versioned_docs/version-1.0/intro.md",57378],"7d1602ac":[()=>n.e(6069).then(n.bind(n,55238)),"@site/versioned_docs/version-0.8/basics/features.md",55238],"7edb0f0d":[()=>n.e(5231).then(n.bind(n,32716)),"@site/versioned_docs/version-0.7/architecture/observability.md",32716],"7f3f1ff7":[()=>n.e(6623).then(n.bind(n,86696)),"@site/versioned_docs/version-0.9/about/telemetry.md",86696],"8132774f":[()=>n.e(1841).then(n.bind(n,58879)),"@site/versioned_docs/version-0.7/getting-started/cluster-setup.md",58879],89486910:[()=>n.e(7086).then(n.bind(n,41805)),"@site/docs/components/overview.md",41805],"8965cb1f":[()=>n.e(2731).then(n.t.bind(n,45337,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-5-category-network-encryption-bd2.json",45337],"896da145":[()=>Promise.all([n.e(1869),n.e(1739)]).then(n.bind(n,57204)),"@site/versioned_docs/version-0.7/examples/index.md",57204],"89a4f0ca":[()=>n.e(4687).then(n.bind(n,78700)),"@site/docs/basics/features.md",78700],"8c9a8791":[()=>n.e(5335).then(n.bind(n,20016)),"@site/versioned_docs/version-0.7/components/runtime.md",20016],"8dca39c2":[()=>n.e(3116).then(n.bind(n,82489)),"@site/versioned_docs/version-0.5/basics/confidential-containers.md",82489],"8f09b871":[()=>n.e(9686).then(n.t.bind(n,20088,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-5-category-components-a64.json",20088],"9040bbc8":[()=>n.e(2453).then(n.bind(n,98935)),"@site/versioned_docs/version-1.0/examples/emojivoto.md",98935],"90af0d0d":[()=>n.e(8921).then(n.bind(n,17170)),"@site/versioned_docs/version-0.6/components/runtime.md",17170],"9152dfbd":[()=>n.e(8036).then(n.t.bind(n,5359,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-1-0-097.json",5359],"927cf76e":[()=>n.e(1226).then(n.bind(n,9902)),"@site/docs/architecture/observability.md",9902],"9397123b":[()=>n.e(2941).then(n.bind(n,99845)),"@site/versioned_docs/version-0.5/architecture/attestation/manifest.md",99845],"9620adf5":[()=>n.e(912).then(n.bind(n,81469)),"@site/versioned_docs/version-1.0/basics/security-benefits.md",81469],"966b9f47":[()=>n.e(1112).then(n.bind(n,98525)),"@site/versioned_docs/version-0.5/architecture/components/cli.md",98525],"969019ea":[()=>n.e(485).then(n.bind(n,31424)),"@site/versioned_docs/version-1.1/components/service-mesh.md",31424],"98367cce":[()=>n.e(133).then(n.bind(n,71663)),"@site/versioned_docs/version-0.8/basics/security-benefits.md",71663],"989c6d03":[()=>n.e(782).then(n.bind(n,91122)),"@site/docs/components/policies.md",91122],"9a06ae3d":[()=>n.e(2912).then(n.bind(n,56704)),"@site/docs/getting-started/cluster-setup.md",56704],"9a28f5c4":[()=>n.e(3505).then(n.bind(n,99764)),"@site/versioned_docs/version-0.9/examples/emojivoto.md",99764],"9a99019d":[()=>n.e(801).then(n.bind(n,89293)),"@site/versioned_docs/version-0.7/intro.md",89293],"9c8ec574":[()=>n.e(1831).then(n.t.bind(n,81069,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-9-0e9.json",81069],"9ccb1fc6":[()=>n.e(9874).then(n.bind(n,65339)),"@site/versioned_docs/version-0.8/components/runtime.md",65339],"9ce1fd56":[()=>n.e(426).then(n.bind(n,42809)),"@site/versioned_docs/version-0.8/components/overview.md",42809],"9d9e06f4":[()=>Promise.all([n.e(1869),n.e(4670)]).then(n.bind(n,12325)),"@site/versioned_docs/version-0.5/architecture/index.md",12325],"9d9f8394":[()=>n.e(9013).then(n.bind(n,64626)),"@site/docs/troubleshooting.md",64626],a0a1fd3b:[()=>n.e(6755).then(n.bind(n,92395)),"@site/versioned_docs/version-1.1/getting-started/install.md",92395],a0a4ec6e:[()=>n.e(4980).then(n.bind(n,48542)),"@site/versioned_docs/version-0.8/examples/emojivoto.md",48542],a161c24f:[()=>n.e(1575).then(n.bind(n,82560)),"@site/versioned_docs/version-0.5/getting-started/install.md",82560],a2899f6e:[()=>n.e(1861).then(n.bind(n,51866)),"@site/versioned_docs/version-1.0/getting-started/cluster-setup.md",51866],a3713279:[()=>n.e(9588).then(n.bind(n,33745)),"@site/docs/deployment.md",33745],a66d714b:[()=>n.e(9974).then(n.bind(n,91304)),"@site/versioned_docs/version-0.8/deployment.md",91304],a71cbd8f:[()=>n.e(5003).then(n.bind(n,91238)),"@site/versioned_docs/version-0.8/architecture/secrets.md",91238],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,50298)),"@theme/DocVersionRoot",50298],a86a94ce:[()=>n.e(212).then(n.bind(n,55850)),"@site/versioned_docs/version-1.1/about/telemetry.md",55850],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,40350)),"@theme/DocRoot",40350],aa0f7abf:[()=>Promise.all([n.e(1869),n.e(8295)]).then(n.bind(n,40593)),"@site/versioned_docs/version-0.7/architecture/index.md",40593],aaec90ae:[()=>n.e(4304).then(n.bind(n,19947)),"@site/versioned_docs/version-1.0/features-limitations.md",19947],aafa6b90:[()=>n.e(6645).then(n.bind(n,55633)),"@site/versioned_docs/version-0.8/architecture/certificates.md",55633],ab09c42c:[()=>n.e(8683).then(n.bind(n,99437)),"@site/versioned_docs/version-0.7/architecture/attestation.md",99437],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,27093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",27093],abfbdc79:[()=>n.e(2045).then(n.bind(n,71925)),"@site/versioned_docs/version-0.7/components/index.md",71925],ac3e6feb:[()=>n.e(3074).then(n.bind(n,25315)),"@site/versioned_docs/version-0.8/about/telemetry.md",25315],ae6c0c68:[()=>n.e(2729).then(n.bind(n,32113)),"@site/versioned_docs/version-0.8/components/policies.md",32113],b0cb3eb4:[()=>n.e(2132).then(n.bind(n,81850)),"@site/docs/architecture/security-considerations.md",81850],b20d32fc:[()=>n.e(4325).then(n.t.bind(n,66744,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-7-6d8.json",66744],b27c3275:[()=>n.e(3690).then(n.bind(n,40497)),"@site/docs/basics/confidential-containers.md",40497],b3916dd3:[()=>n.e(89).then(n.bind(n,34806)),"@site/versioned_docs/version-0.5/architecture/network-encryption/sidecar.md",34806],b3a88889:[()=>n.e(9440).then(n.t.bind(n,37367,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-5-710.json",37367],b451d7c3:[()=>n.e(234).then(n.bind(n,90961)),"@site/versioned_docs/version-1.1/getting-started/bare-metal.md",90961],ba2406d8:[()=>n.e(2476).then(n.bind(n,56218)),"@site/versioned_docs/version-0.8/getting-started/cluster-setup.md",56218],baef5027:[()=>Promise.all([n.e(1869),n.e(9103)]).then(n.bind(n,51760)),"@site/versioned_docs/version-0.5/getting-started/index.md",51760],bced0f3c:[()=>n.e(8001).then(n.bind(n,33221)),"@site/versioned_docs/version-0.7/basics/security-benefits.md",33221],bd029836:[()=>n.e(1047).then(n.bind(n,74283)),"@site/versioned_docs/version-1.0/components/policies.md",74283],bd625abb:[()=>n.e(4415).then(n.bind(n,89939)),"@site/versioned_docs/version-1.0/architecture/attestation.md",89939],bde25e2b:[()=>n.e(5878).then(n.t.bind(n,51556,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-next-ec8.json",51556],bf823012:[()=>n.e(5225).then(n.bind(n,32615)),"@site/versioned_docs/version-0.7/getting-started/install.md",32615],c09e49b9:[()=>n.e(390).then(n.bind(n,82693)),"@site/versioned_docs/version-0.6/architecture/certificates.md",82693],c1fac065:[()=>Promise.all([n.e(1869),n.e(4206)]).then(n.bind(n,69006)),"@site/versioned_docs/version-0.6/getting-started/index.md",69006],c2ce05d5:[()=>n.e(8024).then(n.bind(n,94003)),"@site/versioned_docs/version-1.0/troubleshooting.md",94003],c3a9f66a:[()=>n.e(7832).then(n.bind(n,8032)),"@site/versioned_docs/version-0.9/components/service-mesh.md",8032],c4b4ced0:[()=>n.e(2564).then(n.bind(n,58505)),"@site/docs/components/runtime.md",58505],c7462af2:[()=>n.e(2540).then(n.bind(n,56473)),"@site/versioned_docs/version-0.9/components/policies.md",56473],ca5b6702:[()=>n.e(5945).then(n.bind(n,95477)),"@site/docs/components/service-mesh.md",95477],cdb2b1a5:[()=>Promise.all([n.e(1869),n.e(9119)]).then(n.bind(n,78496)),"@site/versioned_docs/version-0.6/examples/index.md",78496],cf49aa2b:[()=>n.e(4703).then(n.bind(n,18803)),"@site/docs/getting-started/bare-metal.md",18803],d1a11e04:[()=>n.e(8902).then(n.bind(n,97232)),"@site/versioned_docs/version-0.8/features-limitations.md",97232],d2630e76:[()=>n.e(9634).then(n.bind(n,22846)),"@site/versioned_docs/version-0.5/architecture/network-encryption/protocols-and-keys.md",22846],d580a1fd:[()=>n.e(1734).then(n.bind(n,42533)),"@site/versioned_docs/version-0.5/architecture/components/init-container.md",42533],d77304ba:[()=>n.e(4233).then(n.bind(n,15796)),"@site/versioned_docs/version-1.0/basics/confidential-containers.md",15796],dacf14a0:[()=>n.e(101).then(n.bind(n,48763)),"@site/versioned_docs/version-0.9/getting-started/install.md",48763],de615ffd:[()=>n.e(1321).then(n.bind(n,85230)),"@site/versioned_docs/version-0.7/deployment.md",85230],dfd9c366:[()=>n.e(2454).then(n.bind(n,29026)),"@site/versioned_docs/version-0.6/basics/features.md",29026],e1e441c9:[()=>n.e(2623).then(n.bind(n,54794)),"@site/versioned_docs/version-0.6/architecture/attestation.md",54794],e277c26a:[()=>n.e(1632).then(n.bind(n,78335)),"@site/versioned_docs/version-0.7/architecture/certificates.md",78335],e2b3b970:[()=>n.e(2841).then(n.bind(n,6428)),"@site/versioned_docs/version-0.7/features-limitations.md",6428],e446d98f:[()=>n.e(221).then(n.bind(n,43008)),"@site/versioned_docs/version-0.5/architecture/components/coordinator.md",43008],e55aefba:[()=>n.e(4113).then(n.bind(n,69732)),"@site/versioned_docs/version-0.9/basics/confidential-containers.md",69732],e8480491:[()=>n.e(1362).then(n.bind(n,14920)),"@site/versioned_docs/version-1.0/architecture/certificates.md",14920],e9dbdd13:[()=>n.e(1647).then(n.bind(n,35121)),"@site/versioned_docs/version-1.1/troubleshooting.md",35121],edcfcef8:[()=>n.e(3133).then(n.bind(n,81779)),"@site/versioned_docs/version-1.1/components/overview.md",81779],ee8b52db:[()=>n.e(5316).then(n.bind(n,51076)),"@site/versioned_docs/version-0.5/basics/security-benefits.md",51076],f2348f57:[()=>n.e(8772).then(n.bind(n,74153)),"@site/versioned_docs/version-1.1/architecture/secrets.md",74153],f31967d8:[()=>n.e(6733).then(n.bind(n,89400)),"@site/versioned_docs/version-0.7/about/telemetry.md",89400],f36abd57:[()=>n.e(6711).then(n.bind(n,8624)),"@site/versioned_docs/version-0.9/getting-started/cluster-setup.md",8624],f47dd6e5:[()=>n.e(6408).then(n.bind(n,99851)),"@site/versioned_docs/version-0.5/intro.md",99851],f5272de0:[()=>n.e(564).then(n.t.bind(n,11324,19)),"@generated/docusaurus-plugin-content-docs/default/p/contrast-pr-preview-pr-976-0-5-category-certificates-and-identities-2b8.json",11324],f593d43a:[()=>n.e(1956).then(n.bind(n,60558)),"@site/versioned_docs/version-0.6/intro.md",60558],f65fea7a:[()=>n.e(2472).then(n.bind(n,27115)),"@site/docs/examples/emojivoto.md",27115],fbad2ec0:[()=>n.e(1658).then(n.bind(n,6784)),"@site/versioned_docs/version-0.6/getting-started/cluster-setup.md",6784],fbad79f4:[()=>n.e(2590).then(n.bind(n,98707)),"@site/versioned_docs/version-1.0/getting-started/install.md",98707],fbcf0d59:[()=>n.e(3970).then(n.bind(n,18012)),"@site/versioned_docs/version-0.9/architecture/certificates.md",18012],fda633d9:[()=>n.e(827).then(n.bind(n,29598)),"@site/versioned_docs/version-1.0/architecture/secrets.md",29598]};var s=n(74848);function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var l=n(6367),u=n(92764);function p(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(8159).then(n.bind(n,18159)),modules:["@theme/NotFound"],webpack:()=>[18159],render(e,t){const n=e.default;return(0,s.jsx)(u.W,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],p={},d=[],f=[],m=(0,l.A)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=i[n];r&&(p[t]=r[0],d.push(r[1]),f.push(r[2]))})),o().Map({loading:c,loader:p,modules:d,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,s.jsx)(u.W,{value:i,children:(0,s.jsx)(a,{...o,...c,...n})})}})}const d=[{path:"/contrast/pr-preview/pr-976/",component:p("/contrast/pr-preview/pr-976/","a12"),routes:[{path:"/contrast/pr-preview/pr-976/0.5",component:p("/contrast/pr-preview/pr-976/0.5","78d"),routes:[{path:"/contrast/pr-preview/pr-976/0.5",component:p("/contrast/pr-preview/pr-976/0.5","895"),routes:[{path:"/contrast/pr-preview/pr-976/0.5",component:p("/contrast/pr-preview/pr-976/0.5","7f7"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture",component:p("/contrast/pr-preview/pr-976/0.5/architecture","83c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator",component:p("/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator","a64"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware",component:p("/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware","2f5"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest",component:p("/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest","963"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm",component:p("/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm","aea"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies",component:p("/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies","bf9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki",component:p("/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki","89c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/components/cli",component:p("/contrast/pr-preview/pr-976/0.5/architecture/components/cli","2f7"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator",component:p("/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator","257"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container",component:p("/contrast/pr-preview/pr-976/0.5/architecture/components/init-container","56a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers","19b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys",component:p("/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys","f9c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar",component:p("/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar","973"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.5/basics/confidential-containers","62c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/basics/features",component:p("/contrast/pr-preview/pr-976/0.5/basics/features","87d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/0.5/basics/security-benefits","004"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/category/attestation",component:p("/contrast/pr-preview/pr-976/0.5/category/attestation","00d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities",component:p("/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities","968"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/category/components",component:p("/contrast/pr-preview/pr-976/0.5/category/components","c39"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/category/network-encryption",component:p("/contrast/pr-preview/pr-976/0.5/category/network-encryption","633"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/deployment",component:p("/contrast/pr-preview/pr-976/0.5/deployment","b43"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/examples",component:p("/contrast/pr-preview/pr-976/0.5/examples","4f4"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/0.5/examples/emojivoto","811"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/getting-started",component:p("/contrast/pr-preview/pr-976/0.5/getting-started","7dd"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup","26d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps",component:p("/contrast/pr-preview/pr-976/0.5/getting-started/first-steps","ce9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.5/getting-started/install",component:p("/contrast/pr-preview/pr-976/0.5/getting-started/install","437"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/0.6",component:p("/contrast/pr-preview/pr-976/0.6","6f5"),routes:[{path:"/contrast/pr-preview/pr-976/0.6",component:p("/contrast/pr-preview/pr-976/0.6","a86"),routes:[{path:"/contrast/pr-preview/pr-976/0.6",component:p("/contrast/pr-preview/pr-976/0.6","f27"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/about",component:p("/contrast/pr-preview/pr-976/0.6/about","67b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/about/telemetry",component:p("/contrast/pr-preview/pr-976/0.6/about/telemetry","61b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/architecture",component:p("/contrast/pr-preview/pr-976/0.6/architecture","ce6"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/architecture/attestation",component:p("/contrast/pr-preview/pr-976/0.6/architecture/attestation","c3a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/architecture/certificates",component:p("/contrast/pr-preview/pr-976/0.6/architecture/certificates","7cc"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.6/basics/confidential-containers","24c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/basics/features",component:p("/contrast/pr-preview/pr-976/0.6/basics/features","3b5"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/0.6/basics/security-benefits","7a8"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/components",component:p("/contrast/pr-preview/pr-976/0.6/components","f96"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/components/policies",component:p("/contrast/pr-preview/pr-976/0.6/components/policies","d35"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/components/runtime",component:p("/contrast/pr-preview/pr-976/0.6/components/runtime","570"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/components/service-mesh",component:p("/contrast/pr-preview/pr-976/0.6/components/service-mesh","2a9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/deployment",component:p("/contrast/pr-preview/pr-976/0.6/deployment","ee0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/examples",component:p("/contrast/pr-preview/pr-976/0.6/examples","e8d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/0.6/examples/emojivoto","7eb"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/getting-started",component:p("/contrast/pr-preview/pr-976/0.6/getting-started","0c5"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup","864"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/getting-started/install",component:p("/contrast/pr-preview/pr-976/0.6/getting-started/install","2e9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.6/known-limitations",component:p("/contrast/pr-preview/pr-976/0.6/known-limitations","454"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/0.7",component:p("/contrast/pr-preview/pr-976/0.7","599"),routes:[{path:"/contrast/pr-preview/pr-976/0.7",component:p("/contrast/pr-preview/pr-976/0.7","9f8"),routes:[{path:"/contrast/pr-preview/pr-976/0.7",component:p("/contrast/pr-preview/pr-976/0.7","78b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/about",component:p("/contrast/pr-preview/pr-976/0.7/about","054"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/about/telemetry",component:p("/contrast/pr-preview/pr-976/0.7/about/telemetry","da0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/architecture",component:p("/contrast/pr-preview/pr-976/0.7/architecture","742"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/architecture/attestation",component:p("/contrast/pr-preview/pr-976/0.7/architecture/attestation","b8a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/architecture/certificates",component:p("/contrast/pr-preview/pr-976/0.7/architecture/certificates","2fb"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/architecture/observability",component:p("/contrast/pr-preview/pr-976/0.7/architecture/observability","5f2"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.7/basics/confidential-containers","2ab"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/basics/features",component:p("/contrast/pr-preview/pr-976/0.7/basics/features","a92"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/0.7/basics/security-benefits","7bd"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/components",component:p("/contrast/pr-preview/pr-976/0.7/components","afa"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/components/policies",component:p("/contrast/pr-preview/pr-976/0.7/components/policies","e21"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/components/runtime",component:p("/contrast/pr-preview/pr-976/0.7/components/runtime","0ae"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/components/service-mesh",component:p("/contrast/pr-preview/pr-976/0.7/components/service-mesh","1f6"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/deployment",component:p("/contrast/pr-preview/pr-976/0.7/deployment","670"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/examples",component:p("/contrast/pr-preview/pr-976/0.7/examples","03a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/0.7/examples/emojivoto","d75"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/features-limitations",component:p("/contrast/pr-preview/pr-976/0.7/features-limitations","90a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/getting-started",component:p("/contrast/pr-preview/pr-976/0.7/getting-started","230"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup","99c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.7/getting-started/install",component:p("/contrast/pr-preview/pr-976/0.7/getting-started/install","610"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/0.8",component:p("/contrast/pr-preview/pr-976/0.8","eb1"),routes:[{path:"/contrast/pr-preview/pr-976/0.8",component:p("/contrast/pr-preview/pr-976/0.8","9c8"),routes:[{path:"/contrast/pr-preview/pr-976/0.8",component:p("/contrast/pr-preview/pr-976/0.8","75f"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/about/telemetry",component:p("/contrast/pr-preview/pr-976/0.8/about/telemetry","ca9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/architecture/attestation",component:p("/contrast/pr-preview/pr-976/0.8/architecture/attestation","fec"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/architecture/certificates",component:p("/contrast/pr-preview/pr-976/0.8/architecture/certificates","765"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/architecture/observability",component:p("/contrast/pr-preview/pr-976/0.8/architecture/observability","220"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/architecture/secrets",component:p("/contrast/pr-preview/pr-976/0.8/architecture/secrets","754"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.8/basics/confidential-containers","4d5"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/basics/features",component:p("/contrast/pr-preview/pr-976/0.8/basics/features","793"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/0.8/basics/security-benefits","a16"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/components/overview",component:p("/contrast/pr-preview/pr-976/0.8/components/overview","2d3"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/components/policies",component:p("/contrast/pr-preview/pr-976/0.8/components/policies","652"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/components/runtime",component:p("/contrast/pr-preview/pr-976/0.8/components/runtime","006"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/components/service-mesh",component:p("/contrast/pr-preview/pr-976/0.8/components/service-mesh","17b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/deployment",component:p("/contrast/pr-preview/pr-976/0.8/deployment","370"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/0.8/examples/emojivoto","a78"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/features-limitations",component:p("/contrast/pr-preview/pr-976/0.8/features-limitations","d8e"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup","4ac"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/getting-started/install",component:p("/contrast/pr-preview/pr-976/0.8/getting-started/install","eb7"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.8/troubleshooting",component:p("/contrast/pr-preview/pr-976/0.8/troubleshooting","6ab"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/0.9",component:p("/contrast/pr-preview/pr-976/0.9","901"),routes:[{path:"/contrast/pr-preview/pr-976/0.9",component:p("/contrast/pr-preview/pr-976/0.9","e48"),routes:[{path:"/contrast/pr-preview/pr-976/0.9",component:p("/contrast/pr-preview/pr-976/0.9","cbe"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/about/telemetry",component:p("/contrast/pr-preview/pr-976/0.9/about/telemetry","3db"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/architecture/attestation",component:p("/contrast/pr-preview/pr-976/0.9/architecture/attestation","128"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/architecture/certificates",component:p("/contrast/pr-preview/pr-976/0.9/architecture/certificates","f8d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/architecture/observability",component:p("/contrast/pr-preview/pr-976/0.9/architecture/observability","a73"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/architecture/secrets",component:p("/contrast/pr-preview/pr-976/0.9/architecture/secrets","74d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/0.9/basics/confidential-containers","5df"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/basics/features",component:p("/contrast/pr-preview/pr-976/0.9/basics/features","a33"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/0.9/basics/security-benefits","23f"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/components/overview",component:p("/contrast/pr-preview/pr-976/0.9/components/overview","28a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/components/policies",component:p("/contrast/pr-preview/pr-976/0.9/components/policies","542"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/components/runtime",component:p("/contrast/pr-preview/pr-976/0.9/components/runtime","271"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/components/service-mesh",component:p("/contrast/pr-preview/pr-976/0.9/components/service-mesh","956"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/deployment",component:p("/contrast/pr-preview/pr-976/0.9/deployment","bc8"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/0.9/examples/emojivoto","748"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/features-limitations",component:p("/contrast/pr-preview/pr-976/0.9/features-limitations","8b0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup","12b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/getting-started/install",component:p("/contrast/pr-preview/pr-976/0.9/getting-started/install","4fc"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/0.9/troubleshooting",component:p("/contrast/pr-preview/pr-976/0.9/troubleshooting","714"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/1.0",component:p("/contrast/pr-preview/pr-976/1.0","b7e"),routes:[{path:"/contrast/pr-preview/pr-976/1.0",component:p("/contrast/pr-preview/pr-976/1.0","9da"),routes:[{path:"/contrast/pr-preview/pr-976/1.0",component:p("/contrast/pr-preview/pr-976/1.0","7f4"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/about/telemetry",component:p("/contrast/pr-preview/pr-976/1.0/about/telemetry","7ef"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/architecture/attestation",component:p("/contrast/pr-preview/pr-976/1.0/architecture/attestation","a51"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/architecture/certificates",component:p("/contrast/pr-preview/pr-976/1.0/architecture/certificates","1e4"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/architecture/observability",component:p("/contrast/pr-preview/pr-976/1.0/architecture/observability","2ab"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/architecture/secrets",component:p("/contrast/pr-preview/pr-976/1.0/architecture/secrets","30a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/1.0/basics/confidential-containers","ce9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/basics/features",component:p("/contrast/pr-preview/pr-976/1.0/basics/features","8a2"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/1.0/basics/security-benefits","ac9"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/components/overview",component:p("/contrast/pr-preview/pr-976/1.0/components/overview","d41"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/components/policies",component:p("/contrast/pr-preview/pr-976/1.0/components/policies","72d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/components/runtime",component:p("/contrast/pr-preview/pr-976/1.0/components/runtime","038"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/components/service-mesh",component:p("/contrast/pr-preview/pr-976/1.0/components/service-mesh","cb6"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/deployment",component:p("/contrast/pr-preview/pr-976/1.0/deployment","467"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/1.0/examples/emojivoto","78f"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/features-limitations",component:p("/contrast/pr-preview/pr-976/1.0/features-limitations","343"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup","5a4"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/getting-started/install",component:p("/contrast/pr-preview/pr-976/1.0/getting-started/install","465"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/1.0/troubleshooting",component:p("/contrast/pr-preview/pr-976/1.0/troubleshooting","026"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/next",component:p("/contrast/pr-preview/pr-976/next","b22"),routes:[{path:"/contrast/pr-preview/pr-976/next",component:p("/contrast/pr-preview/pr-976/next","f3f"),routes:[{path:"/contrast/pr-preview/pr-976/next",component:p("/contrast/pr-preview/pr-976/next","3d7"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/about/telemetry",component:p("/contrast/pr-preview/pr-976/next/about/telemetry","8bd"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/architecture/attestation",component:p("/contrast/pr-preview/pr-976/next/architecture/attestation","270"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/architecture/certificates",component:p("/contrast/pr-preview/pr-976/next/architecture/certificates","ab4"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/architecture/observability",component:p("/contrast/pr-preview/pr-976/next/architecture/observability","153"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/architecture/secrets",component:p("/contrast/pr-preview/pr-976/next/architecture/secrets","6dc"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/architecture/security-considerations",component:p("/contrast/pr-preview/pr-976/next/architecture/security-considerations","d7f"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/next/basics/confidential-containers","fe2"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/basics/features",component:p("/contrast/pr-preview/pr-976/next/basics/features","6df"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/next/basics/security-benefits","dd0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/components/overview",component:p("/contrast/pr-preview/pr-976/next/components/overview","438"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/components/policies",component:p("/contrast/pr-preview/pr-976/next/components/policies","460"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/components/runtime",component:p("/contrast/pr-preview/pr-976/next/components/runtime","fa0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/components/service-mesh",component:p("/contrast/pr-preview/pr-976/next/components/service-mesh","702"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/deployment",component:p("/contrast/pr-preview/pr-976/next/deployment","1dd"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/next/examples/emojivoto","f41"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/features-limitations",component:p("/contrast/pr-preview/pr-976/next/features-limitations","8c2"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/getting-started/bare-metal",component:p("/contrast/pr-preview/pr-976/next/getting-started/bare-metal","409"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/next/getting-started/cluster-setup","1d1"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/getting-started/install",component:p("/contrast/pr-preview/pr-976/next/getting-started/install","251"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/next/troubleshooting",component:p("/contrast/pr-preview/pr-976/next/troubleshooting","193"),exact:!0,sidebar:"docs"}]}]},{path:"/contrast/pr-preview/pr-976/",component:p("/contrast/pr-preview/pr-976/","2fb"),routes:[{path:"/contrast/pr-preview/pr-976/",component:p("/contrast/pr-preview/pr-976/","c3c"),routes:[{path:"/contrast/pr-preview/pr-976/about/telemetry",component:p("/contrast/pr-preview/pr-976/about/telemetry","f74"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/architecture/attestation",component:p("/contrast/pr-preview/pr-976/architecture/attestation","171"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/architecture/certificates",component:p("/contrast/pr-preview/pr-976/architecture/certificates","40a"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/architecture/observability",component:p("/contrast/pr-preview/pr-976/architecture/observability","da1"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/architecture/secrets",component:p("/contrast/pr-preview/pr-976/architecture/secrets","eae"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/architecture/security-considerations",component:p("/contrast/pr-preview/pr-976/architecture/security-considerations","cc5"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/basics/confidential-containers",component:p("/contrast/pr-preview/pr-976/basics/confidential-containers","308"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/basics/features",component:p("/contrast/pr-preview/pr-976/basics/features","76b"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/basics/security-benefits",component:p("/contrast/pr-preview/pr-976/basics/security-benefits","899"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/components/overview",component:p("/contrast/pr-preview/pr-976/components/overview","cb2"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/components/policies",component:p("/contrast/pr-preview/pr-976/components/policies","7da"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/components/runtime",component:p("/contrast/pr-preview/pr-976/components/runtime","aee"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/components/service-mesh",component:p("/contrast/pr-preview/pr-976/components/service-mesh","1d8"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/deployment",component:p("/contrast/pr-preview/pr-976/deployment","9b1"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/examples/emojivoto",component:p("/contrast/pr-preview/pr-976/examples/emojivoto","827"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/features-limitations",component:p("/contrast/pr-preview/pr-976/features-limitations","3d3"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/getting-started/bare-metal",component:p("/contrast/pr-preview/pr-976/getting-started/bare-metal","9e3"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/getting-started/cluster-setup",component:p("/contrast/pr-preview/pr-976/getting-started/cluster-setup","2b0"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/getting-started/install",component:p("/contrast/pr-preview/pr-976/getting-started/install","87c"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/troubleshooting",component:p("/contrast/pr-preview/pr-976/troubleshooting","e8d"),exact:!0,sidebar:"docs"},{path:"/contrast/pr-preview/pr-976/",component:p("/contrast/pr-preview/pr-976/","870"),exact:!0,sidebar:"docs"}]}]}]},{path:"*",component:p("*")}]},24221:(e,t,n)=>{var r,o;!function(){var a,i,s,c,l,u,p,d,f,m,h,v,g,b,y,w,_,x,S,k,E,O,j,P,C,A,T,I,N,L,R=function(e){var t=new R.Builder;return t.pipeline.add(R.trimmer,R.stopWordFilter,R.stemmer),t.searchPipeline.add(R.stemmer),e.call(t,t),t.build()};R.version="2.3.9",R.utils={},R.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),R.utils.asString=function(e){return null==e?"":e.toString()},R.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r<n.length;r++){var o=n[r],a=e[o];if(Array.isArray(a))t[o]=a.slice();else{if("string"!=typeof a&&"number"!=typeof a&&"boolean"!=typeof a)throw new TypeError("clone is not deep and does not support nested objects");t[o]=a}}return t},R.FieldRef=function(e,t,n){this.docRef=e,this.fieldName=t,this._stringValue=n},R.FieldRef.joiner="/",R.FieldRef.fromString=function(e){var t=e.indexOf(R.FieldRef.joiner);if(-1===t)throw"malformed field ref string";var n=e.slice(0,t),r=e.slice(t+1);return new R.FieldRef(r,n,e)},R.FieldRef.prototype.toString=function(){return null==this._stringValue&&(this._stringValue=this.fieldName+R.FieldRef.joiner+this.docRef),this._stringValue},R.Set=function(e){if(this.elements=Object.create(null),e){this.length=e.length;for(var t=0;t<this.length;t++)this.elements[e[t]]=!0}else this.length=0},R.Set.complete={intersect:function(e){return e},union:function(){return this},contains:function(){return!0}},R.Set.empty={intersect:function(){return this},union:function(e){return e},contains:function(){return!1}},R.Set.prototype.contains=function(e){return!!this.elements[e]},R.Set.prototype.intersect=function(e){var t,n,r,o=[];if(e===R.Set.complete)return this;if(e===R.Set.empty)return e;this.length<e.length?(t=this,n=e):(t=e,n=this),r=Object.keys(t.elements);for(var a=0;a<r.length;a++){var i=r[a];i in n.elements&&o.push(i)}return new R.Set(o)},R.Set.prototype.union=function(e){return e===R.Set.complete?R.Set.complete:e===R.Set.empty?this:new R.Set(Object.keys(this.elements).concat(Object.keys(e.elements)))},R.idf=function(e,t){var n=0;for(var r in e)"_index"!=r&&(n+=Object.keys(e[r]).length);var o=(t-n+.5)/(n+.5);return Math.log(1+Math.abs(o))},R.Token=function(e,t){this.str=e||"",this.metadata=t||{}},R.Token.prototype.toString=function(){return this.str},R.Token.prototype.update=function(e){return this.str=e(this.str,this.metadata),this},R.Token.prototype.clone=function(e){return e=e||function(e){return e},new R.Token(e(this.str,this.metadata),this.metadata)},R.tokenizer=function(e,t){if(null==e||null==e)return[];if(Array.isArray(e))return e.map((function(e){return new R.Token(R.utils.asString(e).toLowerCase(),R.utils.clone(t))}));for(var n=e.toString().toLowerCase(),r=n.length,o=[],a=0,i=0;a<=r;a++){var s=a-i;if(n.charAt(a).match(R.tokenizer.separator)||a==r){if(s>0){var c=R.utils.clone(t)||{};c.position=[i,s],c.index=o.length,o.push(new R.Token(n.slice(i,a),c))}i=a+1}}return o},R.tokenizer.separator=/[\s\-]+/,R.Pipeline=function(){this._stack=[]},R.Pipeline.registeredFunctions=Object.create(null),R.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&R.utils.warn("Overwriting existing registered function: "+t),e.label=t,R.Pipeline.registeredFunctions[e.label]=e},R.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||R.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},R.Pipeline.load=function(e){var t=new R.Pipeline;return e.forEach((function(e){var n=R.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},R.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){R.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},R.Pipeline.prototype.after=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},R.Pipeline.prototype.before=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},R.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},R.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n<t;n++){for(var r=this._stack[n],o=[],a=0;a<e.length;a++){var i=r(e[a],a,e);if(null!=i&&""!==i)if(Array.isArray(i))for(var s=0;s<i.length;s++)o.push(i[s]);else o.push(i)}e=o}return e},R.Pipeline.prototype.runString=function(e,t){var n=new R.Token(e,t);return this.run([n]).map((function(e){return e.toString()}))},R.Pipeline.prototype.reset=function(){this._stack=[]},R.Pipeline.prototype.toJSON=function(){return this._stack.map((function(e){return R.Pipeline.warnIfFunctionNotRegistered(e),e.label}))},R.Vector=function(e){this._magnitude=0,this.elements=e||[]},R.Vector.prototype.positionForIndex=function(e){if(0==this.elements.length)return 0;for(var t=0,n=this.elements.length/2,r=n-t,o=Math.floor(r/2),a=this.elements[2*o];r>1&&(a<e&&(t=o),a>e&&(n=o),a!=e);)r=n-t,o=t+Math.floor(r/2),a=this.elements[2*o];return a==e||a>e?2*o:a<e?2*(o+1):void 0},R.Vector.prototype.insert=function(e,t){this.upsert(e,t,(function(){throw"duplicate index"}))},R.Vector.prototype.upsert=function(e,t,n){this._magnitude=0;var r=this.positionForIndex(e);this.elements[r]==e?this.elements[r+1]=n(this.elements[r+1],t):this.elements.splice(r,0,e,t)},R.Vector.prototype.magnitude=function(){if(this._magnitude)return this._magnitude;for(var e=0,t=this.elements.length,n=1;n<t;n+=2){var r=this.elements[n];e+=r*r}return this._magnitude=Math.sqrt(e)},R.Vector.prototype.dot=function(e){for(var t=0,n=this.elements,r=e.elements,o=n.length,a=r.length,i=0,s=0,c=0,l=0;c<o&&l<a;)(i=n[c])<(s=r[l])?c+=2:i>s?l+=2:i==s&&(t+=n[c+1]*r[l+1],c+=2,l+=2);return t},R.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},R.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t<this.elements.length;t+=2,n++)e[n]=this.elements[t];return e},R.Vector.prototype.toJSON=function(){return this.elements},R.stemmer=(i={ational:"ate",tional:"tion",enci:"ence",anci:"ance",izer:"ize",bli:"ble",alli:"al",entli:"ent",eli:"e",ousli:"ous",ization:"ize",ation:"ate",ator:"ate",alism:"al",iveness:"ive",fulness:"ful",ousness:"ous",aliti:"al",iviti:"ive",biliti:"ble",logi:"log"},s={icate:"ic",ative:"",alize:"al",iciti:"ic",ical:"ic",ful:"",ness:""},p="^("+(l="[^aeiou][^aeiouy]*")+")?"+(u=(c="[aeiouy]")+"[aeiou]*")+l+"("+u+")?$",d="^("+l+")?"+u+l+u+l,f="^("+l+")?"+c,m=new RegExp("^("+l+")?"+u+l),h=new RegExp(d),v=new RegExp(p),g=new RegExp(f),b=/^(.+?)(ss|i)es$/,y=/^(.+?)([^s])s$/,w=/^(.+?)eed$/,_=/^(.+?)(ed|ing)$/,x=/.$/,S=/(at|bl|iz)$/,k=new RegExp("([^aeiouylsz])\\1$"),E=new RegExp("^"+l+c+"[^aeiouwxy]$"),O=/^(.+?[^aeiou])y$/,j=/^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/,P=/^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/,C=/^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/,A=/^(.+?)(s|t)(ion)$/,T=/^(.+?)e$/,I=/ll$/,N=new RegExp("^"+l+c+"[^aeiouwxy]$"),L=function(e){var t,n,r,o,a,c,l;if(e.length<3)return e;if("y"==(r=e.substr(0,1))&&(e=r.toUpperCase()+e.substr(1)),a=y,(o=b).test(e)?e=e.replace(o,"$1$2"):a.test(e)&&(e=e.replace(a,"$1$2")),a=_,(o=w).test(e)){var u=o.exec(e);(o=m).test(u[1])&&(o=x,e=e.replace(o,""))}else a.test(e)&&(t=(u=a.exec(e))[1],(a=g).test(t)&&(c=k,l=E,(a=S).test(e=t)?e+="e":c.test(e)?(o=x,e=e.replace(o,"")):l.test(e)&&(e+="e")));return(o=O).test(e)&&(e=(t=(u=o.exec(e))[1])+"i"),(o=j).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+i[n])),(o=P).test(e)&&(t=(u=o.exec(e))[1],n=u[2],(o=m).test(t)&&(e=t+s[n])),a=A,(o=C).test(e)?(t=(u=o.exec(e))[1],(o=h).test(t)&&(e=t)):a.test(e)&&(t=(u=a.exec(e))[1]+u[2],(a=h).test(t)&&(e=t)),(o=T).test(e)&&(t=(u=o.exec(e))[1],a=v,c=N,((o=h).test(t)||a.test(t)&&!c.test(t))&&(e=t)),a=h,(o=I).test(e)&&a.test(e)&&(o=x,e=e.replace(o,"")),"y"==r&&(e=r.toLowerCase()+e.substr(1)),e},function(e){return e.update(L)}),R.Pipeline.registerFunction(R.stemmer,"stemmer"),R.generateStopWordFilter=function(e){var t=e.reduce((function(e,t){return e[t]=t,e}),{});return function(e){if(e&&t[e.toString()]!==e.toString())return e}},R.stopWordFilter=R.generateStopWordFilter(["a","able","about","across","after","all","almost","also","am","among","an","and","any","are","as","at","be","because","been","but","by","can","cannot","could","dear","did","do","does","either","else","ever","every","for","from","get","got","had","has","have","he","her","hers","him","his","how","however","i","if","in","into","is","it","its","just","least","let","like","likely","may","me","might","most","must","my","neither","no","nor","not","of","off","often","on","only","or","other","our","own","rather","said","say","says","she","should","since","so","some","than","that","the","their","them","then","there","these","they","this","tis","to","too","twas","us","wants","was","we","were","what","when","where","which","while","who","whom","why","will","with","would","yet","you","your"]),R.Pipeline.registerFunction(R.stopWordFilter,"stopWordFilter"),R.trimmer=function(e){return e.update((function(e){return e.replace(/^\W+/,"").replace(/\W+$/,"")}))},R.Pipeline.registerFunction(R.trimmer,"trimmer"),R.TokenSet=function(){this.final=!1,this.edges={},this.id=R.TokenSet._nextId,R.TokenSet._nextId+=1},R.TokenSet._nextId=1,R.TokenSet.fromArray=function(e){for(var t=new R.TokenSet.Builder,n=0,r=e.length;n<r;n++)t.insert(e[n]);return t.finish(),t.root},R.TokenSet.fromClause=function(e){return"editDistance"in e?R.TokenSet.fromFuzzyString(e.term,e.editDistance):R.TokenSet.fromString(e.term)},R.TokenSet.fromFuzzyString=function(e,t){for(var n=new R.TokenSet,r=[{node:n,editsRemaining:t,str:e}];r.length;){var o=r.pop();if(o.str.length>0){var a,i=o.str.charAt(0);i in o.node.edges?a=o.node.edges[i]:(a=new R.TokenSet,o.node.edges[i]=a),1==o.str.length&&(a.final=!0),r.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new R.TokenSet;o.node.edges["*"]=s}if(0==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var c=o.node.edges["*"];else{c=new R.TokenSet;o.node.edges["*"]=c}1==o.str.length&&(c.final=!0),r.push({node:c,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var l,u=o.str.charAt(0),p=o.str.charAt(1);p in o.node.edges?l=o.node.edges[p]:(l=new R.TokenSet,o.node.edges[p]=l),1==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},R.TokenSet.fromString=function(e){for(var t=new R.TokenSet,n=t,r=0,o=e.length;r<o;r++){var a=e[r],i=r==o-1;if("*"==a)t.edges[a]=t,t.final=i;else{var s=new R.TokenSet;s.final=i,t.edges[a]=s,t=s}}return n},R.TokenSet.prototype.toArray=function(){for(var e=[],t=[{prefix:"",node:this}];t.length;){var n=t.pop(),r=Object.keys(n.node.edges),o=r.length;n.node.final&&(n.prefix.charAt(0),e.push(n.prefix));for(var a=0;a<o;a++){var i=r[a];t.push({prefix:n.prefix.concat(i),node:n.node.edges[i]})}}return e},R.TokenSet.prototype.toString=function(){if(this._str)return this._str;for(var e=this.final?"1":"0",t=Object.keys(this.edges).sort(),n=t.length,r=0;r<n;r++){var o=t[r];e=e+o+this.edges[o].id}return e},R.TokenSet.prototype.intersect=function(e){for(var t=new R.TokenSet,n=void 0,r=[{qNode:e,output:t,node:this}];r.length;){n=r.pop();for(var o=Object.keys(n.qNode.edges),a=o.length,i=Object.keys(n.node.edges),s=i.length,c=0;c<a;c++)for(var l=o[c],u=0;u<s;u++){var p=i[u];if(p==l||"*"==l){var d=n.node.edges[p],f=n.qNode.edges[l],m=d.final&&f.final,h=void 0;p in n.output.edges?(h=n.output.edges[p]).final=h.final||m:((h=new R.TokenSet).final=m,n.output.edges[p]=h),r.push({qNode:f,output:h,node:d})}}}return t},R.TokenSet.Builder=function(){this.previousWord="",this.root=new R.TokenSet,this.uncheckedNodes=[],this.minimizedNodes={}},R.TokenSet.Builder.prototype.insert=function(e){var t,n=0;if(e<this.previousWord)throw new Error("Out of order word insertion");for(var r=0;r<e.length&&r<this.previousWord.length&&e[r]==this.previousWord[r];r++)n++;this.minimize(n),t=0==this.uncheckedNodes.length?this.root:this.uncheckedNodes[this.uncheckedNodes.length-1].child;for(r=n;r<e.length;r++){var o=new R.TokenSet,a=e[r];t.edges[a]=o,this.uncheckedNodes.push({parent:t,char:a,child:o}),t=o}t.final=!0,this.previousWord=e},R.TokenSet.Builder.prototype.finish=function(){this.minimize(0)},R.TokenSet.Builder.prototype.minimize=function(e){for(var t=this.uncheckedNodes.length-1;t>=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},R.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},R.Index.prototype.search=function(e){return this.query((function(t){new R.QueryParser(e,t).parse()}))},R.Index.prototype.query=function(e){for(var t=new R.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),i=Object.create(null),s=0;s<this.fields.length;s++)r[this.fields[s]]=new R.Vector;e.call(t,t);for(s=0;s<t.clauses.length;s++){var c=t.clauses[s],l=null,u=R.Set.empty;l=c.usePipeline?this.pipeline.runString(c.term,{fields:c.fields}):[c.term];for(var p=0;p<l.length;p++){var d=l[p];c.term=d;var f=R.TokenSet.fromClause(c),m=this.tokenSet.intersect(f).toArray();if(0===m.length&&c.presence===R.Query.presence.REQUIRED){for(var h=0;h<c.fields.length;h++){a[T=c.fields[h]]=R.Set.empty}break}for(var v=0;v<m.length;v++){var g=m[v],b=this.invertedIndex[g],y=b._index;for(h=0;h<c.fields.length;h++){var w=b[T=c.fields[h]],_=Object.keys(w),x=g+"/"+T,S=new R.Set(_);if(c.presence==R.Query.presence.REQUIRED&&(u=u.union(S),void 0===a[T]&&(a[T]=R.Set.complete)),c.presence!=R.Query.presence.PROHIBITED){if(r[T].upsert(y,c.boost,(function(e,t){return e+t})),!o[x]){for(var k=0;k<_.length;k++){var E,O=_[k],j=new R.FieldRef(O,T),P=w[O];void 0===(E=n[j])?n[j]=new R.MatchData(g,T,P):E.add(g,T,P)}o[x]=!0}}else void 0===i[T]&&(i[T]=R.Set.empty),i[T]=i[T].union(S)}}}if(c.presence===R.Query.presence.REQUIRED)for(h=0;h<c.fields.length;h++){a[T=c.fields[h]]=a[T].intersect(u)}}var C=R.Set.complete,A=R.Set.empty;for(s=0;s<this.fields.length;s++){var T;a[T=this.fields[s]]&&(C=C.intersect(a[T])),i[T]&&(A=A.union(i[T]))}var I=Object.keys(n),N=[],L=Object.create(null);if(t.isNegated()){I=Object.keys(this.fieldVectors);for(s=0;s<I.length;s++){j=I[s];var D=R.FieldRef.fromString(j);n[j]=new R.MatchData}}for(s=0;s<I.length;s++){var F=(D=R.FieldRef.fromString(I[s])).docRef;if(C.contains(F)&&!A.contains(F)){var M,B=this.fieldVectors[D],z=r[D.fieldName].similarity(B);if(void 0!==(M=L[F]))M.score+=z,M.matchData.combine(n[D]);else{var $={ref:F,score:z,matchData:n[D]};L[F]=$,N.push($)}}}return N.sort((function(e,t){return t.score-e.score}))},R.Index.prototype.toJSON=function(){var e=Object.keys(this.invertedIndex).sort().map((function(e){return[e,this.invertedIndex[e]]}),this),t=Object.keys(this.fieldVectors).map((function(e){return[e,this.fieldVectors[e].toJSON()]}),this);return{version:R.version,fields:this.fields,fieldVectors:t,invertedIndex:e,pipeline:this.pipeline.toJSON()}},R.Index.load=function(e){var t={},n={},r=e.fieldVectors,o=Object.create(null),a=e.invertedIndex,i=new R.TokenSet.Builder,s=R.Pipeline.load(e.pipeline);e.version!=R.version&&R.utils.warn("Version mismatch when loading serialised index. Current version of lunr '"+R.version+"' does not match serialized index '"+e.version+"'");for(var c=0;c<r.length;c++){var l=(p=r[c])[0],u=p[1];n[l]=new R.Vector(u)}for(c=0;c<a.length;c++){var p,d=(p=a[c])[0],f=p[1];i.insert(d),o[d]=f}return i.finish(),t.fields=e.fields,t.fieldVectors=n,t.invertedIndex=o,t.tokenSet=i.root,t.pipeline=s,new R.Index(t)},R.Builder=function(){this._ref="id",this._fields=Object.create(null),this._documents=Object.create(null),this.invertedIndex=Object.create(null),this.fieldTermFrequencies={},this.fieldLengths={},this.tokenizer=R.tokenizer,this.pipeline=new R.Pipeline,this.searchPipeline=new R.Pipeline,this.documentCount=0,this._b=.75,this._k1=1.2,this.termIndex=0,this.metadataWhitelist=[]},R.Builder.prototype.ref=function(e){this._ref=e},R.Builder.prototype.field=function(e,t){if(/\//.test(e))throw new RangeError("Field '"+e+"' contains illegal character '/'");this._fields[e]=t||{}},R.Builder.prototype.b=function(e){this._b=e<0?0:e>1?1:e},R.Builder.prototype.k1=function(e){this._k1=e},R.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o<r.length;o++){var a=r[o],i=this._fields[a].extractor,s=this._fields[a].isLiteral??!1,c=i?i(e):e[a],l=s?[c]:this.tokenizer(c,{fields:[a]}),u=s?l:this.pipeline.run(l),p=new R.FieldRef(n,a),d=Object.create(null);this.fieldTermFrequencies[p]=d,this.fieldLengths[p]=0,this.fieldLengths[p]+=u.length;for(var f=0;f<u.length;f++){var m=u[f];if(null==d[m]&&(d[m]=0),d[m]+=1,null==this.invertedIndex[m]){var h=Object.create(null);h._index=this.termIndex,this.termIndex+=1;for(var v=0;v<r.length;v++)h[r[v]]=Object.create(null);this.invertedIndex[m]=h}null==this.invertedIndex[m][a][n]&&(this.invertedIndex[m][a][n]=Object.create(null));for(var g=0;g<this.metadataWhitelist.length;g++){var b=this.metadataWhitelist[g],y=m.metadata[b];null==this.invertedIndex[m][a][n][b]&&(this.invertedIndex[m][a][n][b]=[]),this.invertedIndex[m][a][n][b].push(y)}}}},R.Builder.prototype.calculateAverageFieldLengths=function(){for(var e=Object.keys(this.fieldLengths),t=e.length,n={},r={},o=0;o<t;o++){var a=R.FieldRef.fromString(e[o]),i=a.fieldName;r[i]||(r[i]=0),r[i]+=1,n[i]||(n[i]=0),n[i]+=this.fieldLengths[a]}var s=Object.keys(this._fields);for(o=0;o<s.length;o++){var c=s[o];n[c]=n[c]/r[c]}this.averageFieldLength=n},R.Builder.prototype.createFieldVectors=function(){for(var e={},t=Object.keys(this.fieldTermFrequencies),n=t.length,r=Object.create(null),o=0;o<n;o++){for(var a=R.FieldRef.fromString(t[o]),i=a.fieldName,s=this.fieldLengths[a],c=new R.Vector,l=this.fieldTermFrequencies[a],u=Object.keys(l),p=u.length,d=this._fields[i].boost||1,f=this._documents[a.docRef].boost||1,m=0;m<p;m++){var h,v,g,b=u[m],y=l[b],w=this.invertedIndex[b]._index;void 0===r[b]?(h=R.idf(this.invertedIndex[b],this.documentCount),r[b]=h):h=r[b],v=h*((this._k1+1)*y)/(this._k1*(1-this._b+this._b*(s/this.averageFieldLength[i]))+y),v*=d,v*=f,g=Math.round(1e3*v)/1e3,c.insert(w,g)}e[a]=c}this.fieldVectors=e},R.Builder.prototype.createTokenSet=function(){this.tokenSet=R.TokenSet.fromArray(Object.keys(this.invertedIndex).sort())},R.Builder.prototype.build=function(){return this.calculateAverageFieldLengths(),this.createFieldVectors(),this.createTokenSet(),new R.Index({invertedIndex:this.invertedIndex,fieldVectors:this.fieldVectors,tokenSet:this.tokenSet,fields:Object.keys(this._fields),pipeline:this.searchPipeline})},R.Builder.prototype.use=function(e){var t=Array.prototype.slice.call(arguments,1);t.unshift(this),e.apply(this,t)},R.MatchData=function(e,t,n){for(var r=Object.create(null),o=Object.keys(n||{}),a=0;a<o.length;a++){var i=o[a];r[i]=n[i].slice()}this.metadata=Object.create(null),void 0!==e&&(this.metadata[e]=Object.create(null),this.metadata[e][t]=r)},R.MatchData.prototype.combine=function(e){for(var t=Object.keys(e.metadata),n=0;n<t.length;n++){var r=t[n],o=Object.keys(e.metadata[r]);null==this.metadata[r]&&(this.metadata[r]=Object.create(null));for(var a=0;a<o.length;a++){var i=o[a],s=Object.keys(e.metadata[r][i]);null==this.metadata[r][i]&&(this.metadata[r][i]=Object.create(null));for(var c=0;c<s.length;c++){var l=s[c];null==this.metadata[r][i][l]?this.metadata[r][i][l]=e.metadata[r][i][l]:this.metadata[r][i][l]=this.metadata[r][i][l].concat(e.metadata[r][i][l])}}}},R.MatchData.prototype.add=function(e,t,n){if(!(e in this.metadata))return this.metadata[e]=Object.create(null),void(this.metadata[e][t]=n);if(t in this.metadata[e])for(var r=Object.keys(n),o=0;o<r.length;o++){var a=r[o];a in this.metadata[e][t]?this.metadata[e][t][a]=this.metadata[e][t][a].concat(n[a]):this.metadata[e][t][a]=n[a]}else this.metadata[e][t]=n},R.Query=function(e){this.clauses=[],this.allFields=e},R.Query.wildcard=new String("*"),R.Query.wildcard.NONE=0,R.Query.wildcard.LEADING=1,R.Query.wildcard.TRAILING=2,R.Query.presence={OPTIONAL:1,REQUIRED:2,PROHIBITED:3},R.Query.prototype.clause=function(e){return"fields"in e||(e.fields=this.allFields),"boost"in e||(e.boost=1),"usePipeline"in e||(e.usePipeline=!0),"wildcard"in e||(e.wildcard=R.Query.wildcard.NONE),e.wildcard&R.Query.wildcard.LEADING&&e.term.charAt(0)!=R.Query.wildcard&&(e.term="*"+e.term),e.wildcard&R.Query.wildcard.TRAILING&&e.term.slice(-1)!=R.Query.wildcard&&(e.term=e.term+"*"),"presence"in e||(e.presence=R.Query.presence.OPTIONAL),this.clauses.push(e),this},R.Query.prototype.isNegated=function(){for(var e=0;e<this.clauses.length;e++)if(this.clauses[e].presence!=R.Query.presence.PROHIBITED)return!1;return!0},R.Query.prototype.term=function(e,t){if(Array.isArray(e))return e.forEach((function(e){this.term(e,R.utils.clone(t))}),this),this;var n=t||{};return n.term=e.toString(),this.clause(n),this},R.QueryParseError=function(e,t,n){this.name="QueryParseError",this.message=e,this.start=t,this.end=n},R.QueryParseError.prototype=new Error,R.QueryLexer=function(e){this.lexemes=[],this.str=e,this.length=e.length,this.pos=0,this.start=0,this.escapeCharPositions=[]},R.QueryLexer.prototype.run=function(){for(var e=R.QueryLexer.lexText;e;)e=e(this)},R.QueryLexer.prototype.sliceString=function(){for(var e=[],t=this.start,n=this.pos,r=0;r<this.escapeCharPositions.length;r++)n=this.escapeCharPositions[r],e.push(this.str.slice(t,n)),t=n+1;return e.push(this.str.slice(t,this.pos)),this.escapeCharPositions.length=0,e.join("")},R.QueryLexer.prototype.emit=function(e){this.lexemes.push({type:e,str:this.sliceString(),start:this.start,end:this.pos}),this.start=this.pos},R.QueryLexer.prototype.escapeCharacter=function(){this.escapeCharPositions.push(this.pos-1),this.pos+=1},R.QueryLexer.prototype.next=function(){if(this.pos>=this.length)return R.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},R.QueryLexer.prototype.width=function(){return this.pos-this.start},R.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},R.QueryLexer.prototype.backup=function(){this.pos-=1},R.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=R.QueryLexer.EOS&&this.backup()},R.QueryLexer.prototype.more=function(){return this.pos<this.length},R.QueryLexer.EOS="EOS",R.QueryLexer.FIELD="FIELD",R.QueryLexer.TERM="TERM",R.QueryLexer.EDIT_DISTANCE="EDIT_DISTANCE",R.QueryLexer.BOOST="BOOST",R.QueryLexer.PRESENCE="PRESENCE",R.QueryLexer.lexField=function(e){return e.backup(),e.emit(R.QueryLexer.FIELD),e.ignore(),R.QueryLexer.lexText},R.QueryLexer.lexTerm=function(e){if(e.width()>1&&(e.backup(),e.emit(R.QueryLexer.TERM)),e.ignore(),e.more())return R.QueryLexer.lexText},R.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.EDIT_DISTANCE),R.QueryLexer.lexText},R.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.BOOST),R.QueryLexer.lexText},R.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(R.QueryLexer.TERM)},R.QueryLexer.termSeparator=R.tokenizer.separator,R.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==R.QueryLexer.EOS)return R.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return R.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if(t.match(R.QueryLexer.termSeparator))return R.QueryLexer.lexTerm}else e.escapeCharacter()}},R.QueryParser=function(e,t){this.lexer=new R.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},R.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=R.QueryParser.parseClause;e;)e=e(this);return this.query},R.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},R.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},R.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},R.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case R.QueryLexer.PRESENCE:return R.QueryParser.parsePresence;case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new R.QueryParseError(n,t.start,t.end)}},R.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=R.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=R.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new R.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new R.QueryParseError(n,t.start,t.end)}switch(r.type){case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new R.QueryParseError(n,r.start,r.end)}}},R.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new R.QueryParseError(r,t.start,t.end)}if(o.type===R.QueryLexer.TERM)return R.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}},R.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new R.QueryParseError(r,n.start,n.end)}else e.nextClause()}},R.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},R.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return R})?r.call(t,n,t,e):r)||(e.exports=o)}()},71555:(e,t,n)=>{"use strict";n.d(t,{o:()=>a,x:()=>i});var r=n(96540),o=n(74848);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},20979:(e,t,n)=>{"use strict";var r=n(96540),o=n(5338),a=n(80545),i=n(54625),s=n(4784),c=n(71191);const l=[n(42245),n(85300),n(16547),n(36232),n(58252)];var u=n(38858),p=n(56347),d=n(22831),f=n(74848);function m(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var h=n(24502),v=n(25792),g=n(24763),b=n(31436),y=n(63523),w=n(62473),_=n(2920),x=n(59529),S=n(9458),k=n(28505);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,v.A)(),r=(0,w.o)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,f.jsxs)(h.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function O(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,v.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,v.A)(),{pathname:r}=(0,p.zy)();return e+(0,S.Ks)((0,g.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:o}),(0,f.jsx)("link",{rel:"canonical",href:o})]})}function j(){const{i18n:{currentLocale:e}}=(0,v.A)(),{metadata:t,image:n}=(0,b.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:_.w})]}),n&&(0,f.jsx)(y.be,{image:n}),(0,f.jsx)(O,{}),(0,f.jsx)(E,{}),(0,f.jsx)(k.A,{tag:x.C,locale:e}),(0,f.jsx)(h.A,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const P=new Map;var C=n(71555),A=n(5705),T=n(68963);function I(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const o=l.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,T.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),I("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function L(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=c.A.canUseDOM?I("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=I("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),L(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(p.qh,{location:t,render:()=>e})})}}const D=R,F="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",B="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${F}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${B}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${B}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function $(){const{siteConfig:{baseUrl:e}}=(0,v.A)();return(0,f.jsx)(f.Fragment,{children:!c.A.canUseDOM&&(0,f.jsx)(h.A,{children:(0,f.jsx)("script",{children:z(e)})})})}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,v.A)(),{pathname:n}=(0,p.zy)();return t&&n===e?(0,f.jsx)($,{}):null}function H(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,v.A)(),a=(0,g.Ay)(e),{htmlLang:i,direction:s}=o[r];return(0,f.jsxs)(h.A,{children:[(0,f.jsx)("html",{lang:i,dir:s}),(0,f.jsx)("title",{children:t}),(0,f.jsx)("meta",{property:"og:title",content:t}),(0,f.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,f.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,f.jsx)("link",{rel:"icon",href:a})]})}var V=n(50035),W=n(94753);function Q(){const e=(0,W.A)();return(0,f.jsx)(h.A,{children:(0,f.jsx)("html",{"data-has-hydrated":e})})}const q=(0,d.v)(u.A);function G(){const e=function(e){if(P.has(e.pathname))return{...e,pathname:P.get(e.pathname)};if((0,d.u)(u.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return P.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return P.set(e.pathname,t),{...e,pathname:t}}((0,p.zy)());return(0,f.jsx)(D,{location:e,children:q})}function K(){return(0,f.jsx)(V.A,{children:(0,f.jsx)(A.l,{children:(0,f.jsxs)(C.x,{children:[(0,f.jsxs)(m,{children:[(0,f.jsx)(H,{}),(0,f.jsx)(j,{}),(0,f.jsx)(U,{}),(0,f.jsx)(G,{})]}),(0,f.jsx)(Q,{})]})})})}var Y=n(84054);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var X=n(6367);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,d.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(Y).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,X.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),L(e))},re=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===s.A.future.experimental_router?(0,f.jsx)(i.I9,{children:t}):(0,f.jsx)(i.Kd,{children:t})}const ae=Boolean(!0);if(c.A.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(a.vd,{children:(0,f.jsx)(oe,{children:(0,f.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},i=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(ae)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};L(window.location.pathname).then((()=>{(0,r.startTransition)(i)}))}},5705:(e,t,n)=>{"use strict";n.d(t,{o:()=>p,l:()=>d});var r=n(96540),o=n(4784);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/contrast/pr-preview/pr-976/","versions":[{"name":"current","label":"Next","isLast":false,"path":"/contrast/pr-preview/pr-976/next","mainDocId":"intro","docs":[{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/next/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/next/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/next/architecture/certificates","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/next/architecture/observability","sidebar":"docs"},{"id":"architecture/secrets","path":"/contrast/pr-preview/pr-976/next/architecture/secrets","sidebar":"docs"},{"id":"architecture/security-considerations","path":"/contrast/pr-preview/pr-976/next/architecture/security-considerations","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/next/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/next/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/next/basics/security-benefits","sidebar":"docs"},{"id":"components/overview","path":"/contrast/pr-preview/pr-976/next/components/overview","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/next/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/next/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/next/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/next/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/next/examples/emojivoto","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/next/features-limitations","sidebar":"docs"},{"id":"getting-started/bare-metal","path":"/contrast/pr-preview/pr-976/next/getting-started/bare-metal","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/next/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/next/","sidebar":"docs"},{"id":"troubleshooting","path":"/contrast/pr-preview/pr-976/next/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/next/","label":"What is Contrast?"}}}},{"name":"1.1","label":"1.1","isLast":true,"path":"/contrast/pr-preview/pr-976/","mainDocId":"intro","docs":[{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/architecture/certificates","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/architecture/observability","sidebar":"docs"},{"id":"architecture/secrets","path":"/contrast/pr-preview/pr-976/architecture/secrets","sidebar":"docs"},{"id":"architecture/security-considerations","path":"/contrast/pr-preview/pr-976/architecture/security-considerations","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/basics/security-benefits","sidebar":"docs"},{"id":"components/overview","path":"/contrast/pr-preview/pr-976/components/overview","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/examples/emojivoto","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/features-limitations","sidebar":"docs"},{"id":"getting-started/bare-metal","path":"/contrast/pr-preview/pr-976/getting-started/bare-metal","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/","sidebar":"docs"},{"id":"troubleshooting","path":"/contrast/pr-preview/pr-976/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/","label":"What is Contrast?"}}}},{"name":"1.0","label":"1.0","isLast":false,"path":"/contrast/pr-preview/pr-976/1.0","mainDocId":"intro","docs":[{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/1.0/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/1.0/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/1.0/architecture/certificates","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/1.0/architecture/observability","sidebar":"docs"},{"id":"architecture/secrets","path":"/contrast/pr-preview/pr-976/1.0/architecture/secrets","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/1.0/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/1.0/basics/security-benefits","sidebar":"docs"},{"id":"components/overview","path":"/contrast/pr-preview/pr-976/1.0/components/overview","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/1.0/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/1.0/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/1.0/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/1.0/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/1.0/examples/emojivoto","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/1.0/features-limitations","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/1.0/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/1.0/","sidebar":"docs"},{"id":"troubleshooting","path":"/contrast/pr-preview/pr-976/1.0/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/1.0/","label":"What is Contrast?"}}}},{"name":"0.9","label":"0.9","isLast":false,"path":"/contrast/pr-preview/pr-976/0.9","mainDocId":"intro","docs":[{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/0.9/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/0.9/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/0.9/architecture/certificates","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/0.9/architecture/observability","sidebar":"docs"},{"id":"architecture/secrets","path":"/contrast/pr-preview/pr-976/0.9/architecture/secrets","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/0.9/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/0.9/basics/security-benefits","sidebar":"docs"},{"id":"components/overview","path":"/contrast/pr-preview/pr-976/0.9/components/overview","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/0.9/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/0.9/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/0.9/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/0.9/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/0.9/examples/emojivoto","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/0.9/features-limitations","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/0.9/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/0.9/","sidebar":"docs"},{"id":"troubleshooting","path":"/contrast/pr-preview/pr-976/0.9/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/0.9/","label":"What is Contrast?"}}}},{"name":"0.8","label":"0.8","isLast":false,"path":"/contrast/pr-preview/pr-976/0.8","mainDocId":"intro","docs":[{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/0.8/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/0.8/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/0.8/architecture/certificates","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/0.8/architecture/observability","sidebar":"docs"},{"id":"architecture/secrets","path":"/contrast/pr-preview/pr-976/0.8/architecture/secrets","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/0.8/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/0.8/basics/security-benefits","sidebar":"docs"},{"id":"components/overview","path":"/contrast/pr-preview/pr-976/0.8/components/overview","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/0.8/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/0.8/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/0.8/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/0.8/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/0.8/examples/emojivoto","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/0.8/features-limitations","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/0.8/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/0.8/","sidebar":"docs"},{"id":"troubleshooting","path":"/contrast/pr-preview/pr-976/0.8/troubleshooting","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/0.8/","label":"What is Contrast?"}}}},{"name":"0.7","label":"0.7","isLast":false,"path":"/contrast/pr-preview/pr-976/0.7","mainDocId":"intro","docs":[{"id":"about/index","path":"/contrast/pr-preview/pr-976/0.7/about/","sidebar":"docs"},{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/0.7/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/0.7/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/0.7/architecture/certificates","sidebar":"docs"},{"id":"architecture/index","path":"/contrast/pr-preview/pr-976/0.7/architecture/","sidebar":"docs"},{"id":"architecture/observability","path":"/contrast/pr-preview/pr-976/0.7/architecture/observability","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/0.7/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/0.7/basics/security-benefits","sidebar":"docs"},{"id":"components/index","path":"/contrast/pr-preview/pr-976/0.7/components/","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/0.7/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/0.7/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/0.7/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/0.7/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/0.7/examples/emojivoto","sidebar":"docs"},{"id":"examples/index","path":"/contrast/pr-preview/pr-976/0.7/examples/","sidebar":"docs"},{"id":"features-limitations","path":"/contrast/pr-preview/pr-976/0.7/features-limitations","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/index","path":"/contrast/pr-preview/pr-976/0.7/getting-started/","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/0.7/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/0.7/","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/0.7/","label":"What is Contrast?"}}}},{"name":"0.6","label":"0.6","isLast":false,"path":"/contrast/pr-preview/pr-976/0.6","mainDocId":"intro","docs":[{"id":"about/index","path":"/contrast/pr-preview/pr-976/0.6/about/","sidebar":"docs"},{"id":"about/telemetry","path":"/contrast/pr-preview/pr-976/0.6/about/telemetry","sidebar":"docs"},{"id":"architecture/attestation","path":"/contrast/pr-preview/pr-976/0.6/architecture/attestation","sidebar":"docs"},{"id":"architecture/certificates","path":"/contrast/pr-preview/pr-976/0.6/architecture/certificates","sidebar":"docs"},{"id":"architecture/index","path":"/contrast/pr-preview/pr-976/0.6/architecture/","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/0.6/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits","sidebar":"docs"},{"id":"components/index","path":"/contrast/pr-preview/pr-976/0.6/components/","sidebar":"docs"},{"id":"components/policies","path":"/contrast/pr-preview/pr-976/0.6/components/policies","sidebar":"docs"},{"id":"components/runtime","path":"/contrast/pr-preview/pr-976/0.6/components/runtime","sidebar":"docs"},{"id":"components/service-mesh","path":"/contrast/pr-preview/pr-976/0.6/components/service-mesh","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/0.6/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto","sidebar":"docs"},{"id":"examples/index","path":"/contrast/pr-preview/pr-976/0.6/examples/","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/index","path":"/contrast/pr-preview/pr-976/0.6/getting-started/","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/0.6/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/0.6/","sidebar":"docs"},{"id":"known-limitations","path":"/contrast/pr-preview/pr-976/0.6/known-limitations","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/0.6/","label":"What is Contrast?"}}}},{"name":"0.5","label":"0.5","isLast":false,"path":"/contrast/pr-preview/pr-976/0.5","mainDocId":"intro","docs":[{"id":"architecture/attestation/coordinator","path":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator","sidebar":"docs"},{"id":"architecture/attestation/hardware","path":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware","sidebar":"docs"},{"id":"architecture/attestation/manifest","path":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest","sidebar":"docs"},{"id":"architecture/attestation/pod-vm","path":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm","sidebar":"docs"},{"id":"architecture/attestation/runtime-policies","path":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies","sidebar":"docs"},{"id":"architecture/certificates-and-identities/pki","path":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki","sidebar":"docs"},{"id":"architecture/components/cli","path":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli","sidebar":"docs"},{"id":"architecture/components/coordinator","path":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator","sidebar":"docs"},{"id":"architecture/components/init-container","path":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container","sidebar":"docs"},{"id":"architecture/confidential-containers","path":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers","sidebar":"docs"},{"id":"architecture/index","path":"/contrast/pr-preview/pr-976/0.5/architecture/","sidebar":"docs"},{"id":"architecture/network-encryption/protocols-and-keys","path":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys","sidebar":"docs"},{"id":"architecture/network-encryption/sidecar","path":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar","sidebar":"docs"},{"id":"basics/confidential-containers","path":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers","sidebar":"docs"},{"id":"basics/features","path":"/contrast/pr-preview/pr-976/0.5/basics/features","sidebar":"docs"},{"id":"basics/security-benefits","path":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits","sidebar":"docs"},{"id":"deployment","path":"/contrast/pr-preview/pr-976/0.5/deployment","sidebar":"docs"},{"id":"examples/emojivoto","path":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto","sidebar":"docs"},{"id":"examples/index","path":"/contrast/pr-preview/pr-976/0.5/examples/","sidebar":"docs"},{"id":"getting-started/cluster-setup","path":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup","sidebar":"docs"},{"id":"getting-started/first-steps","path":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps","sidebar":"docs"},{"id":"getting-started/index","path":"/contrast/pr-preview/pr-976/0.5/getting-started/","sidebar":"docs"},{"id":"getting-started/install","path":"/contrast/pr-preview/pr-976/0.5/getting-started/install","sidebar":"docs"},{"id":"intro","path":"/contrast/pr-preview/pr-976/0.5/","sidebar":"docs"},{"id":"/category/components","path":"/contrast/pr-preview/pr-976/0.5/category/components","sidebar":"docs"},{"id":"/category/attestation","path":"/contrast/pr-preview/pr-976/0.5/category/attestation","sidebar":"docs"},{"id":"/category/certificates-and-identities","path":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities","sidebar":"docs"},{"id":"/category/network-encryption","path":"/contrast/pr-preview/pr-976/0.5/category/network-encryption","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/contrast/pr-preview/pr-976/0.5/","label":"What is Contrast?"}}}}],"breadcrumbs":true}},"docusaurus-plugin-google-gtag":{"default":{"trackingID":["G-3DVYB2CHLG"],"anonymizeIP":true,"id":"default"}},"@cmfcmf/docusaurus-search-local":{"default":{"titleBoost":5,"contentBoost":1,"tagsBoost":3,"parentCategoriesBoost":2,"indexDocSidebarParentCategories":0,"maxSearchResults":8}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(22654);const c=JSON.parse('{"docusaurusVersion":"3.6.0","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.6.0"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.6.0"},"docusaurus-plugin-google-gtag":{"type":"package","name":"@docusaurus/plugin-google-gtag","version":"3.6.0"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.6.0"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.6.0"},"@cmfcmf/docusaurus-search-local":{"type":"package","name":"@cmfcmf/docusaurus-search-local","version":"1.2.0"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.6.0"}}}');var l=n(74848);const u={siteConfig:o.A,siteMetadata:c,globalData:a,i18n:i,codeTranslations:s},p=r.createContext(u);function d(e){let{children:t}=e;return(0,l.jsx)(p.Provider,{value:u,children:t})}},50035:(e,t,n)=>{"use strict";n.d(t,{A:()=>h});var r=n(96540),o=n(71191),a=n(24502),i=n(9458),s=n(83502),c=n(92764),l=n(74848);function u(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(p,{error:t})]})}function p(e){let{error:t}=e;const n=(0,i.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{children:t}=e;return(0,l.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,l.jsx)(d,{children:(0,l.jsxs)(h,{fallback:()=>(0,l.jsx)(u,{error:t,tryAgain:n}),children:[(0,l.jsx)(a.A,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.A,{children:(0,l.jsx)(u,{error:t,tryAgain:n})})]})})}const m=e=>(0,l.jsx)(f,{...e});class h extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},71191:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},24502:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);var r=n(80545),o=n(74848);function a(e){return(0,o.jsx)(r.mg,{...e})}},57880:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(96540),o=n(54625),a=n(9458),i=n(25792),s=n(77056),c=n(71191),l=n(97756),u=n(24763),p=n(74848);function d(e,t){let{isNavLink:n,to:d,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":v,autoAddBaseUrl:g=!0,...b}=e;const{siteConfig:y}=(0,i.A)(),{trailingSlash:w,baseUrl:_}=y,x=y.future.experimental_router,{withBaseUrl:S}=(0,u.hH)(),k=(0,l.A)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const O=d||f;const j=(0,s.A)(O),P=O?.replace("pathname://","");let C=void 0!==P?(A=P,g&&(e=>e.startsWith("/"))(A)?S(A):A):void 0;var A;"hash"===x&&C?.startsWith("./")&&(C=C?.slice(1)),C&&j&&(C=(0,a.Ks)(C,{trailingSlash:w,baseUrl:_}));const T=(0,r.useRef)(!1),I=n?o.k2:o.N_,N=c.A.canUseIntersectionObserver,L=(0,r.useRef)(),R=()=>{T.current||null==C||(window.docusaurus.preload(C),T.current=!0)};(0,r.useEffect)((()=>(!N&&j&&c.A.canUseDOM&&null!=C&&window.docusaurus.prefetch(C),()=>{N&&L.current&&L.current.disconnect()})),[L,C,N,j]);const D=C?.startsWith("#")??!1,F=!b.target||"_self"===b.target,M=!C||!j||!F||D&&"hash"!==x;v||!D&&M||k.collectLink(C),b.id&&k.collectAnchor(b.id);const B={};return M?(0,p.jsx)("a",{ref:E,href:C,...O&&!j&&{target:"_blank",rel:"noopener noreferrer"},...b,...B}):(0,p.jsx)(I,{...b,onMouseEnter:R,onTouchStart:R,innerRef:e=>{E.current=e,N&&e&&j&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=C&&window.docusaurus.prefetch(C))}))})),L.current.observe(e))},to:C,...n&&{isActive:h,activeClassName:m},...B})}const f=r.forwardRef(d)},32032:(e,t,n)=>{"use strict";n.d(t,{A:()=>l,T:()=>c});var r=n(96540),o=n(74848);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(22654);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function c(e,t){let{message:n,id:r}=e;return a(s({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const i=s({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},6583:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},77056:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},24763:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>s,hH:()=>i});var r=n(96540),o=n(25792),a=n(77056);function i(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,i=e.future.experimental_router,s=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:i=!1}={},router:s}=e;if(!r||r.startsWith("#")||(0,a.z)(r))return r;if("hash"===s)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const c=r.startsWith(n)?r:n+r.replace(/^\//,"");return i?t+c:c}({siteUrl:n,baseUrl:t,url:e,options:r,router:i})),[n,t,i]);return{withBaseUrl:s}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},97756:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(96540);n(74848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},25792:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(96540),o=n(5705);function a(){return(0,r.useContext)(o.o)}},62114:(e,t,n)=>{"use strict";n.d(t,{P_:()=>i,kh:()=>a});var r=n(25792),o=n(6583);function a(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,r.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}function i(e,t,n){void 0===t&&(t=o.W),void 0===n&&(n={});const r=a(e),i=r?.[t];if(!i&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return i}},94753:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(96540),o=n(71555);function a(){return(0,r.useContext)(o.o)}},68963:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(96540);const o=n(71191).A.canUseDOM?r.useLayoutEffect:r.useEffect},6367:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const s=o?`${o}.${a}`:a;r(i)?e(i,s):t[s]=i}))}(e),t}},92764:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>a});var r=n(96540),o=n(74848);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:s,children:t})}},36220:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>v,XK:()=>y,g1:()=>b});var r=n(96540),o=n(80869),a=n(6583),i=n(31436),s=n(45054),c=n(15302),l=n(74848);const u=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,s.Wf)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,s.Wf)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,s.Wf)(u(e),{persistence:t}).del()}},d=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function m(){const e=(0,o.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,s]=(0,r.useState)((()=>d(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function h(e){let{children:t}=e;const n=m();return(0,l.jsx)(f.Provider,{value:n,children:t})}function v(e){let{children:t}=e;return(0,l.jsx)(h,{children:t})}function g(){const e=(0,r.useContext)(f);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function b(e){void 0===e&&(e=a.W);const t=(0,o.ht)(e),[n,i]=g(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}function y(){const e=(0,o.Gy)(),[t]=g();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},95947:(e,t,n)=>{"use strict";n.d(t,{k:()=>a,v:()=>i});var r=n(80869),o=n(36220);function a(e,t){return`docs-${e}-${t}`}function i(){const e=(0,r.Gy)(),t=(0,r.gk)(),n=(0,o.XK)();return[...Object.keys(e).map((function(r){const o=t?.activePlugin.pluginId===r?t.activeVersion:void 0,i=n[r],s=e[r].versions.find((e=>e.isLast));return a(r,(o??i??s).name)}))]}},5779:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>l});var r=n(96540),o=n(15302),a=n(74848);const i=Symbol("EmptyContext"),s=r.createContext(i);function c(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(s.Provider,{value:i,children:t})}function l(){const e=(0,r.useContext)(s);if(e===i)throw new o.dV("DocsSidebarProvider");return e}},85246:(e,t,n)=>{"use strict";n.d(t,{$S:()=>m,B5:()=>E,Nr:()=>f,OF:()=>_,QB:()=>k,Vd:()=>x,Y:()=>y,cC:()=>d,d1:()=>O,fW:()=>S,w8:()=>g});var r=n(96540),o=n(56347),a=n(22831),i=n(80869),s=n(86707),c=n(52808),l=n(36220),u=n(18875),p=n(5779);function d(e){const t=(0,u.r)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function f(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=f(t);if(e)return e}}(e):void 0:e.href}function m(){const{pathname:e}=(0,o.zy)(),t=(0,p.t)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=w({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const h=(e,t)=>void 0!==e&&(0,s.ys)(e,t),v=(e,t)=>e.some((e=>g(e,t)));function g(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||v(e.items,t))}function b(e,t){switch(e.type){case"category":return g(e,t)||e.items.some((e=>b(e,t)));case"link":return!e.unlisted||g(e,t);default:return!0}}function y(e,t){return(0,r.useMemo)((()=>e.filter((e=>b(e,t)))),[e,t])}function w(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,s.ys)(a.href,n)||e(a.items))||"link"===a.type&&(0,s.ys)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function _(){const e=(0,p.t)(),{pathname:t}=(0,o.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?w({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,l.g1)(e),o=(0,i.r7)(e);return(0,r.useMemo)((()=>(0,c.sb)([t,n,o].filter(Boolean))),[t,n,o])}function S(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,u.r)(),i=t.routes,s=i.find((e=>(0,o.B6)(n.pathname,e)));if(!s)return null;const c=s.sidebar,l=c?r.docsSidebars[c]:void 0;return{docElement:(0,a.v)(i),sidebarName:c,sidebarItems:l}}function O(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!f(e)))}},18875:(e,t,n)=>{"use strict";n.d(t,{n:()=>s,r:()=>c});var r=n(96540),o=n(15302),a=n(74848);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(null===e)throw new o.dV("DocsVersionProvider");return e}},80869:(e,t,n)=>{"use strict";n.d(t,{d1:()=>c.d1,zK:()=>b,vT:()=>m,gk:()=>h,Gy:()=>d,$S:()=>c.$S,HW:()=>y,vF:()=>u.v,ht:()=>f,g1:()=>l.g1,r7:()=>g,jh:()=>v});var r=n(56347),o=n(62114);const a=e=>e.versions.find((e=>e.isLast));function i(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}function s(e,t){const n=i(e,t),o=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}var c=n(85246),l=n(36220),u=n(95947);const p={},d=()=>(0,o.kh)("docusaurus-plugin-content-docs")??p,f=e=>{try{return(0,o.P_)("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function m(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function h(e){void 0===e&&(e={});const t=m(e),{pathname:n}=(0,r.zy)();if(!t)return;return{activePlugin:t,activeVersion:i(t.pluginData,n)}}function v(e){return f(e).versions}function g(e){const t=f(e);return a(t)}function b(e){const t=f(e),{pathname:n}=(0,r.zy)();return s(t,n)}function y(e){const t=f(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=a(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},42245:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>r});const r={onRouteDidUpdate(e){let{location:t,previousLocation:n}=e;!n||t.pathname===n.pathname&&t.search===n.search&&t.hash===n.hash||setTimeout((()=>{window.gtag("set","page_path",t.pathname+t.search+t.hash),window.gtag("event","page_view")}))}}},36232:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(5947),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},16547:(e,t,n)=>{"use strict";var r=n(71765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.A,{additionalLanguages:r}=t,a=globalThis.Prism;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(19700),n(97553)(`./prism-${e}`)})),delete globalThis.Prism,void 0!==a&&(globalThis.Prism=e)}(r.My)},98445:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var r=n(34164),o=n(32032),a=n(31436),i=n(57880),s=n(97756);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(74848);function u(e){let{as:t,id:n,...u}=e;const p=(0,s.A)(),{navbar:{hideOnScroll:d}}=(0,a.p)();if("h1"===t||!n)return(0,l.jsx)(t,{...u,id:void 0});p.collectAnchor(n);const f=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,l.jsxs)(t,{...u,className:(0,r.A)("anchor",d?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,l.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},88584:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(74848);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},83502:(e,t,n)=>{"use strict";n.d(t,{A:()=>si});var r=n(96540),o=n(34164),a=n(50035),i=n(63523),s=n(56347),c=n(32032),l=n(24232),u=n(74848);const p="__docusaurus_skipToContent_fallback";function d(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(p);t&&d(t)}),[]);return(0,l.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&d(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${p}`,onClick:r,children:t})})}var v=n(74717),g=n(2920);const b={skipToContent:"skipToContent_fXgn"};function y(){return(0,u.jsx)(h,{className:b.skipToContent})}var w=n(31436),_=n(82459);function x(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function k(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",S.closeButton,e.className),children:(0,u.jsx)(x,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function O(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const j={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function P(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,_.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:j.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:j.announcementBarPlaceholder}),(0,u.jsx)(O,{className:j.announcementBarContent}),a&&(0,u.jsx)(k,{onClick:n,className:j.announcementBarClose})]})}var C=n(1227),A=n(53622);var T=n(15302),I=n(67078);const N=r.createContext(null);function L(e){let{children:t}=e;const n=function(){const e=(0,C.M)(),t=(0,I.YL)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,T.ZC)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(N.Provider,{value:n,children:t})}function R(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new T.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,I.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:R(a)})),[o,a,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=D();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(65331),B=n(94753);function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function H(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,B.A)(),s=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.A)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.A)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite","aria-pressed":"dark"===r?"true":"false",children:[(0,u.jsx)(z,{className:(0,o.A)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)($,{className:(0,o.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const V=r.memo(H),W={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Q(e){let{className:t}=e;const n=(0,w.p)().navbar.style,r=(0,w.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,M.G)();return r?null:(0,u.jsx)(V,{className:t,buttonClassName:"dark"===n?W.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var q=n(979);function G(){return(0,u.jsx)(q.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,C.M)();return(0,u.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(x,{color:"var(--ifm-color-emphasis-600)"})})}function Y(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(G,{}),(0,u.jsx)(Q,{className:"margin-right--md"}),(0,u.jsx)(K,{})]})}var Z=n(57880),X=n(24763),J=n(77056);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(88584);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:s,prependBaseUrlToHref:c,...l}=e;const p=(0,X.Ay)(r),d=(0,X.Ay)(t),f=(0,X.Ay)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.A)(o),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,m&&(0,u.jsx)(te.A,{...s&&{width:12,height:12}})]})};return o?(0,u.jsx)(Z.A,{href:c?f:o,...l,...h}):(0,u.jsx)(Z.A,{to:p,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(d)},...l,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(70936),se=n(86707),ce=n(25792);const le={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,se.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function pe(e){let{items:t,position:n,className:a,onClick:i,...s}=e;const c=(0,r.useRef)(null),[l,p]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&p(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,u.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":l}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:s.to?void 0:"#",className:(0,o.A)("navbar__link",a),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),p(!l))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Sa,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function de(e){let{items:t,className:n,position:a,onClick:i,...c}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,s.zy)();return t.replace(e,"/")}(),p=ue(t,l),{collapsed:d,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!p});return(0,r.useEffect)((()=>{p&&m(!p)}),[l,p,m]),(0,u.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":d}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.A)(le.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),f()},children:c.children??c.label}),(0,u.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:d,children:t.map(((e,t)=>(0,r.createElement)(Sa,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?de:pe;return(0,u.jsx)(r,{...n})}var me=n(62473);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ve="iconLanguage_nlXk";var ge=n(40961);function be(e,t){var n=void 0;return function(){for(var r=arguments.length,o=new Array(r),a=0;a<r;a++)o[a]=arguments[a];n&&clearTimeout(n),n=setTimeout((function(){return e.apply(void 0,o)}),t)}}function ye(e){return{current:e}}function we(e){return e!==Object(e)}function _e(e,t){if(e===t)return!0;if(we(e)||we(t)||"function"==typeof e||"function"==typeof t)return e===t;if(Object.keys(e).length!==Object.keys(t).length)return!1;for(var n=0,r=Object.keys(e);n<r.length;n++){var o=r[n];if(!(o in t))return!1;if(!_e(e[o],t[o]))return!1}return!0}var xe=function(){};function Se(e){var t=e.item,n=e.items,r=void 0===n?[]:n;return{index:t.__autocomplete_indexName,items:[t],positions:[1+r.findIndex((function(e){return e.objectID===t.objectID}))],queryID:t.__autocomplete_queryID,algoliaSource:["autocomplete"]}}function ke(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,a,i,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(u){l=!0,o=u}finally{try{if(!c&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return Ee(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Ee(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ee(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var Oe=["items"],je=["items"];function Pe(e){return Pe="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Pe(e)}function Ce(e){return function(e){if(Array.isArray(e))return Ae(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Ae(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Ae(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ae(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Te(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function Ie(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ne(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ie(Object(n),!0).forEach((function(t){Le(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ie(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Le(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Pe(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Pe(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Pe(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Re(e){return e.map((function(e){var t=e.items,n=Te(e,Oe);return Ne(Ne({},n),{},{objectIDs:(null==t?void 0:t.map((function(e){return e.objectID})))||n.objectIDs})}))}function De(e){var t=function(e){var t=ke((e.version||"").split(".").map(Number),2),n=t[0],r=t[1];return n>=3||2===n&&r>=4||1===n&&r>=10}(e);function n(n,r,o){if(t&&void 0!==o){var a=o[0].__autocomplete_algoliaCredentials,i={"X-Algolia-Application-Id":a.appId,"X-Algolia-API-Key":a.apiKey};e.apply(void 0,[n].concat(Ce(r),[{headers:i}]))}else e.apply(void 0,[n].concat(Ce(r)))}return{init:function(t,n){e("init",{appId:t,apiKey:n})},setAuthenticatedUserToken:function(t){e("setAuthenticatedUserToken",t)},setUserToken:function(t){e("setUserToken",t)},clickedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("clickedObjectIDsAfterSearch",Re(t),t[0].items)},clickedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("clickedObjectIDs",Re(t),t[0].items)},clickedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["clickedFilters"].concat(n))},convertedObjectIDsAfterSearch:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("convertedObjectIDsAfterSearch",Re(t),t[0].items)},convertedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&n("convertedObjectIDs",Re(t),t[0].items)},convertedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["convertedFilters"].concat(n))},viewedObjectIDs:function(){for(var e=arguments.length,t=new Array(e),r=0;r<e;r++)t[r]=arguments[r];t.length>0&&t.reduce((function(e,t){var n=t.items,r=Te(t,je);return[].concat(Ce(e),Ce(function(e){for(var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:20,n=[],r=0;r<e.objectIDs.length;r+=t)n.push(Ne(Ne({},e),{},{objectIDs:e.objectIDs.slice(r,r+t)}));return n}(Ne(Ne({},r),{},{objectIDs:(null==n?void 0:n.map((function(e){return e.objectID})))||r.objectIDs})).map((function(e){return{items:n,payload:e}}))))}),[]).forEach((function(e){var t=e.items;return n("viewedObjectIDs",[e.payload],t)}))},viewedFilters:function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];n.length>0&&e.apply(void 0,["viewedFilters"].concat(n))}}}function Fe(e){var t=e.items.reduce((function(e,t){var n;return e[t.__autocomplete_indexName]=(null!==(n=e[t.__autocomplete_indexName])&&void 0!==n?n:[]).concat(t),e}),{});return Object.keys(t).map((function(e){return{index:e,items:t[e],algoliaSource:["autocomplete"]}}))}function Me(e){return e.objectID&&e.__autocomplete_indexName&&e.__autocomplete_queryID}function Be(e){return Be="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Be(e)}function ze(e){return function(e){if(Array.isArray(e))return $e(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return $e(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return $e(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function $e(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Ue(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function He(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ue(Object(n),!0).forEach((function(t){Ve(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ue(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Ve(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Be(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Be(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Be(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var We="2.15.0",Qe="https://cdn.jsdelivr.net/npm/search-insights@".concat(We,"/dist/search-insights.min.js"),qe=be((function(e){var t=e.onItemsChange,n=e.items,r=e.insights,o=e.state;t({insights:r,insightsEvents:Fe({items:n}).map((function(e){return He({eventName:"Items Viewed"},e)})),state:o})}),400);function Ge(e){var t=function(e){return He({onItemsChange:function(e){var t=e.insights,n=e.insightsEvents,r=e.state;t.viewedObjectIDs.apply(t,ze(n.map((function(e){return He(He({},e),{},{algoliaSource:Ke(e.algoliaSource,r.context)})}))))},onSelect:function(e){var t=e.insights,n=e.insightsEvents,r=e.state;t.clickedObjectIDsAfterSearch.apply(t,ze(n.map((function(e){return He(He({},e),{},{algoliaSource:Ke(e.algoliaSource,r.context)})}))))},onActive:xe,__autocomplete_clickAnalytics:!0},e)}(e),n=t.insightsClient,r=t.insightsInitParams,o=t.onItemsChange,a=t.onSelect,i=t.onActive,s=t.__autocomplete_clickAnalytics,c=n;if(n||function(e){if("undefined"!=typeof window)e({window:window})}((function(e){var t=e.window,n=t.AlgoliaAnalyticsObject||"aa";"string"==typeof n&&(c=t[n]),c||(t.AlgoliaAnalyticsObject=n,t[n]||(t[n]=function(){t[n].queue||(t[n].queue=[]);for(var e=arguments.length,r=new Array(e),o=0;o<e;o++)r[o]=arguments[o];t[n].queue.push(r)}),t[n].version=We,c=t[n],function(e){var t="[Autocomplete]: Could not load search-insights.js. Please load it manually following https://alg.li/insights-autocomplete";try{var n=e.document.createElement("script");n.async=!0,n.src=Qe,n.onerror=function(){console.error(t)},document.body.appendChild(n)}catch(r){console.error(t)}}(t))})),!c)return{};r&&c("init",He({partial:!0},r));var l=De(c),u=ye([]),p=be((function(e){var t=e.state;if(t.isOpen){var n=t.collections.reduce((function(e,t){return[].concat(ze(e),ze(t.items))}),[]).filter(Me);_e(u.current.map((function(e){return e.objectID})),n.map((function(e){return e.objectID})))||(u.current=n,n.length>0&&qe({onItemsChange:o,items:n,insights:l,state:t}))}}),0);return{name:"aa.algoliaInsightsPlugin",subscribe:function(e){var t=e.setContext,n=e.onSelect,r=e.onActive,o=!1;function u(e){t({algoliaInsightsPlugin:{__algoliaSearchParameters:He(He({},s?{clickAnalytics:!0}:{}),e?{userToken:Ye(e)}:{}),insights:l}})}c("addAlgoliaAgent","insights-plugin"),u(),c("onUserTokenChange",(function(e){o||u(e)})),c("getUserToken",null,(function(e,t){o||u(t)})),c("onAuthenticatedUserTokenChange",(function(e){e?(o=!0,u(e)):(o=!1,c("getUserToken",null,(function(e,t){return u(t)})))})),c("getAuthenticatedUserToken",null,(function(e,t){t&&(o=!0,u(t))})),n((function(e){var t=e.item,n=e.state,r=e.event,o=e.source;Me(t)&&a({state:n,event:r,insights:l,item:t,insightsEvents:[He({eventName:"Item Selected"},Se({item:t,items:o.getItems().filter(Me)}))]})})),r((function(e){var t=e.item,n=e.source,r=e.state,o=e.event;Me(t)&&i({state:r,event:o,insights:l,item:t,insightsEvents:[He({eventName:"Item Active"},Se({item:t,items:n.getItems().filter(Me)}))]})}))},onStateChange:function(e){var t=e.state;p({state:t})},__autocomplete_pluginOptions:e}}function Ke(){var e,t=arguments.length>1?arguments[1]:void 0;return[].concat(ze(arguments.length>0&&void 0!==arguments[0]?arguments[0]:[]),["autocomplete-internal"],ze(null!==(e=t.algoliaInsightsPlugin)&&void 0!==e&&e.__automaticInsights?["autocomplete-automatic"]:[]))}function Ye(e){return"number"==typeof e?e.toString():e}function Ze(e){return Ze="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Ze(e)}function Xe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Je(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Ze(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Ze(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Ze(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function et(e,t,n){var r,o=t.initialState;return{getState:function(){return o},dispatch:function(r,a){var i=function(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Xe(Object(n),!0).forEach((function(t){Je(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Xe(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}({},o);o=e(o,{type:r,props:t,payload:a}),n({state:o,prevState:i})},pendingRequests:(r=[],{add:function(e){return r.push(e),e.finally((function(){r=r.filter((function(t){return t!==e}))}))},cancelAll:function(){r.forEach((function(e){return e.cancel()}))},isEmpty:function(){return 0===r.length}})}}function tt(e){return e.reduce((function(e,t){return e.concat(t)}),[])}function nt(e){return nt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},nt(e)}function rt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ot(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?rt(Object(n),!0).forEach((function(t){at(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):rt(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function at(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==nt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==nt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===nt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function it(e){return 0===e.collections.length?0:e.collections.reduce((function(e,t){return e+t.items.length}),0)}var st=0;function ct(){return"autocomplete-".concat(st++)}function lt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ut(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?lt(Object(n),!0).forEach((function(t){pt(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):lt(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function pt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==dt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==dt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===dt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function dt(e){return dt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},dt(e)}function ft(e){return ft="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ft(e)}function mt(e){return function(e){if(Array.isArray(e))return ht(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return ht(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return ht(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function ht(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function vt(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function gt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?vt(Object(n),!0).forEach((function(t){bt(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):vt(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function bt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==ft(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==ft(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===ft(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function yt(e,t){var n,r="undefined"!=typeof window?window:{},o=e.plugins||[];return gt(gt({debug:!1,openOnFocus:!1,enterKeyHint:void 0,ignoreCompositionEvents:!1,placeholder:"",autoFocus:!1,defaultActiveItemId:null,stallThreshold:300,insights:void 0,environment:r,shouldPanelOpen:function(e){return it(e.state)>0},reshape:function(e){return e.sources}},e),{},{id:null!==(n=e.id)&&void 0!==n?n:ct(),plugins:o,initialState:gt({activeItemId:null,query:"",completion:null,collections:[],isOpen:!1,status:"idle",context:{}},e.initialState),onStateChange:function(t){var n;null===(n=e.onStateChange)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onStateChange)||void 0===n?void 0:n.call(e,t)}))},onSubmit:function(t){var n;null===(n=e.onSubmit)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onSubmit)||void 0===n?void 0:n.call(e,t)}))},onReset:function(t){var n;null===(n=e.onReset)||void 0===n||n.call(e,t),o.forEach((function(e){var n;return null===(n=e.onReset)||void 0===n?void 0:n.call(e,t)}))},getSources:function(n){return Promise.all([].concat(mt(o.map((function(e){return e.getSources}))),[e.getSources]).filter(Boolean).map((function(e){return function(e,t){var n=[];return Promise.resolve(e(t)).then((function(e){return Array.isArray(e),Promise.all(e.filter((function(e){return Boolean(e)})).map((function(e){if(e.sourceId,n.includes(e.sourceId))throw new Error("[Autocomplete] The `sourceId` ".concat(JSON.stringify(e.sourceId)," is not unique."));n.push(e.sourceId);var t={getItemInputValue:function(e){return e.state.query},getItemUrl:function(){},onSelect:function(e){(0,e.setIsOpen)(!1)},onActive:xe,onResolve:xe};Object.keys(t).forEach((function(e){t[e].__default=!0}));var r=ut(ut({},t),e);return Promise.resolve(r)})))}))}(e,n)}))).then((function(e){return tt(e)})).then((function(e){return e.map((function(e){return gt(gt({},e),{},{onSelect:function(n){e.onSelect(n),t.forEach((function(e){var t;return null===(t=e.onSelect)||void 0===t?void 0:t.call(e,n)}))},onActive:function(n){e.onActive(n),t.forEach((function(e){var t;return null===(t=e.onActive)||void 0===t?void 0:t.call(e,n)}))},onResolve:function(n){e.onResolve(n),t.forEach((function(e){var t;return null===(t=e.onResolve)||void 0===t?void 0:t.call(e,n)}))}})}))}))},navigator:gt({navigate:function(e){var t=e.itemUrl;r.location.assign(t)},navigateNewTab:function(e){var t=e.itemUrl,n=r.open(t,"_blank","noopener");null==n||n.focus()},navigateNewWindow:function(e){var t=e.itemUrl;r.open(t,"_blank","noopener")}},e.navigator)})}function wt(e){return wt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},wt(e)}function _t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function xt(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?_t(Object(n),!0).forEach((function(t){St(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):_t(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function St(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==wt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==wt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===wt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function kt(e){return kt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},kt(e)}function Et(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ot(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Et(Object(n),!0).forEach((function(t){jt(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Et(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function jt(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==kt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==kt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===kt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Pt(e){return function(e){if(Array.isArray(e))return Ct(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Ct(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Ct(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Ct(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function At(e){return Boolean(e.execute)}function Tt(e,t,n){if(o=e,Boolean(null==o?void 0:o.execute)){var r="algolia"===e.requesterId?Object.assign.apply(Object,[{}].concat(Pt(Object.keys(n.context).map((function(e){var t;return null===(t=n.context[e])||void 0===t?void 0:t.__algoliaSearchParameters}))))):{};return Ot(Ot({},e),{},{requests:e.queries.map((function(n){return{query:"algolia"===e.requesterId?Ot(Ot({},n),{},{params:Ot(Ot({},r),n.params)}):n,sourceId:t,transformResponse:e.transformResponse}}))})}var o;return{items:e,sourceId:t}}function It(e){var t=e.reduce((function(e,t){if(!At(t))return e.push(t),e;var n=t.searchClient,r=t.execute,o=t.requesterId,a=t.requests,i=e.find((function(e){return At(t)&&At(e)&&e.searchClient===n&&Boolean(o)&&e.requesterId===o}));if(i){var s;(s=i.items).push.apply(s,Pt(a))}else{var c={execute:r,requesterId:o,items:a,searchClient:n};e.push(c)}return e}),[]).map((function(e){if(!At(e))return Promise.resolve(e);var t=e,n=t.execute,r=t.items;return n({searchClient:t.searchClient,requests:r})}));return Promise.all(t).then((function(e){return tt(e)}))}function Nt(e,t,n){return t.map((function(t){var r,o=e.filter((function(e){return e.sourceId===t.sourceId})),a=o.map((function(e){return e.items})),i=o[0].transformResponse,s=i?i({results:r=a,hits:r.map((function(e){return e.hits})).filter(Boolean),facetHits:r.map((function(e){var t;return null===(t=e.facetHits)||void 0===t?void 0:t.map((function(e){return{label:e.value,count:e.count,_highlightResult:{label:{value:e.highlighted}}}}))})).filter(Boolean)}):a;return t.onResolve({source:t,results:a,items:s,state:n.getState()}),Array.isArray(s),s.every(Boolean),'The `getItems` function from source "'.concat(t.sourceId,'" must return an array of items but returned ').concat(JSON.stringify(void 0),".\n\nDid you forget to return items?\n\nSee: https://www.algolia.com/doc/ui-libraries/autocomplete/core-concepts/sources/#param-getitems"),{source:t,items:s}}))}function Lt(e,t){var n=t;return{then:function(t,r){return Lt(e.then(Ft(t,n,e),Ft(r,n,e)),n)},catch:function(t){return Lt(e.catch(Ft(t,n,e)),n)},finally:function(t){return t&&n.onCancelList.push(t),Lt(e.finally(Ft(t&&function(){return n.onCancelList=[],t()},n,e)),n)},cancel:function(){n.isCanceled=!0;var e=n.onCancelList;n.onCancelList=[],e.forEach((function(e){e()}))},isCanceled:function(){return!0===n.isCanceled}}}function Rt(e){return Lt(new Promise((function(t,n){return e(t,n)})),{isCanceled:!1,onCancelList:[]})}function Dt(e){return Lt(e,{isCanceled:!1,onCancelList:[]})}function Ft(e,t,n){return e?function(n){return t.isCanceled?n:e(n)}:n}function Mt(e){var t=function(e){var t=e.collections.map((function(e){return e.items.length})).reduce((function(e,t,n){var r=(e[n-1]||0)+t;return e.push(r),e}),[]).reduce((function(t,n){return n<=e.activeItemId?t+1:t}),0);return e.collections[t]}(e);if(!t)return null;var n=t.items[function(e){for(var t=e.state,n=e.collection,r=!1,o=0,a=0;!1===r;){var i=t.collections[o];if(i===n){r=!0;break}a+=i.items.length,o++}return t.activeItemId-a}({state:e,collection:t})],r=t.source;return{item:n,itemInputValue:r.getItemInputValue({item:n,state:e}),itemUrl:r.getItemUrl({item:n,state:e}),source:r}}function Bt(e){return Bt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Bt(e)}Rt.resolve=function(e){return Dt(Promise.resolve(e))},Rt.reject=function(e){return Dt(Promise.reject(e))};var zt=["event","nextState","props","query","refresh","store"];function $t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Ut(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?$t(Object(n),!0).forEach((function(t){Ht(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):$t(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Ht(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Bt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Bt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Bt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Vt(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Wt,Qt,qt,Gt=null,Kt=(Wt=-1,Qt=-1,qt=void 0,function(e){var t=++Wt;return Promise.resolve(e).then((function(e){return qt&&t<Qt?qt:(Qt=t,qt=e,e)}))});function Yt(e){var t=e.event,n=e.nextState,r=void 0===n?{}:n,o=e.props,a=e.query,i=e.refresh,s=e.store,c=Vt(e,zt);Gt&&o.environment.clearTimeout(Gt);var l=c.setCollections,u=c.setIsOpen,p=c.setQuery,d=c.setActiveItemId,f=c.setStatus,m=c.setContext;if(p(a),d(o.defaultActiveItemId),!a&&!1===o.openOnFocus){var h,v=s.getState().collections.map((function(e){return Ut(Ut({},e),{},{items:[]})}));f("idle"),l(v),u(null!==(h=r.isOpen)&&void 0!==h?h:o.shouldPanelOpen({state:s.getState()}));var g=Dt(Kt(v).then((function(){return Promise.resolve()})));return s.pendingRequests.add(g)}f("loading"),Gt=o.environment.setTimeout((function(){f("stalled")}),o.stallThreshold);var b=Dt(Kt(o.getSources(Ut({query:a,refresh:i,state:s.getState()},c)).then((function(e){return Promise.all(e.map((function(e){return Promise.resolve(e.getItems(Ut({query:a,refresh:i,state:s.getState()},c))).then((function(t){return Tt(t,e.sourceId,s.getState())}))}))).then(It).then((function(t){var n,r=t.some((function(e){return function(e){return!Array.isArray(e)&&Boolean(null==e?void 0:e._automaticInsights)}(e.items)}));r&&m({algoliaInsightsPlugin:Ut(Ut({},(null===(n=s.getState().context)||void 0===n?void 0:n.algoliaInsightsPlugin)||{}),{},{__automaticInsights:r})});return Nt(t,e,s)})).then((function(e){return function(e){var t=e.collections,n=e.props,r=e.state,o=t.reduce((function(e,t){return xt(xt({},e),{},St({},t.source.sourceId,xt(xt({},t.source),{},{getItems:function(){return tt(t.items)}})))}),{}),a=n.plugins.reduce((function(e,t){return t.reshape?t.reshape(e):e}),{sourcesBySourceId:o,state:r}).sourcesBySourceId;return tt(n.reshape({sourcesBySourceId:a,sources:Object.values(a),state:r})).filter(Boolean).map((function(e){return{source:e,items:e.getItems()}}))}({collections:e,props:o,state:s.getState()})}))})))).then((function(e){var n;f("idle"),l(e);var p=o.shouldPanelOpen({state:s.getState()});u(null!==(n=r.isOpen)&&void 0!==n?n:o.openOnFocus&&!a&&p||p);var d=Mt(s.getState());if(null!==s.getState().activeItemId&&d){var m=d.item,h=d.itemInputValue,v=d.itemUrl,g=d.source;g.onActive(Ut({event:t,item:m,itemInputValue:h,itemUrl:v,refresh:i,source:g,state:s.getState()},c))}})).finally((function(){f("idle"),Gt&&o.environment.clearTimeout(Gt)}));return s.pendingRequests.add(b)}function Zt(e,t,n){return[e,null==n?void 0:n.sourceId,t].filter(Boolean).join("-").replace(/\s/g,"")}function Xt(e){return Xt="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Xt(e)}var Jt=["event","props","refresh","store"];function en(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function tn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?en(Object(n),!0).forEach((function(t){nn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):en(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function nn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Xt(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Xt(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Xt(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function rn(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var on=/((gt|sm)-|galaxy nexus)|samsung[- ]|samsungbrowser/i;function an(e){return e.nativeEvent||e}function sn(e){return sn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},sn(e)}var cn=["props","refresh","store"],ln=["inputElement","formElement","panelElement"],un=["inputElement"],pn=["inputElement","maxLength"],dn=["source"],fn=["item","source"];function mn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function hn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?mn(Object(n),!0).forEach((function(t){vn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):mn(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function vn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==sn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==sn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===sn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function gn(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function bn(e){var t=e.props,n=e.refresh,r=e.store,o=gn(e,cn);return{getEnvironmentProps:function(e){var n=e.inputElement,o=e.formElement,a=e.panelElement;function i(e){!r.getState().isOpen&&r.pendingRequests.isEmpty()||e.target===n||!1===[o,a].some((function(t){return n=t,r=e.target,n===r||n.contains(r);var n,r}))&&(r.dispatch("blur",null),t.debug||r.pendingRequests.cancelAll())}return hn({onTouchStart:i,onMouseDown:i,onTouchMove:function(e){!1!==r.getState().isOpen&&n===t.environment.document.activeElement&&e.target!==n&&n.blur()}},gn(e,ln))},getRootProps:function(e){return hn({role:"combobox","aria-expanded":r.getState().isOpen,"aria-haspopup":"listbox","aria-owns":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return Zt(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":Zt(t.id,"label")},e)},getFormProps:function(e){e.inputElement;return hn({action:"",noValidate:!0,role:"search",onSubmit:function(a){var i;a.preventDefault(),t.onSubmit(hn({event:a,refresh:n,state:r.getState()},o)),r.dispatch("submit",null),null===(i=e.inputElement)||void 0===i||i.blur()},onReset:function(a){var i;a.preventDefault(),t.onReset(hn({event:a,refresh:n,state:r.getState()},o)),r.dispatch("reset",null),null===(i=e.inputElement)||void 0===i||i.focus()}},gn(e,un))},getLabelProps:function(e){return hn({htmlFor:Zt(t.id,"input"),id:Zt(t.id,"label")},e)},getInputProps:function(e){var a;function i(e){(t.openOnFocus||Boolean(r.getState().query))&&Yt(hn({event:e,props:t,query:r.getState().completion||r.getState().query,refresh:n,store:r},o)),r.dispatch("focus",null)}var s=e||{},c=(s.inputElement,s.maxLength),l=void 0===c?512:c,u=gn(s,pn),p=Mt(r.getState()),d=function(e){return Boolean(e&&e.match(on))}((null===(a=t.environment.navigator)||void 0===a?void 0:a.userAgent)||""),f=t.enterKeyHint||(null!=p&&p.itemUrl&&!d?"go":"search");return hn({"aria-autocomplete":"both","aria-activedescendant":r.getState().isOpen&&null!==r.getState().activeItemId?Zt(t.id,"item-".concat(r.getState().activeItemId),null==p?void 0:p.source):void 0,"aria-controls":r.getState().isOpen?r.getState().collections.map((function(e){var n=e.source;return Zt(t.id,"list",n)})).join(" "):void 0,"aria-labelledby":Zt(t.id,"label"),value:r.getState().completion||r.getState().query,id:Zt(t.id,"input"),autoComplete:"off",autoCorrect:"off",autoCapitalize:"off",enterKeyHint:f,spellCheck:"false",autoFocus:t.autoFocus,placeholder:t.placeholder,maxLength:l,type:"search",onChange:function(e){var a=e.currentTarget.value;t.ignoreCompositionEvents&&an(e).isComposing?o.setQuery(a):Yt(hn({event:e,props:t,query:a.slice(0,l),refresh:n,store:r},o))},onCompositionEnd:function(e){Yt(hn({event:e,props:t,query:e.currentTarget.value.slice(0,l),refresh:n,store:r},o))},onKeyDown:function(e){an(e).isComposing||function(e){var t=e.event,n=e.props,r=e.refresh,o=e.store,a=rn(e,Jt);if("ArrowUp"===t.key||"ArrowDown"===t.key){var i=function(){var e=Mt(o.getState()),t=n.environment.document.getElementById(Zt(n.id,"item-".concat(o.getState().activeItemId),null==e?void 0:e.source));t&&(t.scrollIntoViewIfNeeded?t.scrollIntoViewIfNeeded(!1):t.scrollIntoView(!1))},s=function(){var e=Mt(o.getState());if(null!==o.getState().activeItemId&&e){var n=e.item,i=e.itemInputValue,s=e.itemUrl,c=e.source;c.onActive(tn({event:t,item:n,itemInputValue:i,itemUrl:s,refresh:r,source:c,state:o.getState()},a))}};t.preventDefault(),!1===o.getState().isOpen&&(n.openOnFocus||Boolean(o.getState().query))?Yt(tn({event:t,props:n,query:o.getState().query,refresh:r,store:o},a)).then((function(){o.dispatch(t.key,{nextActiveItemId:n.defaultActiveItemId}),s(),setTimeout(i,0)})):(o.dispatch(t.key,{}),s(),i())}else if("Escape"===t.key)t.preventDefault(),o.dispatch(t.key,null),o.pendingRequests.cancelAll();else if("Tab"===t.key)o.dispatch("blur",null),o.pendingRequests.cancelAll();else if("Enter"===t.key){if(null===o.getState().activeItemId||o.getState().collections.every((function(e){return 0===e.items.length})))return void(n.debug||o.pendingRequests.cancelAll());t.preventDefault();var c=Mt(o.getState()),l=c.item,u=c.itemInputValue,p=c.itemUrl,d=c.source;if(t.metaKey||t.ctrlKey)void 0!==p&&(d.onSelect(tn({event:t,item:l,itemInputValue:u,itemUrl:p,refresh:r,source:d,state:o.getState()},a)),n.navigator.navigateNewTab({itemUrl:p,item:l,state:o.getState()}));else if(t.shiftKey)void 0!==p&&(d.onSelect(tn({event:t,item:l,itemInputValue:u,itemUrl:p,refresh:r,source:d,state:o.getState()},a)),n.navigator.navigateNewWindow({itemUrl:p,item:l,state:o.getState()}));else if(t.altKey);else{if(void 0!==p)return d.onSelect(tn({event:t,item:l,itemInputValue:u,itemUrl:p,refresh:r,source:d,state:o.getState()},a)),void n.navigator.navigate({itemUrl:p,item:l,state:o.getState()});Yt(tn({event:t,nextState:{isOpen:!1},props:n,query:u,refresh:r,store:o},a)).then((function(){d.onSelect(tn({event:t,item:l,itemInputValue:u,itemUrl:p,refresh:r,source:d,state:o.getState()},a))}))}}}(hn({event:e,props:t,refresh:n,store:r},o))},onFocus:i,onBlur:xe,onClick:function(n){e.inputElement!==t.environment.document.activeElement||r.getState().isOpen||i(n)}},u)},getPanelProps:function(e){return hn({onMouseDown:function(e){e.preventDefault()},onMouseLeave:function(){r.dispatch("mouseleave",null)}},e)},getListProps:function(e){var n=e||{},r=n.source,o=gn(n,dn);return hn({role:"listbox","aria-labelledby":Zt(t.id,"label"),id:Zt(t.id,"list",r)},o)},getItemProps:function(e){var a=e.item,i=e.source,s=gn(e,fn);return hn({id:Zt(t.id,"item-".concat(a.__autocomplete_id),i),role:"option","aria-selected":r.getState().activeItemId===a.__autocomplete_id,onMouseMove:function(e){if(a.__autocomplete_id!==r.getState().activeItemId){r.dispatch("mousemove",a.__autocomplete_id);var t=Mt(r.getState());if(null!==r.getState().activeItemId&&t){var i=t.item,s=t.itemInputValue,c=t.itemUrl,l=t.source;l.onActive(hn({event:e,item:i,itemInputValue:s,itemUrl:c,refresh:n,source:l,state:r.getState()},o))}}},onMouseDown:function(e){e.preventDefault()},onClick:function(e){var s=i.getItemInputValue({item:a,state:r.getState()}),c=i.getItemUrl({item:a,state:r.getState()});(c?Promise.resolve():Yt(hn({event:e,nextState:{isOpen:!1},props:t,query:s,refresh:n,store:r},o))).then((function(){i.onSelect(hn({event:e,item:a,itemInputValue:s,itemUrl:c,refresh:n,source:i,state:r.getState()},o))}))}},s)}}}var yn="1.17.4",wn=[{segment:"autocomplete-core",version:yn}];function _n(e){return _n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_n(e)}function xn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Sn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?xn(Object(n),!0).forEach((function(t){kn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):xn(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function kn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==_n(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==_n(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===_n(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function En(e){var t,n,r,o,a=e.plugins,i=e.options,s=null===(t=((null===(n=i.__autocomplete_metadata)||void 0===n?void 0:n.userAgents)||[])[0])||void 0===t?void 0:t.segment,c=s?kn({},s,Object.keys((null===(r=i.__autocomplete_metadata)||void 0===r?void 0:r.options)||{})):{};return{plugins:a.map((function(e){return{name:e.name,options:Object.keys(e.__autocomplete_pluginOptions||[])}})),options:Sn({"autocomplete-core":Object.keys(i)},c),ua:wn.concat((null===(o=i.__autocomplete_metadata)||void 0===o?void 0:o.userAgents)||[])}}function On(e){var t,n=e.state;return!1===n.isOpen||null===n.activeItemId?null:(null===(t=Mt(n))||void 0===t?void 0:t.itemInputValue)||null}function jn(e,t,n,r){if(!n)return null;if(e<0&&(null===t||null!==r&&0===t))return n+e;var o=(null===t?-1:t)+e;return o<=-1||o>=n?null===r?null:0:o}function Pn(e){return Pn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Pn(e)}function Cn(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function An(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Cn(Object(n),!0).forEach((function(t){Tn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Cn(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Tn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Pn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Pn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Pn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var In=function(e,t){switch(t.type){case"setActiveItemId":case"mousemove":return An(An({},e),{},{activeItemId:t.payload});case"setQuery":return An(An({},e),{},{query:t.payload,completion:null});case"setCollections":return An(An({},e),{},{collections:t.payload});case"setIsOpen":return An(An({},e),{},{isOpen:t.payload});case"setStatus":return An(An({},e),{},{status:t.payload});case"setContext":return An(An({},e),{},{context:An(An({},e.context),t.payload)});case"ArrowDown":var n=An(An({},e),{},{activeItemId:t.payload.hasOwnProperty("nextActiveItemId")?t.payload.nextActiveItemId:jn(1,e.activeItemId,it(e),t.props.defaultActiveItemId)});return An(An({},n),{},{completion:On({state:n})});case"ArrowUp":var r=An(An({},e),{},{activeItemId:jn(-1,e.activeItemId,it(e),t.props.defaultActiveItemId)});return An(An({},r),{},{completion:On({state:r})});case"Escape":return e.isOpen?An(An({},e),{},{activeItemId:null,isOpen:!1,completion:null}):An(An({},e),{},{activeItemId:null,query:"",status:"idle",collections:[]});case"submit":return An(An({},e),{},{activeItemId:null,isOpen:!1,status:"idle"});case"reset":return An(An({},e),{},{activeItemId:!0===t.props.openOnFocus?t.props.defaultActiveItemId:null,status:"idle",completion:null,query:""});case"focus":return An(An({},e),{},{activeItemId:t.props.defaultActiveItemId,isOpen:(t.props.openOnFocus||Boolean(e.query))&&t.props.shouldPanelOpen({state:e})});case"blur":return t.props.debug?e:An(An({},e),{},{isOpen:!1,activeItemId:null});case"mouseleave":return An(An({},e),{},{activeItemId:t.props.defaultActiveItemId});default:return"The reducer action ".concat(JSON.stringify(t.type)," is not supported."),e}};function Nn(e){return Nn="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Nn(e)}function Ln(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Rn(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Ln(Object(n),!0).forEach((function(t){Dn(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Ln(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Dn(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Nn(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Nn(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Nn(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Fn(e){var t=[],n=yt(e,t),r=et(In,n,(function(e){var t,r,a=e.prevState,l=e.state;if(n.onStateChange(Rn({prevState:a,state:l,refresh:i,navigator:n.navigator},o)),!c()&&null!==(t=l.context)&&void 0!==t&&null!==(r=t.algoliaInsightsPlugin)&&void 0!==r&&r.__automaticInsights&&!1!==n.insights){var u=Ge({__autocomplete_clickAnalytics:!1});n.plugins.push(u),s([u])}})),o=function(e){var t=e.store;return{setActiveItemId:function(e){t.dispatch("setActiveItemId",e)},setQuery:function(e){t.dispatch("setQuery",e)},setCollections:function(e){var n=0,r=e.map((function(e){return ot(ot({},e),{},{items:tt(e.items).map((function(e){return ot(ot({},e),{},{__autocomplete_id:n++})}))})}));t.dispatch("setCollections",r)},setIsOpen:function(e){t.dispatch("setIsOpen",e)},setStatus:function(e){t.dispatch("setStatus",e)},setContext:function(e){t.dispatch("setContext",e)}}}({store:r}),a=bn(Rn({props:n,refresh:i,store:r,navigator:n.navigator},o));function i(){return Yt(Rn({event:new Event("input"),nextState:{isOpen:r.getState().isOpen},props:n,navigator:n.navigator,query:r.getState().query,refresh:i,store:r},o))}function s(e){e.forEach((function(e){var r;return null===(r=e.subscribe)||void 0===r?void 0:r.call(e,Rn(Rn({},o),{},{navigator:n.navigator,refresh:i,onSelect:function(e){t.push({onSelect:e})},onActive:function(e){t.push({onActive:e})},onResolve:function(e){t.push({onResolve:e})}}))}))}function c(){return n.plugins.some((function(e){return"aa.algoliaInsightsPlugin"===e.name}))}if(n.insights&&!c()){var l="boolean"==typeof n.insights?{}:n.insights;n.plugins.push(Ge(l))}return s(n.plugins),function(e){var t,n,r=e.metadata,o=e.environment;if(null===(t=o.navigator)||void 0===t||null===(n=t.userAgent)||void 0===n?void 0:n.includes("Algolia Crawler")){var a=o.document.createElement("meta"),i=o.document.querySelector("head");a.name="algolia:metadata",setTimeout((function(){a.content=JSON.stringify(r),i.appendChild(a)}),0)}}({metadata:En({plugins:n.plugins,options:e}),environment:n.environment}),Rn(Rn({refresh:i,navigator:n.navigator},a),o)}var Mn=function(e,t,n,r){var o;t[0]=0;for(var a=1;a<t.length;a++){var i=t[a++],s=t[a]?(t[0]|=i?1:2,n[t[a++]]):t[++a];3===i?r[0]=s:4===i?r[1]=Object.assign(r[1]||{},s):5===i?(r[1]=r[1]||{})[t[++a]]=s:6===i?r[1][t[++a]]+=s+"":i?(o=e.apply(s,Mn(e,s,n,["",null])),r.push(o),s[0]?t[0]|=2:(t[a-2]=0,t[a]=o)):r.push(s)}return r},Bn=new Map;function zn(e){var t=Bn.get(this);return t||(t=new Map,Bn.set(this,t)),(t=Mn(this,t.get(e)||(t.set(e,t=function(e){for(var t,n,r=1,o="",a="",i=[0],s=function(e){1===r&&(e||(o=o.replace(/^\s*\n\s*|\s*\n\s*$/g,"")))?i.push(0,e,o):3===r&&(e||o)?(i.push(3,e,o),r=2):2===r&&"..."===o&&e?i.push(4,e,0):2===r&&o&&!e?i.push(5,0,!0,o):r>=5&&((o||!e&&5===r)&&(i.push(r,0,o,n),r=6),e&&(i.push(r,e,0,n),r=6)),o=""},c=0;c<e.length;c++){c&&(1===r&&s(),s(c));for(var l=0;l<e[c].length;l++)t=e[c][l],1===r?"<"===t?(s(),i=[i],r=3):o+=t:4===r?"--"===o&&">"===t?(r=1,o=""):o=t+o[0]:a?t===a?a="":o+=t:'"'===t||"'"===t?a=t:">"===t?(s(),r=1):r&&("="===t?(r=5,n=o,o=""):"/"===t&&(r<5||">"===e[c][l+1])?(s(),3===r&&(i=i[0]),r=i,(i=i[0]).push(2,0,r),r=0):" "===t||"\t"===t||"\n"===t||"\r"===t?(s(),r=2):o+=t),3===r&&"!--"===o&&(r=4,i=i[0])}return s(),i}(e)),t),arguments,[])).length>1?t:t[0]}var $n=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-SubmitIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","20"),n.setAttribute("height","20"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M16.041 15.856c-0.034 0.026-0.067 0.055-0.099 0.087s-0.060 0.064-0.087 0.099c-1.258 1.213-2.969 1.958-4.855 1.958-1.933 0-3.682-0.782-4.95-2.050s-2.050-3.017-2.050-4.95 0.782-3.682 2.050-4.95 3.017-2.050 4.95-2.050 3.682 0.782 4.95 2.050 2.050 3.017 2.050 4.95c0 1.886-0.745 3.597-1.959 4.856zM21.707 20.293l-3.675-3.675c1.231-1.54 1.968-3.493 1.968-5.618 0-2.485-1.008-4.736-2.636-6.364s-3.879-2.636-6.364-2.636-4.736 1.008-6.364 2.636-2.636 3.879-2.636 6.364 1.008 4.736 2.636 6.364 3.879 2.636 6.364 2.636c2.125 0 4.078-0.737 5.618-1.968l3.675 3.675c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414z"),n.appendChild(r),n},Un=function(e){var t=e.environment,n=t.document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("class","aa-ClearIcon"),n.setAttribute("viewBox","0 0 24 24"),n.setAttribute("width","18"),n.setAttribute("height","18"),n.setAttribute("fill","currentColor");var r=t.document.createElementNS("http://www.w3.org/2000/svg","path");return r.setAttribute("d","M5.293 6.707l5.293 5.293-5.293 5.293c-0.391 0.391-0.391 1.024 0 1.414s1.024 0.391 1.414 0l5.293-5.293 5.293 5.293c0.391 0.391 1.024 0.391 1.414 0s0.391-1.024 0-1.414l-5.293-5.293 5.293-5.293c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0l-5.293 5.293-5.293-5.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414z"),n.appendChild(r),n},Hn=function(e){var t=e.environment.document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("class","aa-LoadingIcon"),t.setAttribute("viewBox","0 0 100 100"),t.setAttribute("width","20"),t.setAttribute("height","20"),t.innerHTML='<circle\n cx="50"\n cy="50"\n fill="none"\n r="35"\n stroke="currentColor"\n stroke-dasharray="164.93361431346415 56.97787143782138"\n stroke-width="6"\n>\n <animateTransform\n attributeName="transform"\n type="rotate"\n repeatCount="indefinite"\n dur="1s"\n values="0 50 50;90 50 50;180 50 50;360 50 50"\n keyTimes="0;0.40;0.65;1"\n />\n</circle>',t},Vn=["ontouchstart","ontouchend","ontouchmove","ontouchcancel"];function Wn(e,t,n){e[t]=null===n?"":"number"!=typeof n?n:n+"px"}function Qn(e){this._listeners[e.type](e)}function qn(e,t,n){var r,o,a=e[t];if("style"===t)if("string"==typeof n)e.style=n;else if(null===n)e.style="";else for(t in n)a&&n[t]===a[t]||Wn(e.style,t,n[t]);else"o"===t[0]&&"n"===t[1]?(r=t!==(t=t.replace(/Capture$/,"")),((o=t.toLowerCase())in e||Vn.includes(o))&&(t=o),t=t.slice(2),e._listeners||(e._listeners={}),e._listeners[t]=n,n?a||e.addEventListener(t,Qn,r):e.removeEventListener(t,Qn,r)):"list"!==t&&"tagName"!==t&&"form"!==t&&"type"!==t&&"size"!==t&&"download"!==t&&"href"!==t&&t in e?e[t]=null==n?"":n:"function"!=typeof n&&"dangerouslySetInnerHTML"!==t&&(null==n||!1===n&&!/^ar/.test(t)?e.removeAttribute(t):e.setAttribute(t,n))}function Gn(e){switch(e){case"onChange":return"onInput";case"onCompositionEnd":return"oncompositionend";default:return e}}function Kn(e,t){for(var n in t)qn(e,Gn(n),t[n])}function Yn(e,t){for(var n in t)"o"===n[0]&&"n"===n[1]||qn(e,Gn(n),t[n])}var Zn=["children"];function Xn(e){return function(e){if(Array.isArray(e))return Jn(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return Jn(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Jn(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Jn(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function er(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function tr(e){return function(t,n){var r=n.children,o=void 0===r?[]:r,a=er(n,Zn),i=e.document.createElement(t);return Kn(i,a),i.append.apply(i,Xn(o)),i}}function nr(e){return nr="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},nr(e)}var rr=["autocompleteScopeApi","environment","classNames","getInputProps","getInputPropsCore","isDetached","state"];function or(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ar(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?or(Object(n),!0).forEach((function(t){ir(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):or(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function ir(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==nr(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==nr(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===nr(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function sr(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var cr=function(e){var t=e.autocompleteScopeApi,n=e.environment,r=(e.classNames,e.getInputProps),o=e.getInputPropsCore,a=e.isDetached,i=e.state,s=sr(e,rr),c=tr(n)("input",s),l=r(ar({state:i,props:o({inputElement:c}),inputElement:c},t));return Kn(c,ar(ar({},l),{},{onKeyDown:function(e){a&&"Tab"===e.key||l.onKeyDown(e)}})),c};function lr(e){return lr="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},lr(e)}function ur(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function pr(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ur(Object(n),!0).forEach((function(t){dr(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ur(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function dr(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==lr(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==lr(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===lr(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var fr,mr,hr,vr,gr,br,yr,wr,_r,xr,Sr={},kr=[],Er=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Or=Array.isArray;function jr(e,t){for(var n in t)e[n]=t[n];return e}function Pr(e){var t=e.parentNode;t&&t.removeChild(e)}function Cr(e,t,n){var r,o,a,i={};for(a in t)"key"==a?r=t[a]:"ref"==a?o=t[a]:i[a]=t[a];if(arguments.length>2&&(i.children=arguments.length>3?fr.call(arguments,2):n),"function"==typeof e&&null!=e.defaultProps)for(a in e.defaultProps)void 0===i[a]&&(i[a]=e.defaultProps[a]);return Ar(e,i,r,o,null)}function Ar(e,t,n,r,o){var a={type:e,props:t,key:n,ref:r,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,constructor:void 0,__v:null==o?++hr:o,__i:-1,__u:0};return null==o&&null!=mr.vnode&&mr.vnode(a),a}function Tr(e){return e.children}function Ir(e,t){this.props=e,this.context=t}function Nr(e,t){if(null==t)return e.__?Nr(e.__,e.__i+1):null;for(var n;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e)return n.__e;return"function"==typeof e.type?Nr(e):null}function Lr(e){var t,n;if(null!=(e=e.__)&&null!=e.__c){for(e.__e=e.__c.base=null,t=0;t<e.__k.length;t++)if(null!=(n=e.__k[t])&&null!=n.__e){e.__e=e.__c.base=n.__e;break}return Lr(e)}}function Rr(e){(!e.__d&&(e.__d=!0)&&vr.push(e)&&!Dr.__r++||gr!==mr.debounceRendering)&&((gr=mr.debounceRendering)||br)(Dr)}function Dr(){var e,t,n,r,o,a,i,s;for(vr.sort(yr);e=vr.shift();)e.__d&&(t=vr.length,r=void 0,a=(o=(n=e).__v).__e,i=[],s=[],n.__P&&((r=jr({},o)).__v=o.__v+1,mr.vnode&&mr.vnode(r),Vr(n.__P,r,o,n.__n,n.__P.namespaceURI,32&o.__u?[a]:null,i,null==a?Nr(o):a,!!(32&o.__u),s),r.__v=o.__v,r.__.__k[r.__i]=r,Wr(i,r,s),r.__e!=a&&Lr(r)),vr.length>t&&vr.sort(yr));Dr.__r=0}function Fr(e,t,n,r,o,a,i,s,c,l,u){var p,d,f,m,h,v=r&&r.__k||kr,g=t.length;for(n.__d=c,Mr(n,t,v),c=n.__d,p=0;p<g;p++)null!=(f=n.__k[p])&&"boolean"!=typeof f&&"function"!=typeof f&&(d=-1===f.__i?Sr:v[f.__i]||Sr,f.__i=p,Vr(e,f,d,o,a,i,s,c,l,u),m=f.__e,f.ref&&d.ref!=f.ref&&(d.ref&&qr(d.ref,null,f),u.push(f.ref,f.__c||m,f)),null==h&&null!=m&&(h=m),65536&f.__u||d.__k===f.__k?c=Br(f,c,e):"function"==typeof f.type&&void 0!==f.__d?c=f.__d:m&&(c=m.nextSibling),f.__d=void 0,f.__u&=-196609);n.__d=c,n.__e=h}function Mr(e,t,n){var r,o,a,i,s,c=t.length,l=n.length,u=l,p=0;for(e.__k=[],r=0;r<c;r++)i=r+p,null!=(o=e.__k[r]=null==(o=t[r])||"boolean"==typeof o||"function"==typeof o?null:"string"==typeof o||"number"==typeof o||"bigint"==typeof o||o.constructor==String?Ar(null,o,null,null,null):Or(o)?Ar(Tr,{children:o},null,null,null):void 0===o.constructor&&o.__b>0?Ar(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):o)?(o.__=e,o.__b=e.__b+1,s=zr(o,n,i,u),o.__i=s,a=null,-1!==s&&(u--,(a=n[s])&&(a.__u|=131072)),null==a||null===a.__v?(-1==s&&p--,"function"!=typeof o.type&&(o.__u|=65536)):s!==i&&(s==i-1?p--:s==i+1?p++:s>i?u>c-i?p+=s-i:p--:s<i&&(s==i-p?p-=s-i:p++),s!==r+p&&(o.__u|=65536))):(a=n[i])&&null==a.key&&a.__e&&!(131072&a.__u)&&(a.__e==e.__d&&(e.__d=Nr(a)),Gr(a,a,!1),n[i]=null,u--);if(u)for(r=0;r<l;r++)null!=(a=n[r])&&!(131072&a.__u)&&(a.__e==e.__d&&(e.__d=Nr(a)),Gr(a,a))}function Br(e,t,n){var r,o;if("function"==typeof e.type){for(r=e.__k,o=0;r&&o<r.length;o++)r[o]&&(r[o].__=e,t=Br(r[o],t,n));return t}e.__e!=t&&(t&&e.type&&!n.contains(t)&&(t=Nr(e)),n.insertBefore(e.__e,t||null),t=e.__e);do{t=t&&t.nextSibling}while(null!=t&&8===t.nodeType);return t}function zr(e,t,n,r){var o=e.key,a=e.type,i=n-1,s=n+1,c=t[n];if(null===c||c&&o==c.key&&a===c.type&&!(131072&c.__u))return n;if(r>(null==c||131072&c.__u?0:1))for(;i>=0||s<t.length;){if(i>=0){if((c=t[i])&&!(131072&c.__u)&&o==c.key&&a===c.type)return i;i--}if(s<t.length){if((c=t[s])&&!(131072&c.__u)&&o==c.key&&a===c.type)return s;s++}}return-1}function $r(e,t,n){"-"===t[0]?e.setProperty(t,null==n?"":n):e[t]=null==n?"":"number"!=typeof n||Er.test(t)?n:n+"px"}function Ur(e,t,n,r,o){var a;e:if("style"===t)if("string"==typeof n)e.style.cssText=n;else{if("string"==typeof r&&(e.style.cssText=r=""),r)for(t in r)n&&t in n||$r(e.style,t,"");if(n)for(t in n)r&&n[t]===r[t]||$r(e.style,t,n[t])}else if("o"===t[0]&&"n"===t[1])a=t!==(t=t.replace(/(PointerCapture)$|Capture$/i,"$1")),t=t.toLowerCase()in e||"onFocusOut"===t||"onFocusIn"===t?t.toLowerCase().slice(2):t.slice(2),e.l||(e.l={}),e.l[t+a]=n,n?r?n.u=r.u:(n.u=wr,e.addEventListener(t,a?xr:_r,a)):e.removeEventListener(t,a?xr:_r,a);else{if("http://www.w3.org/2000/svg"==o)t=t.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!=t&&"height"!=t&&"href"!=t&&"list"!=t&&"form"!=t&&"tabIndex"!=t&&"download"!=t&&"rowSpan"!=t&&"colSpan"!=t&&"role"!=t&&"popover"!=t&&t in e)try{e[t]=null==n?"":n;break e}catch(e){}"function"==typeof n||(null==n||!1===n&&"-"!==t[4]?e.removeAttribute(t):e.setAttribute(t,"popover"==t&&1==n?"":n))}}function Hr(e){return function(t){if(this.l){var n=this.l[t.type+e];if(null==t.t)t.t=wr++;else if(t.t<n.u)return;return n(mr.event?mr.event(t):t)}}}function Vr(e,t,n,r,o,a,i,s,c,l){var u,p,d,f,m,h,v,g,b,y,w,_,x,S,k,E,O=t.type;if(void 0!==t.constructor)return null;128&n.__u&&(c=!!(32&n.__u),a=[s=t.__e=n.__e]),(u=mr.__b)&&u(t);e:if("function"==typeof O)try{if(g=t.props,b="prototype"in O&&O.prototype.render,y=(u=O.contextType)&&r[u.__c],w=u?y?y.props.value:u.__:r,n.__c?v=(p=t.__c=n.__c).__=p.__E:(b?t.__c=p=new O(g,w):(t.__c=p=new Ir(g,w),p.constructor=O,p.render=Kr),y&&y.sub(p),p.props=g,p.state||(p.state={}),p.context=w,p.__n=r,d=p.__d=!0,p.__h=[],p._sb=[]),b&&null==p.__s&&(p.__s=p.state),b&&null!=O.getDerivedStateFromProps&&(p.__s==p.state&&(p.__s=jr({},p.__s)),jr(p.__s,O.getDerivedStateFromProps(g,p.__s))),f=p.props,m=p.state,p.__v=t,d)b&&null==O.getDerivedStateFromProps&&null!=p.componentWillMount&&p.componentWillMount(),b&&null!=p.componentDidMount&&p.__h.push(p.componentDidMount);else{if(b&&null==O.getDerivedStateFromProps&&g!==f&&null!=p.componentWillReceiveProps&&p.componentWillReceiveProps(g,w),!p.__e&&(null!=p.shouldComponentUpdate&&!1===p.shouldComponentUpdate(g,p.__s,w)||t.__v===n.__v)){for(t.__v!==n.__v&&(p.props=g,p.state=p.__s,p.__d=!1),t.__e=n.__e,t.__k=n.__k,t.__k.forEach((function(e){e&&(e.__=t)})),_=0;_<p._sb.length;_++)p.__h.push(p._sb[_]);p._sb=[],p.__h.length&&i.push(p);break e}null!=p.componentWillUpdate&&p.componentWillUpdate(g,p.__s,w),b&&null!=p.componentDidUpdate&&p.__h.push((function(){p.componentDidUpdate(f,m,h)}))}if(p.context=w,p.props=g,p.__P=e,p.__e=!1,x=mr.__r,S=0,b){for(p.state=p.__s,p.__d=!1,x&&x(t),u=p.render(p.props,p.state,p.context),k=0;k<p._sb.length;k++)p.__h.push(p._sb[k]);p._sb=[]}else do{p.__d=!1,x&&x(t),u=p.render(p.props,p.state,p.context),p.state=p.__s}while(p.__d&&++S<25);p.state=p.__s,null!=p.getChildContext&&(r=jr(jr({},r),p.getChildContext())),b&&!d&&null!=p.getSnapshotBeforeUpdate&&(h=p.getSnapshotBeforeUpdate(f,m)),Fr(e,Or(E=null!=u&&u.type===Tr&&null==u.key?u.props.children:u)?E:[E],t,n,r,o,a,i,s,c,l),p.base=t.__e,t.__u&=-161,p.__h.length&&i.push(p),v&&(p.__E=p.__=null)}catch(e){if(t.__v=null,c||null!=a){for(t.__u|=c?160:32;s&&8===s.nodeType&&s.nextSibling;)s=s.nextSibling;a[a.indexOf(s)]=null,t.__e=s}else t.__e=n.__e,t.__k=n.__k;mr.__e(e,t,n)}else null==a&&t.__v===n.__v?(t.__k=n.__k,t.__e=n.__e):t.__e=Qr(n.__e,t,n,r,o,a,i,c,l);(u=mr.diffed)&&u(t)}function Wr(e,t,n){t.__d=void 0;for(var r=0;r<n.length;r++)qr(n[r],n[++r],n[++r]);mr.__c&&mr.__c(t,e),e.some((function(t){try{e=t.__h,t.__h=[],e.some((function(e){e.call(t)}))}catch(e){mr.__e(e,t.__v)}}))}function Qr(e,t,n,r,o,a,i,s,c){var l,u,p,d,f,m,h,v=n.props,g=t.props,b=t.type;if("svg"===b?o="http://www.w3.org/2000/svg":"math"===b?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),null!=a)for(l=0;l<a.length;l++)if((f=a[l])&&"setAttribute"in f==!!b&&(b?f.localName===b:3===f.nodeType)){e=f,a[l]=null;break}if(null==e){if(null===b)return document.createTextNode(g);e=document.createElementNS(o,b,g.is&&g),a=null,s=!1}if(null===b)v===g||s&&e.data===g||(e.data=g);else{if(a=a&&fr.call(e.childNodes),v=n.props||Sr,!s&&null!=a)for(v={},l=0;l<e.attributes.length;l++)v[(f=e.attributes[l]).name]=f.value;for(l in v)if(f=v[l],"children"==l);else if("dangerouslySetInnerHTML"==l)p=f;else if("key"!==l&&!(l in g)){if("value"==l&&"defaultValue"in g||"checked"==l&&"defaultChecked"in g)continue;Ur(e,l,null,f,o)}for(l in g)f=g[l],"children"==l?d=f:"dangerouslySetInnerHTML"==l?u=f:"value"==l?m=f:"checked"==l?h=f:"key"===l||s&&"function"!=typeof f||v[l]===f||Ur(e,l,f,v[l],o);if(u)s||p&&(u.__html===p.__html||u.__html===e.innerHTML)||(e.innerHTML=u.__html),t.__k=[];else if(p&&(e.innerHTML=""),Fr(e,Or(d)?d:[d],t,n,r,"foreignObject"===b?"http://www.w3.org/1999/xhtml":o,a,i,a?a[0]:n.__k&&Nr(n,0),s,c),null!=a)for(l=a.length;l--;)null!=a[l]&&Pr(a[l]);s||(l="value",void 0!==m&&(m!==e[l]||"progress"===b&&!m||"option"===b&&m!==v[l])&&Ur(e,l,m,v[l],o),l="checked",void 0!==h&&h!==e[l]&&Ur(e,l,h,v[l],o))}return e}function qr(e,t,n){try{if("function"==typeof e){var r="function"==typeof e.__u;r&&e.__u(),r&&null==t||(e.__u=e(t))}else e.current=t}catch(e){mr.__e(e,n)}}function Gr(e,t,n){var r,o;if(mr.unmount&&mr.unmount(e),(r=e.ref)&&(r.current&&r.current!==e.__e||qr(r,null,t)),null!=(r=e.__c)){if(r.componentWillUnmount)try{r.componentWillUnmount()}catch(e){mr.__e(e,t)}r.base=r.__P=null}if(r=e.__k)for(o=0;o<r.length;o++)r[o]&&Gr(r[o],t,n||"function"!=typeof e.type);n||null==e.__e||Pr(e.__e),e.__c=e.__=e.__e=e.__d=void 0}function Kr(e,t,n){return this.constructor(e,n)}function Yr(e,t,n){var r,o,a,i;mr.__&&mr.__(e,t),o=(r="function"==typeof n)?null:n&&n.__k||t.__k,a=[],i=[],Vr(t,e=(!r&&n||t).__k=Cr(Tr,null,[e]),o||Sr,Sr,t.namespaceURI,!r&&n?[n]:o?null:t.firstChild?fr.call(t.childNodes):null,a,!r&&n?n:o?o.__e:t.firstChild,r,i),Wr(a,e,i)}function Zr(e,t){return t.reduce((function(e,t){return e&&e[t]}),e)}fr=kr.slice,mr={__e:function(e,t,n,r){for(var o,a,i;t=t.__;)if((o=t.__c)&&!o.__)try{if((a=o.constructor)&&null!=a.getDerivedStateFromError&&(o.setState(a.getDerivedStateFromError(e)),i=o.__d),null!=o.componentDidCatch&&(o.componentDidCatch(e,r||{}),i=o.__d),i)return o.__E=o}catch(t){e=t}throw e}},hr=0,Ir.prototype.setState=function(e,t){var n;n=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=jr({},this.state),"function"==typeof e&&(e=e(jr({},n),this.props)),e&&jr(n,e),null!=e&&this.__v&&(t&&this._sb.push(t),Rr(this))},Ir.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),Rr(this))},Ir.prototype.render=Tr,vr=[],br="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,yr=function(e,t){return e.__v.__b-t.__v.__b},Dr.__r=0,wr=0,_r=Hr(!1),xr=Hr(!0);var Xr="__aa-highlight__",Jr="__/aa-highlight__";function eo(e){var t=e.highlightedValue.split(Xr),n=t.shift(),r=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return{get:function(){return e},add:function(t){var n=e[e.length-1];(null==n?void 0:n.isHighlighted)===t.isHighlighted?e[e.length-1]={value:n.value+t.value,isHighlighted:n.isHighlighted}:e.push(t)}}}(n?[{value:n,isHighlighted:!1}]:[]);return t.forEach((function(e){var t=e.split(Jr);r.add({value:t[0],isHighlighted:!0}),""!==t[1]&&r.add({value:t[1],isHighlighted:!1})})),r.get()}function to(e){return function(e){if(Array.isArray(e))return no(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return no(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return no(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function no(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function ro(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=Zr(t,["_highlightResult"].concat(to(r),["value"]));return"string"!=typeof o&&(o=Zr(t,r)||""),eo({highlightedValue:o})}function oo(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,a=e.tagName,i=void 0===a?"mark":a;return t(n,{},ro({hit:r,attribute:o}).map((function(e,n){return e.isHighlighted?t(i,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="Highlight",r}var ao={"&":"&","<":"<",">":">",""":'"',"'":"'"},io=new RegExp(/\w/i),so=/&(amp|quot|lt|gt|#39);/g,co=RegExp(so.source);function lo(e,t){var n,r,o,a=e[t],i=(null===(n=e[t+1])||void 0===n?void 0:n.isHighlighted)||!0,s=(null===(r=e[t-1])||void 0===r?void 0:r.isHighlighted)||!0;return io.test((o=a.value)&&co.test(o)?o.replace(so,(function(e){return ao[e]})):o)||s!==i?a.isHighlighted:s}function uo(e){return uo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},uo(e)}function po(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function fo(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?po(Object(n),!0).forEach((function(t){mo(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):po(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function mo(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==uo(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==uo(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===uo(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ho(e){return e.some((function(e){return e.isHighlighted}))?e.map((function(t,n){return fo(fo({},t),{},{isHighlighted:!lo(e,n)})})):e.map((function(e){return fo(fo({},e),{},{isHighlighted:!1})}))}function vo(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,a=e.attribute,i=e.tagName,s=void 0===i?"mark":i;return t(n,{},(r={hit:o,attribute:a},ho(ro(r))).map((function(e,n){return e.isHighlighted?t(s,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="ReverseHighlight",r}function go(e){return function(e){if(Array.isArray(e))return bo(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return bo(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return bo(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function bo(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function yo(e){var t=e.hit,n=e.attribute,r=Array.isArray(n)?n:[n],o=Zr(t,["_snippetResult"].concat(go(r),["value"]));return"string"!=typeof o&&(o=Zr(t,r)||""),eo({highlightedValue:o})}function wo(e){var t=e.createElement,n=e.Fragment;function r(e){var r,o=e.hit,a=e.attribute,i=e.tagName,s=void 0===i?"mark":i;return t(n,{},(r={hit:o,attribute:a},ho(yo(r))).map((function(e,n){return e.isHighlighted?t(s,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="ReverseSnippet",r}function _o(e){var t=e.createElement,n=e.Fragment;function r(e){var r=e.hit,o=e.attribute,a=e.tagName,i=void 0===a?"mark":a;return t(n,{},yo({hit:r,attribute:o}).map((function(e,n){return e.isHighlighted?t(i,{key:n},e.value):e.value})))}return r.__autocomplete_componentName="Snippet",r}function xo(e,t){if("string"==typeof t){var n=e.document.querySelector(t);return"The element ".concat(JSON.stringify(t)," is not in the document."),n}return t}function So(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce((function(e,t){return Object.keys(t).forEach((function(n){var r=e[n],o=t[n];r!==o&&(e[n]=[r,o].filter(Boolean).join(" "))})),e}),{})}function ko(e){return ko="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},ko(e)}var Eo=["classNames","container","getEnvironmentProps","getFormProps","getInputProps","getItemProps","getLabelProps","getListProps","getPanelProps","getRootProps","panelContainer","panelPlacement","render","renderNoResults","renderer","detachedMediaQuery","components","translations"];function Oo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function jo(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Oo(Object(n),!0).forEach((function(t){Po(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Oo(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Po(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==ko(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==ko(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===ko(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Co(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Ao={clearButton:"aa-ClearButton",detachedCancelButton:"aa-DetachedCancelButton",detachedContainer:"aa-DetachedContainer",detachedFormContainer:"aa-DetachedFormContainer",detachedOverlay:"aa-DetachedOverlay",detachedSearchButton:"aa-DetachedSearchButton",detachedSearchButtonIcon:"aa-DetachedSearchButtonIcon",detachedSearchButtonPlaceholder:"aa-DetachedSearchButtonPlaceholder",detachedSearchButtonQuery:"aa-DetachedSearchButtonQuery",form:"aa-Form",input:"aa-Input",inputWrapper:"aa-InputWrapper",inputWrapperPrefix:"aa-InputWrapperPrefix",inputWrapperSuffix:"aa-InputWrapperSuffix",item:"aa-Item",label:"aa-Label",list:"aa-List",loadingIndicator:"aa-LoadingIndicator",panel:"aa-Panel",panelLayout:"aa-PanelLayout aa-Panel--scrollable",root:"aa-Autocomplete",source:"aa-Source",sourceFooter:"aa-SourceFooter",sourceHeader:"aa-SourceHeader",sourceNoResults:"aa-SourceNoResults",submitButton:"aa-SubmitButton"},To=function(e,t){var n=e.children;(0,e.render)(n,t)},Io={createElement:Cr,Fragment:Tr,render:Yr};function No(e){var t=e.panelPlacement,n=e.container,r=e.form,o=e.environment,a=n.getBoundingClientRect(),i=(o.pageYOffset||o.document.documentElement.scrollTop||o.document.body.scrollTop||0)+a.top+a.height;switch(t){case"start":return{top:i,left:a.left};case"end":return{top:i,right:o.document.documentElement.clientWidth-(a.left+a.width)};case"full-width":return{top:i,left:0,right:0,width:"unset",maxWidth:"unset"};case"input-wrapper-width":var s=r.getBoundingClientRect();return{top:i,left:s.left,right:o.document.documentElement.clientWidth-(s.left+s.width),width:"unset",maxWidth:"unset"};default:throw new Error("[Autocomplete] The `panelPlacement` value ".concat(JSON.stringify(t)," is not valid."))}}function Lo(e){return Lo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Lo(e)}function Ro(){return Ro=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},Ro.apply(this,arguments)}function Do(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Fo(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Do(Object(n),!0).forEach((function(t){Mo(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Do(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Mo(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Lo(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Lo(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Lo(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}var Bo=[{segment:"autocomplete-js",version:yn}];function zo(e){return function(e){if(Array.isArray(e))return $o(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return $o(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return $o(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function $o(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Uo(e){return Uo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Uo(e)}var Ho=function(e){return e&&"object"===Uo(e)&&"[object Object]"===Object.prototype.toString.call(e)};function Vo(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.reduce((function(e,t){return Object.keys(t).forEach((function(n){var r=e[n],o=t[n];Array.isArray(r)&&Array.isArray(o)?e[n]=r.concat.apply(r,zo(o)):Ho(r)&&Ho(o)?e[n]=Vo(r,o):e[n]=o})),e}),{})}function Wo(e){return Wo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Wo(e)}function Qo(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function qo(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?Qo(Object(n),!0).forEach((function(t){Go(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):Qo(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function Go(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Wo(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Wo(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Wo(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function Ko(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=n){var r,o,a,i,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,0===t){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(u){l=!0,o=u}finally{try{if(!c&&null!=n.return&&(i=n.return(),Object(i)!==i))return}finally{if(l)throw o}}return s}}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return Yo(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return Yo(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function Yo(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}var Zo=["components"];function Xo(e){return Xo="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},Xo(e)}function Jo(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r<a.length;r++)n=a[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function ea(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ta(e){for(var t=1;t<arguments.length;t++){var n=null!=arguments[t]?arguments[t]:{};t%2?ea(Object(n),!0).forEach((function(t){na(e,t,n[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):ea(Object(n)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))}))}return e}function na(e,t,n){return(t=function(e){var t=function(e,t){if("object"!==Xo(e)||null===e)return e;var n=e[Symbol.toPrimitive];if(void 0!==n){var r=n.call(e,t||"default");if("object"!==Xo(r))return r;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===t?String:Number)(e)}(e,"string");return"symbol"===Xo(t)?t:String(t)}(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ra(e){var t,n=function(){var e=[],t=[];function n(n){e.push(n);var r=n();t.push(r)}return{runEffect:n,cleanupEffects:function(){var e=t;t=[],e.forEach((function(e){e()}))},runEffects:function(){var t=e;e=[],t.forEach((function(e){n(e)}))}}}(),r=n.runEffect,o=n.cleanupEffects,a=n.runEffects,i=(t=[],{reactive:function(e){var n=e(),r={_fn:e,_ref:{current:n},get value(){return this._ref.current},set value(e){this._ref.current=e}};return t.push(r),r},runReactives:function(){t.forEach((function(e){e._ref.current=e._fn()}))}}),s=i.reactive,c=i.runReactives,l=ye(!1),u=ye(e),p=ye(void 0),d=s((function(){return function(e){var t,n=e.classNames,r=e.container,o=e.getEnvironmentProps,a=e.getFormProps,i=e.getInputProps,s=e.getItemProps,c=e.getLabelProps,l=e.getListProps,u=e.getPanelProps,p=e.getRootProps,d=e.panelContainer,f=e.panelPlacement,m=e.render,h=e.renderNoResults,v=e.renderer,g=e.detachedMediaQuery,b=e.components,y=e.translations,w=Co(e,Eo),_="undefined"!=typeof window?window:{},x=xo(_,r);x.tagName;var S=jo(jo({},Io),v),k={Highlight:oo(S),ReverseHighlight:vo(S),ReverseSnippet:wo(S),Snippet:_o(S)};return{renderer:{classNames:So(Ao,null!=n?n:{}),container:x,getEnvironmentProps:null!=o?o:function(e){return e.props},getFormProps:null!=a?a:function(e){return e.props},getInputProps:null!=i?i:function(e){return e.props},getItemProps:null!=s?s:function(e){return e.props},getLabelProps:null!=c?c:function(e){return e.props},getListProps:null!=l?l:function(e){return e.props},getPanelProps:null!=u?u:function(e){return e.props},getRootProps:null!=p?p:function(e){return e.props},panelContainer:d?xo(_,d):_.document.body,panelPlacement:null!=f?f:"input-wrapper-width",render:null!=m?m:To,renderNoResults:h,renderer:S,detachedMediaQuery:null!=g?g:getComputedStyle(_.document.documentElement).getPropertyValue("--aa-detached-media-query"),components:jo(jo({},k),b),translations:jo(jo({},{clearButtonTitle:"Clear",detachedCancelButtonText:"Cancel",detachedSearchButtonTitle:"Search",submitButtonTitle:"Submit"}),y)},core:jo(jo({},w),{},{id:null!==(t=w.id)&&void 0!==t?t:ct(),environment:_})}}(u.current)})),f=s((function(){return d.value.core.environment.matchMedia(d.value.renderer.detachedMediaQuery).matches})),m=s((function(){return Fn(ta(ta({},d.value.core),{},{onStateChange:function(e){var t,n,r;l.current=e.state.collections.some((function(e){return e.source.templates.noResults})),null===(t=p.current)||void 0===t||t.call(p,e),null===(n=(r=d.value.core).onStateChange)||void 0===n||n.call(r,e)},shouldPanelOpen:u.current.shouldPanelOpen||function(e){var t=e.state;if(f.value)return!0;var n=it(t)>0;if(!d.value.core.openOnFocus&&!t.query)return n;var r=Boolean(l.current||d.value.renderer.renderNoResults);return!n&&r||n},__autocomplete_metadata:{userAgents:Bo,options:e}}))})),h=ye(ta({collections:[],completion:null,context:{},isOpen:!1,query:"",activeItemId:null,status:"idle"},d.value.core.initialState)),v={getEnvironmentProps:d.value.renderer.getEnvironmentProps,getFormProps:d.value.renderer.getFormProps,getInputProps:d.value.renderer.getInputProps,getItemProps:d.value.renderer.getItemProps,getLabelProps:d.value.renderer.getLabelProps,getListProps:d.value.renderer.getListProps,getPanelProps:d.value.renderer.getPanelProps,getRootProps:d.value.renderer.getRootProps},g={setActiveItemId:m.value.setActiveItemId,setQuery:m.value.setQuery,setCollections:m.value.setCollections,setIsOpen:m.value.setIsOpen,setStatus:m.value.setStatus,setContext:m.value.setContext,refresh:m.value.refresh,navigator:m.value.navigator},b=s((function(){return zn.bind(d.value.renderer.renderer.createElement)})),y=s((function(){return function(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.classNames,o=e.environment,a=e.isDetached,i=e.placeholder,s=void 0===i?"Search":i,c=e.propGetters,l=e.setIsModalOpen,u=e.state,p=e.translations,d=tr(o),f=c.getRootProps(pr({state:u,props:t.getRootProps({})},n)),m=d("div",pr({class:r.root},f)),h=d("div",{class:r.detachedContainer,onMouseDown:function(e){e.stopPropagation()}}),v=d("div",{class:r.detachedOverlay,children:[h],onMouseDown:function(){l(!1),t.setIsOpen(!1)}}),g=c.getLabelProps(pr({state:u,props:t.getLabelProps({})},n)),b=d("button",{class:r.submitButton,type:"submit",title:p.submitButtonTitle,children:[$n({environment:o})]}),y=d("label",pr({class:r.label,children:[b],ariaLabel:p.submitButtonTitle},g)),w=d("button",{class:r.clearButton,type:"reset",title:p.clearButtonTitle,children:[Un({environment:o})]}),_=d("div",{class:r.loadingIndicator,children:[Hn({environment:o})]}),x=cr({class:r.input,environment:o,state:u,getInputProps:c.getInputProps,getInputPropsCore:t.getInputProps,autocompleteScopeApi:n,isDetached:a}),S=d("div",{class:r.inputWrapperPrefix,children:[y,_]}),k=d("div",{class:r.inputWrapperSuffix,children:[w]}),E=d("div",{class:r.inputWrapper,children:[x]}),O=c.getFormProps(pr({state:u,props:t.getFormProps({inputElement:x})},n)),j=d("form",pr({class:r.form,children:[S,E,k]},O)),P=c.getPanelProps(pr({state:u,props:t.getPanelProps({})},n)),C=d("div",pr({class:r.panel},P)),A=d("div",{class:r.detachedSearchButtonQuery,textContent:u.query}),T=d("div",{class:r.detachedSearchButtonPlaceholder,hidden:Boolean(u.query),textContent:s});if(a){var I=d("div",{class:r.detachedSearchButtonIcon,children:[$n({environment:o})]}),N=d("button",{type:"button",class:r.detachedSearchButton,title:p.detachedSearchButtonTitle,id:g.id,onClick:function(){l(!0)},children:[I,T,A]}),L=d("button",{type:"button",class:r.detachedCancelButton,textContent:p.detachedCancelButtonText,onTouchStart:function(e){e.stopPropagation()},onClick:function(){t.setIsOpen(!1),l(!1)}}),R=d("div",{class:r.detachedFormContainer,children:[j,L]});h.appendChild(R),m.appendChild(N)}else m.appendChild(j);return{detachedContainer:h,detachedOverlay:v,detachedSearchButtonQuery:A,detachedSearchButtonPlaceholder:T,inputWrapper:E,input:x,root:m,form:j,label:y,submitButton:b,clearButton:w,loadingIndicator:_,panel:C}}({autocomplete:m.value,autocompleteScopeApi:g,classNames:d.value.renderer.classNames,environment:d.value.core.environment,isDetached:f.value,placeholder:d.value.core.placeholder,propGetters:v,setIsModalOpen:S,state:h.current,translations:d.value.renderer.translations})}));function w(){Kn(y.value.panel,{style:f.value?{}:No({panelPlacement:d.value.renderer.panelPlacement,container:y.value.root,form:y.value.form,environment:d.value.core.environment})})}function _(e){h.current=e;var t={autocomplete:m.value,autocompleteScopeApi:g,classNames:d.value.renderer.classNames,components:d.value.renderer.components,container:d.value.renderer.container,html:b.value,dom:y.value,panelContainer:f.value?y.value.detachedContainer:d.value.renderer.panelContainer,propGetters:v,state:h.current,renderer:d.value.renderer.renderer},n=!it(e)&&!l.current&&d.value.renderer.renderNoResults||d.value.renderer.render;!function(e){var t=e.autocomplete,n=e.autocompleteScopeApi,r=e.dom,o=e.propGetters,a=e.state;Yn(r.root,o.getRootProps(Fo({state:a,props:t.getRootProps({})},n))),Yn(r.input,o.getInputProps(Fo({state:a,props:t.getInputProps({inputElement:r.input}),inputElement:r.input},n))),Kn(r.label,{hidden:"stalled"===a.status}),Kn(r.loadingIndicator,{hidden:"stalled"!==a.status}),Kn(r.clearButton,{hidden:!a.query}),Kn(r.detachedSearchButtonQuery,{textContent:a.query}),Kn(r.detachedSearchButtonPlaceholder,{hidden:Boolean(a.query)})}(t),function(e,t){var n=t.autocomplete,r=t.autocompleteScopeApi,o=t.classNames,a=t.html,i=t.dom,s=t.panelContainer,c=t.propGetters,l=t.state,u=t.components,p=t.renderer;if(l.isOpen){s.contains(i.panel)||"loading"===l.status||s.appendChild(i.panel),i.panel.classList.toggle("aa-Panel--stalled","stalled"===l.status);var d=l.collections.filter((function(e){var t=e.source,n=e.items;return t.templates.noResults||n.length>0})).map((function(e,t){var i=e.source,s=e.items;return p.createElement("section",{key:t,className:o.source,"data-autocomplete-source-id":i.sourceId},i.templates.header&&p.createElement("div",{className:o.sourceHeader},i.templates.header({components:u,createElement:p.createElement,Fragment:p.Fragment,items:s,source:i,state:l,html:a})),i.templates.noResults&&0===s.length?p.createElement("div",{className:o.sourceNoResults},i.templates.noResults({components:u,createElement:p.createElement,Fragment:p.Fragment,source:i,state:l,html:a})):p.createElement("ul",Ro({className:o.list},c.getListProps(Fo({state:l,props:n.getListProps({source:i})},r))),s.map((function(e){var t=n.getItemProps({item:e,source:i});return p.createElement("li",Ro({key:t.id,className:o.item},c.getItemProps(Fo({state:l,props:t},r))),i.templates.item({components:u,createElement:p.createElement,Fragment:p.Fragment,item:e,state:l,html:a}))}))),i.templates.footer&&p.createElement("div",{className:o.sourceFooter},i.templates.footer({components:u,createElement:p.createElement,Fragment:p.Fragment,items:s,source:i,state:l,html:a})))})),f=p.createElement(p.Fragment,null,p.createElement("div",{className:o.panelLayout},d),p.createElement("div",{className:"aa-GradientBottom"})),m=d.reduce((function(e,t){return e[t.props["data-autocomplete-source-id"]]=t,e}),{});e(Fo(Fo({children:f,state:l,sections:d,elements:m},p),{},{components:u,html:a},r),i.panel)}else s.contains(i.panel)&&s.removeChild(i.panel)}(n,t)}function x(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};o();var t,n,r=d.value.renderer,i=r.components,s=Jo(r,Zo);u.current=Vo(s,d.value.core,{components:(t=i,n=function(e){return!e.value.hasOwnProperty("__autocomplete_componentName")},Object.entries(t).reduce((function(e,t){var r=Ko(t,2),o=r[0],a=r[1];return n({key:o,value:a})?qo(qo({},e),{},Go({},o,a)):e}),{})),initialState:h.current},e),c(),a(),m.value.refresh().then((function(){_(h.current)}))}function S(e){e!==d.value.core.environment.document.body.contains(y.value.detachedOverlay)&&(e?(d.value.core.environment.document.body.appendChild(y.value.detachedOverlay),d.value.core.environment.document.body.classList.add("aa-Detached"),y.value.input.focus()):(d.value.core.environment.document.body.removeChild(y.value.detachedOverlay),d.value.core.environment.document.body.classList.remove("aa-Detached")))}return r((function(){var e=m.value.getEnvironmentProps({formElement:y.value.form,panelElement:y.value.panel,inputElement:y.value.input});return Kn(d.value.core.environment,e),function(){Kn(d.value.core.environment,Object.keys(e).reduce((function(e,t){return ta(ta({},e),{},na({},t,void 0))}),{}))}})),r((function(){var e=f.value?d.value.core.environment.document.body:d.value.renderer.panelContainer,t=f.value?y.value.detachedOverlay:y.value.panel;return f.value&&h.current.isOpen&&S(!0),_(h.current),function(){e.contains(t)&&(e.removeChild(t),e.classList.remove("aa-Detached"))}})),r((function(){var e=d.value.renderer.container;return e.appendChild(y.value.root),function(){e.removeChild(y.value.root)}})),r((function(){var e=be((function(e){_(e.state)}),0);return p.current=function(t){var n=t.state,r=t.prevState;(f.value&&r.isOpen!==n.isOpen&&S(n.isOpen),f.value||!n.isOpen||r.isOpen||w(),n.query!==r.query)&&d.value.core.environment.document.querySelectorAll(".aa-Panel--scrollable").forEach((function(e){0!==e.scrollTop&&(e.scrollTop=0)}));e({state:n})},function(){p.current=void 0}})),r((function(){var e=be((function(){var e=f.value;f.value=d.value.core.environment.matchMedia(d.value.renderer.detachedMediaQuery).matches,e!==f.value?x({}):requestAnimationFrame(w)}),20);return d.value.core.environment.addEventListener("resize",e),function(){d.value.core.environment.removeEventListener("resize",e)}})),r((function(){if(!f.value)return function(){};function e(e){y.value.detachedContainer.classList.toggle("aa-DetachedContainer--modal",e)}function t(t){e(t.matches)}var n=d.value.core.environment.matchMedia(getComputedStyle(d.value.core.environment.document.documentElement).getPropertyValue("--aa-detached-modal-media-query"));e(n.matches);var r=Boolean(n.addEventListener);return r?n.addEventListener("change",t):n.addListener(t),function(){r?n.removeEventListener("change",t):n.removeListener(t)}})),r((function(){return requestAnimationFrame(w),function(){}})),ta(ta({},g),{},{update:x,destroy:function(){o()}})}var oa=n(24502);const aa=n(24221);aa.tokenizer.separator=/[\s\-]+/;const ia=aa;var sa=n(689),ca=n.n(sa);function la(){const e=(0,s.zy)(),t=(0,s.W6)(),{siteConfig:{baseUrl:n}}=(0,ce.A)(),[o,a]=(0,r.useState)({terms:[],isDocsOrBlog:!1});return(0,r.useEffect)((()=>{if(!e.state?.cmfcmfhighlight||0===e.state.cmfcmfhighlight.terms.length)return;a(e.state.cmfcmfhighlight);const{cmfcmfhighlight:n,...r}=e.state;t.replace({...e,state:r})}),[e.state?.cmfcmfhighlight,t,e]),(0,r.useEffect)((()=>{if(0===o.terms.length)return;const e=o.isDocsOrBlog?document.getElementsByTagName("article")[0]:document.getElementsByTagName("main")[0];if(!e)return;const t=new(ca())(e),n={ignoreJoiners:!0};return t.mark(o.terms,n),()=>t.unmark(n)}),[o,n]),null}var ua=n(62114),pa=n(59529);function da(e){let{document:t}=e;const[n,r]=t.sectionRoute.split("#");let o=n;return r&&(o+="#"+r),o}const fa={documents:[],index:ia((function(){this.ref("id"),this.field("title"),this.field("content")}))};const ma=()=>{const e=(0,B.A)(),[t,o]=(0,r.useState)((()=>!!e&&"dark"===document.documentElement.getAttribute("data-theme")));(0,r.useEffect)((()=>{const e=new MutationObserver((()=>{o("dark"===document.documentElement.getAttribute("data-theme"))}));return e.observe(document.documentElement,{attributes:!0,attributeFilter:["data-theme"]}),()=>e.disconnect()}),[]);const{siteConfig:{baseUrl:a}}=(0,ce.A)(),{titleBoost:i,contentBoost:l,tagsBoost:u,parentCategoriesBoost:p,indexDocSidebarParentCategories:d,maxSearchResults:f}=(0,ua.P_)("@cmfcmf/docusaurus-search-local"),m=(0,s.W6)(),{tags:h}=function(){const{i18n:e}=(0,ce.A)(),t=n(80869).vF(),r=[pa.C,...t];return{locale:e.currentLocale,tags:r}}(),v=(0,r.useRef)(h);(0,r.useEffect)((()=>{v.current=h}),[h]);const g=(0,r.useRef)({}),b=async e=>{const t=g.current[e];switch(t?.state){case"ready":return t;case void 0:{const t=[];g.current[e]={state:"loading",callbacks:t};const n=await async function(e,t){{let r;try{const n=await fetch(`${e}search-index-${t}.json`);if(!n.ok)return fa;r=await n.json()}catch(n){return fa}return{documents:r.documents,index:ia.Index.load(r.index)}}}(a,e);return t.forEach((e=>e(n))),g.current[e]={state:"ready",...n}}case"loading":return new Promise((e=>{t.callbacks.push(e)}))}},y=(0,c.T)({message:"cmfcmf/d-s-l.searchBar.placeholder",description:"Placeholder shown in the searchbar"}),w=(0,r.useRef)(null),_=(0,r.useRef)(null);return(0,r.useEffect)((()=>{if(w.current)return _.current=ra({container:w.current,placeholder:y,renderer:{createElement:r.createElement,Fragment:r.Fragment,render:ge.render},navigator:{navigate(e){let{item:t,itemUrl:n}=e;m.push(n,{cmfcmfhighlight:{terms:t.terms,isDocsOrBlog:"docs"===t.document.type||"blog"===t.document.type}})}},detachedMediaQuery:"",defaultActiveItemId:0,translations:{clearButtonTitle:(0,c.T)({message:"cmfcmf/d-s-l.searchBar.clearButtonTitle",description:"Title of the button to clear the current search input"}),detachedCancelButtonText:(0,c.T)({message:"cmfcmf/d-s-l.searchBar.detachedCancelButtonText",description:"Text of the button to close the detached search window"}),submitButtonTitle:(0,c.T)({message:"cmfcmf/d-s-l.searchBar.submitButtonTitle",description:"Title of the button to submit a new search"})},getSources(e){let{query:t}=e;return[{sourceId:"search-results",templates:{item(e){let{item:t}=e;const n=da(t);return r.createElement("a",{href:n,className:"aa-ItemLink",onClick:e=>{e.preventDefault(),m.push(n,{cmfcmfhighlight:{terms:t.terms,isDocsOrBlog:"docs"===t.document.type||"blog"===t.document.type}})}},r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},r.createElement("div",{className:"aa-ItemContentTitle"},t.document.sectionTitle),t.document.pageTitle!==t.document.sectionTitle&&r.createElement("div",{className:"aa-ItemContentDescription"},t.document.pageTitle))),r.createElement("div",{className:"aa-ItemActions"},r.createElement("button",{className:"aa-ItemActionButton aa-DesktopOnly aa-ActiveOnly",type:"button",title:"Select"},r.createElement("svg",{viewBox:"0 0 24 24",width:"20",height:"20",fill:"currentColor"},r.createElement("path",{d:"M18.984 6.984h2.016v6h-15.188l3.609 3.609-1.406 1.406-6-6 6-6 1.406 1.406-3.609 3.609h13.172v-4.031z"})))))},noResults:()=>r.createElement("div",{className:"aa-ItemContent"},r.createElement("div",{className:"aa-ItemContentBody"},(0,c.T)({message:"cmfcmf/d-s-l.searchBar.noResults",description:"message shown if no results are found"})))},getItemUrl(e){let{item:t}=e;return da(t)},async getItems(){const e=v.current,n=await Promise.all(e.map((e=>b(e)))),r=(e=>aa.tokenizer(e).map((e=>e.str)))(t);return n.flatMap((e=>{let{index:t,documents:n}=e;return t.query((e=>{e.term(r,{fields:["title"],boost:i}),e.term(r,{fields:["title"],boost:i,wildcard:ia.Query.wildcard.TRAILING}),e.term(r,{fields:["content"],boost:l}),e.term(r,{fields:["content"],boost:l,wildcard:ia.Query.wildcard.TRAILING}),e.term(r,{fields:["tags"],boost:u}),e.term(r,{fields:["tags"],boost:u,wildcard:ia.Query.wildcard.TRAILING}),d&&(e.term(r,{fields:["sidebarParentCategories"],boost:p}),e.term(r,{fields:["sidebarParentCategories"],boost:p,wildcard:ia.Query.wildcard.TRAILING}))})).slice(0,f).map((e=>({document:n.find((t=>t.id.toString()===e.ref)),score:e.score,terms:r})))})).sort(((e,t)=>t.score-e.score)).slice(0,f)}}]}}),()=>_.current?.destroy()}),[f]),r.createElement(r.Fragment,null,r.createElement(oa.A,null,r.createElement("body",{"data-theme":t?"dark":"light"})),r.createElement(la,null),r.createElement("div",{className:"dsla-search-wrapper"},r.createElement("div",{className:"dsla-search-field",ref:w,"data-tags":h.join(",")})))},ha={navbarSearchContainer:"navbarSearchContainer_Bca1"};function va(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.A)(n,ha.navbarSearchContainer),children:t})}var ga=n(80869),ba=n(85246);var ya=n(36220);function wa(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const _a={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:l,localeConfigs:p}}=(0,ce.A)(),d=(0,me.o)(),{search:f,hash:m}=(0,s.zy)(),h=[...n,...l.map((e=>{const n=`${`pathname://${d.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}${o}`;return{label:p[e].label,lang:p[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],v=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):p[i].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:ve}),v]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(va,{className:n,children:(0,u.jsx)(ma,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.A)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,ga.zK)(r),i=(0,ba.QB)(t,r),s=a?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>s||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,ga.zK)(r),i=(0,ba.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,ba.Vd)(r)[0],i=t??a.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:l,hash:p}=(0,s.zy)(),d=(0,ga.zK)(n),f=(0,ga.jh)(n),{savePreferredVersionName:m}=(0,ya.g1)(n),h=[...o,...f.map((function(e){const t=wa(e,d);return{label:e.label,to:`${t.path}${l}${p}`,isActive:()=>e===d.activeVersion,onClick:()=>m(e.name)}})),...a],v=(0,ba.Vd)(n)[0],g=t&&h.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):v.label,b=t&&h.length>1?void 0:wa(v,d).path;return h.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:g,to:b,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:g,to:b,items:h,isActive:r?()=>!1:void 0})}},xa=_a;function Sa(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=xa[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function ka(){const e=(0,C.M)(),t=(0,w.p)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Sa,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ea(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Oa(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ea,{onClick:()=>t.hide()}),t.content]})}function ja(){const e=(0,C.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(F,{header:(0,u.jsx)(Y,{}),primaryMenu:(0,u.jsx)(ka,{}),secondaryMenu:(0,u.jsx)(Oa,{})}):null}const Pa={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ca(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function Aa(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,w.p)(),i=(0,C.M)(),{navbarRef:s,isNavbarVisible:p}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,A.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i<a.current)return void n(!0);if(o.current)return void(o.current=!1);const s=r?.scrollY,c=document.documentElement.scrollHeight-a.current,l=window.innerHeight;s&&i>=s?n(!1):i+l<c&&n(!0)})),(0,l.$)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Pa.navbarHideable,!p&&Pa.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Ca,{onClick:i.toggle}),(0,u.jsx)(ja,{})]})}var Ta=n(71373);const Ia="right";function Na(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function La(){const{toggle:e,shown:t}=(0,C.M)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(Na,{})})}const Ra={colorModeToggle:"colorModeToggle_DEke"};function Da(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(Ta.k2,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Sa,{...e})},t)))})}function Fa(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function Ma(){const e=(0,C.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??Ia)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(Fa,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(La,{}),(0,u.jsx)(G,{}),(0,u.jsx)(Da,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Da,{items:r}),(0,u.jsx)(Q,{className:Ra.colorModeToggle}),!o&&(0,u.jsx)(va,{children:(0,u.jsx)(ma,{})})]})})}function Ba(){return(0,u.jsx)(Aa,{children:(0,u.jsx)(Ma,{})})}function za(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,s=(0,X.Ay)(n),c=(0,X.Ay)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Z.A,{className:"footer__link-item",...r?{href:a?c:r}:{to:s},...i,children:[o,r&&!(0,J.A)(r)&&(0,u.jsx)(te.A,{})]})}function $a(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(za,{item:t})},t.href??t.to)}function Ua(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)($a,{item:e},t)))})]})}function Ha(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(Ua,{column:e},t)))})}function Va(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function Wa(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(za,{item:t})}function Qa(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(Wa,{item:e}),t.length!==n+1&&(0,u.jsx)(Va,{})]},n)))})})}function qa(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(Ha,{columns:t}):(0,u.jsx)(Qa,{links:t})}var Ga=n(9659);const Ka={footerLogoLink:"footerLogoLink_BH7S"};function Ya(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(Ga.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function Za(e){let{logo:t}=e;return t.href?(0,u.jsx)(Z.A,{href:t.href,className:Ka.footerLogoLink,target:t.target,children:(0,u.jsx)(Ya,{logo:t})}):(0,u.jsx)(Ya,{logo:t})}function Xa(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Ja(e){let{style:t,links:n,logo:r,copyright:a}=e;return(0,u.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,u.jsxs)("div",{className:"container container-fluid",children:[n,(r||a)&&(0,u.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,u.jsx)("div",{className:"margin-bottom--sm",children:r}),a]})]})})}function ei(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,u.jsx)(Ja,{style:o,links:n&&n.length>0&&(0,u.jsx)(qa,{links:n}),logo:r&&(0,u.jsx)(Za,{logo:r}),copyright:t&&(0,u.jsx)(Xa,{copyright:t})})}const ti=r.memo(ei),ni=(0,T.fM)([M.a,_.o,A.Tv,ya.VQ,i.Jx,function(e){let{children:t}=e;return(0,u.jsx)(I.y_,{children:(0,u.jsx)(C.e,{children:(0,u.jsx)(L,{children:t})})})}]);function ri(e){let{children:t}=e;return(0,u.jsx)(ni,{children:t})}var oi=n(98445);function ai(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(oi.A,{as:"h1",className:"hero__title",children:(0,u.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(Ta.a2,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(Ta.bq,{error:t})})]})})})}const ii={mainWrapper:"mainWrapper_z2l0"};function si(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:c}=e;return(0,g.J)(),(0,u.jsxs)(ri,{children:[(0,u.jsx)(i.be,{title:s,description:c}),(0,u.jsx)(y,{}),(0,u.jsx)(P,{}),(0,u.jsx)(Ba,{}),(0,u.jsx)("div",{id:p,className:(0,o.A)(v.G.wrapper.main,ii.mainWrapper,r),children:(0,u.jsx)(a.A,{fallback:e=>(0,u.jsx)(ai,{...e}),children:t})}),!n&&(0,u.jsx)(ti,{})]})}},979:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var r=n(57880),o=n(24763),a=n(25792),i=n(31436),s=n(9659),c=n(74848);function l(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},i=(0,c.jsx)(s.A,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,c.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.A)(),{navbar:{title:n,logo:s}}=(0,i.p)(),{imageClassName:u,titleClassName:p,...d}=e,f=(0,o.Ay)(s?.href||"/"),m=n?"":t,h=s?.alt??m;return(0,c.jsxs)(r.A,{to:f,...d,...s?.target&&{target:s.target},children:[s&&(0,c.jsx)(l,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,c.jsx)("b",{className:p,children:n})]})}},28505:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});n(96540);var r=n(24502),o=n(74848);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},9659:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});var r=n(96540),o=n(34164),a=n(94753),i=n(65331);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(74848);function l(e){let{className:t,children:n}=e;const l=(0,a.A)(),{colorMode:u}=(0,i.G)();return(0,c.jsx)(c.Fragment,{children:(l?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.A)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,c.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,c.jsx)(l,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,c.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},70936:(e,t,n)=>{"use strict";n.d(t,{N:()=>g,u:()=>l});var r=n(96540),o=n(71191),a=n(68963),i=n(14459),s=n(74848);const c="ease-in-out";function l(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},p={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?u:p;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return d(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.A.canUseDOM)return e?u:p}function h(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:c,disableSSRStyle:l}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,s.jsx)(t,{ref:u,style:l?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(u.current,n),i?.(n))},className:c,children:o})}function v(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[c,l]=(0,r.useState)(t);return(0,a.A)((()=>{t||i(!0)}),[t]),(0,a.A)((()=>{o&&l(t)}),[o,t]),o?(0,s.jsx)(h,{...n,collapsed:c}):null}function g(e){let{lazy:t,...n}=e;const r=t?v:h;return(0,s.jsx)(r,{...n})}},82459:(e,t,n)=>{"use strict";n.d(t,{M:()=>h,o:()=>m});var r=n(96540),o=n(94753),a=n(45054),i=n(15302),s=n(31436),c=n(74848);const l=(0,a.Wf)("docusaurus.announcement.dismiss"),u=(0,a.Wf)("docusaurus.announcement.id"),p=()=>"true"===l.get(),d=e=>l.set(String(e)),f=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.p)(),t=(0,o.A)(),[n,a]=(0,r.useState)((()=>!!t&&p()));(0,r.useEffect)((()=>{a(p())}),[]);const i=(0,r.useCallback)((()=>{d(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&p()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,c.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},65331:(e,t,n)=>{"use strict";n.d(t,{G:()=>g,a:()=>v});var r=n(96540),o=n(71191),a=n(15302),i=n(45054),s=n(31436),c=n(74848);const l=r.createContext(void 0),u="theme",p=(0,i.Wf)(u),d={light:"light",dark:"dark"},f=e=>e===d.dark?d.dark:d.light,m=e=>o.A.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{p.set(f(e))};function v(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.p)(),[o,a]=(0,r.useState)(m(e));(0,r.useEffect)((()=>{t&&p.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&h(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),p.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=p.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[o,i])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function g(){const e=(0,r.useContext)(l);if(null==e)throw new a.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},1227:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>d});var r=n(96540),o=n(67078),a=n(49607),i=n(9579),s=n(31436),c=n(15302),l=n(74848);const u=r.createContext(void 0);function p(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,s.p)().navbar;return 0===t.length&&!e.component}(),t=(0,a.l)(),n=!e&&"mobile"===t,[c,l]=(0,r.useState)(!1);(0,i.$Z)((()=>{if(c)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:c})),[e,n,u,c])}function d(e){let{children:t}=e;const n=p();return(0,l.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},67078:(e,t,n)=>{"use strict";n.d(t,{GX:()=>l,YL:()=>c,y_:()=>s});var r=n(96540),o=n(15302),a=n(74848);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,s]=a,c=(0,o.Be)(n);return(0,r.useEffect)((()=>{s({component:t,props:c})}),[s,t,c]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},2920:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>a});var r=n(96540);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},49607:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(96540),o=n(71191);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},74717:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},14459:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},71373:(e,t,n)=>{"use strict";n.d(t,{bq:()=>u,MN:()=>l,a2:()=>c,k2:()=>p});var r=n(96540),o=n(32032),a=n(9458);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(74848);function c(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(o.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function l(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(c,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,a.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class p extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},9579:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>i,aZ:()=>c});var r=n(96540),o=n(56347),a=n(15302);function i(e){!function(e){const t=(0,o.W6)(),n=(0,a._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},52808:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{XI:()=>r,sb:()=>o})},63523:(e,t,n)=>{"use strict";n.d(t,{e3:()=>f,be:()=>p,Jx:()=>m});var r=n(96540),o=n(34164),a=n(24502),i=n(92764);function s(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var c=n(24763),l=n(25792);var u=n(74848);function p(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const s=function(e){const{siteConfig:t}=(0,l.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:p}=(0,c.hH)(),d=o?p(o,{absolute:!0}):void 0;return(0,u.jsxs)(a.A,{children:[t&&(0,u.jsx)("title",{children:s}),t&&(0,u.jsx)("meta",{property:"og:title",content:s}),n&&(0,u.jsx)("meta",{name:"description",content:n}),n&&(0,u.jsx)("meta",{property:"og:description",content:n}),r&&(0,u.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),d&&(0,u.jsx)("meta",{property:"og:image",content:d}),d&&(0,u.jsx)("meta",{name:"twitter:image",content:d}),i]})}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,o.A)(i,t);return(0,u.jsxs)(d.Provider,{value:s,children:[(0,u.jsx)(a.A,{children:(0,u.jsx)("html",{className:s})}),n]})}function m(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,u.jsx)(f,{className:(0,o.A)(r,a),children:t})}},15302:(e,t,n)=>{"use strict";n.d(t,{Be:()=>l,ZC:()=>s,_q:()=>i,dV:()=>c,fM:()=>u});var r=n(96540),o=n(68963),a=n(74848);function i(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},86707:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>s,ys:()=>i});var r=n(96540),o=n(38858),a=n(25792);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,a.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},53622:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>u,a_:()=>m,gk:()=>h});var r=n(96540),o=n(71191),a=n(94753),i=n(68963),s=n(15302),c=n(74848);const l=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function p(){const e=(0,r.useContext)(l);if(null==e)throw new s.dV("ScrollControllerProvider");return e}const d=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=p(),o=(0,r.useRef)(d()),a=(0,s._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function m(){const e=p(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.A)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function h(){const e=(0,r.useRef)(null),t=(0,a.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},59529:(e,t,n)=>{"use strict";n.d(t,{C:()=>r});const r="default"},45054:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>u,Dv:()=>p});var r=n(96540);const o=JSON.parse('{"N":"localStorage","M":""}'),a=o.N;function i(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function s(e){if(void 0===e&&(e=a),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,c||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),c=!0),null}var t}let c=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){const n=`${e}${o.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const r=s(t?.persistence);return null===r?l:{get:()=>{try{return r.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=r.getItem(n);r.setItem(n,e),i({key:n,oldValue:t,newValue:e,storage:r})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=r.getItem(n);r.removeItem(n),i({key:n,oldValue:e,newValue:null,storage:r})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===r&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}function p(e,t){const n=(0,r.useRef)((()=>null===e?l:u(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},62473:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(25792),o=n(56347),a=n(9458);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.A)(),{pathname:c}=(0,o.zy)(),l=(0,a.Ks)(c,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),p=l.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${p}`}}}},24232:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(96540),o=n(56347),a=n(15302);function i(e){const t=(0,o.zy)(),n=(0,a.ZC)(t),i=(0,a._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},31436:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(25792);function o(){return(0,r.A)().siteConfig.themeConfig}},29357:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),s="/"===i||i===r?i:(c=i,l=n,l?o(c):a(c));var c,l;return e.replace(i,s)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=a;const r=n(19184);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,r.removeSuffix)(e,"/")}},1155:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},9458:(e,t,n)=>{"use strict";t.rA=t.Ks=void 0;const r=n(31635);var o=n(29357);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var a=n(19184);var i=n(1155);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},19184:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>O,yJ:()=>f,sC:()=>P,AO:()=>d});var r=n(58168);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const i=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],i=t&&t.split("/")||[],s=e&&o(e),c=t&&o(t),l=s||c;if(e&&o(e)?i=r:r.length&&(i.pop(),i=i.concat(r)),!i.length)return"/";if(i.length){var u=i[i.length-1];n="."===u||".."===u||""===u}else n=!1;for(var p=0,d=i.length;d>=0;d--){var f=i[d];"."===f?a(i,d):".."===f?(a(i,d),p++):p&&(a(i,d),p--)}if(!l)for(;p--;p)i.unshift("..");!l||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(11561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function d(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.A)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var h=!("undefined"==typeof window||!window.document||!window.document.createElement);function v(e,t){t(window.confirm(e))}var g="popstate",b="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),h||(0,s.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,a=!(-1===window.navigator.userAgent.indexOf("Trident")),i=e,l=i.forceRefresh,w=void 0!==l&&l,_=i.getUserConfirmation,x=void 0===_?v:_,S=i.keyLength,k=void 0===S?6:S,E=e.basename?p(c(e.basename)):"";function O(e){var t=e||{},n=t.key,r=t.state,o=window.location,a=o.pathname+o.search+o.hash;return E&&(a=u(a,E)),f(a,r,n)}function j(){return Math.random().toString(36).substr(2,k)}var P=m();function C(e){(0,r.A)($,e),$.length=n.length,P.notifyListeners($.location,$.action)}function A(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||N(O(e.state))}function T(){N(O(y()))}var I=!1;function N(e){if(I)I=!1,C();else{P.confirmTransitionTo(e,"POP",x,(function(t){t?C({action:"POP",location:e}):function(e){var t=$.location,n=R.indexOf(t.key);-1===n&&(n=0);var r=R.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(I=!0,F(o))}(e)}))}}var L=O(y()),R=[L.key];function D(e){return E+d(e)}function F(e){n.go(e)}var M=0;function B(e){1===(M+=e)&&1===e?(window.addEventListener(g,A),a&&window.addEventListener(b,T)):0===M&&(window.removeEventListener(g,A),a&&window.removeEventListener(b,T))}var z=!1;var $={length:n.length,action:"POP",location:L,createHref:D,push:function(e,t){var r="PUSH",a=f(e,t,j(),$.location);P.confirmTransitionTo(a,r,x,(function(e){if(e){var t=D(a),i=a.key,s=a.state;if(o)if(n.pushState({key:i,state:s},null,t),w)window.location.href=t;else{var c=R.indexOf($.location.key),l=R.slice(0,c+1);l.push(a.key),R=l,C({action:r,location:a})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",a=f(e,t,j(),$.location);P.confirmTransitionTo(a,r,x,(function(e){if(e){var t=D(a),i=a.key,s=a.state;if(o)if(n.replaceState({key:i,state:s},null,t),w)window.location.replace(t);else{var c=R.indexOf($.location.key);-1!==c&&(R[c]=a.key),C({action:r,location:a})}else window.location.replace(t)}}))},go:F,goBack:function(){F(-1)},goForward:function(){F(1)},block:function(e){void 0===e&&(e=!1);var t=P.setPrompt(e);return z||(B(1),z=!0),function(){return z&&(z=!1,B(-1)),t()}},listen:function(e){var t=P.appendListener(e);return B(1),function(){B(-1),t()}}};return $}var _="hashchange",x={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+l(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:l,decodePath:c},slash:{encodePath:c,decodePath:c}};function S(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function k(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(S(window.location.href)+"#"+e)}function O(e){void 0===e&&(e={}),h||(0,s.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,a=void 0===o?v:o,i=n.hashType,l=void 0===i?"slash":i,g=e.basename?p(c(e.basename)):"",b=x[l],y=b.encodePath,w=b.decodePath;function O(){var e=w(k());return g&&(e=u(e,g)),f(e)}var j=m();function P(e){(0,r.A)(z,e),z.length=t.length,j.notifyListeners(z.location,z.action)}var C=!1,A=null;function T(){var e,t,n=k(),r=y(n);if(n!==r)E(r);else{var o=O(),i=z.location;if(!C&&(t=o,(e=i).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(A===d(o))return;A=null,function(e){if(C)C=!1,P();else{var t="POP";j.confirmTransitionTo(e,t,a,(function(n){n?P({action:t,location:e}):function(e){var t=z.location,n=R.lastIndexOf(d(t));-1===n&&(n=0);var r=R.lastIndexOf(d(e));-1===r&&(r=0);var o=n-r;o&&(C=!0,D(o))}(e)}))}}(o)}}var I=k(),N=y(I);I!==N&&E(N);var L=O(),R=[d(L)];function D(e){t.go(e)}var F=0;function M(e){1===(F+=e)&&1===e?window.addEventListener(_,T):0===F&&window.removeEventListener(_,T)}var B=!1;var z={length:t.length,action:"POP",location:L,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=S(window.location.href)),n+"#"+y(g+d(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);j.confirmTransitionTo(r,n,a,(function(e){if(e){var t=d(r),o=y(g+t);if(k()!==o){A=t,function(e){window.location.hash=e}(o);var a=R.lastIndexOf(d(z.location)),i=R.slice(0,a+1);i.push(t),R=i,P({action:n,location:r})}else P()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);j.confirmTransitionTo(r,n,a,(function(e){if(e){var t=d(r),o=y(g+t);k()!==o&&(A=t,E(o));var a=R.indexOf(d(z.location));-1!==a&&(R[a]=t),P({action:n,location:r})}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=j.setPrompt(e);return B||(M(1),B=!0),function(){return B&&(B=!1,M(-1)),t()}},listen:function(e){var t=j.appendListener(e);return M(1),function(){M(-1),t()}}};return z}function j(e,t,n){return Math.min(Math.max(e,t),n)}function P(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,a=void 0===o?["/"]:o,i=t.initialIndex,s=void 0===i?0:i,c=t.keyLength,l=void 0===c?6:c,u=m();function p(e){(0,r.A)(w,e),w.length=w.entries.length,u.notifyListeners(w.location,w.action)}function h(){return Math.random().toString(36).substr(2,l)}var v=j(s,0,a.length-1),g=a.map((function(e){return f(e,void 0,"string"==typeof e?h():e.key||h())})),b=d;function y(e){var t=j(w.index+e,0,w.entries.length-1),r=w.entries[t];u.confirmTransitionTo(r,"POP",n,(function(e){e?p({action:"POP",location:r,index:t}):p()}))}var w={length:g.length,action:"POP",location:g[v],index:v,entries:g,createHref:b,push:function(e,t){var r="PUSH",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),p({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),w.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,p({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return w}},4146:(e,t,n)=>{"use strict";var r=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function c(e){return r.isMemo(e)?i:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var l=Object.defineProperty,u=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,d=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var i=u(n);p&&(i=i.concat(p(n)));for(var s=c(t),h=c(n),v=0;v<i.length;++v){var g=i[v];if(!(a[g]||r&&r[g]||h&&h[g]||s&&s[g])){var b=d(n,g);try{l(t,g,b)}catch(y){}}}}return t}},20311:e=>{"use strict";e.exports=function(e,t,n,r,o,a,i,s){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,a,i,s],u=0;(c=new Error(t.replace(/%s/g,(function(){return l[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},689:function(e){e.exports=function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),r=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o=function(){function e(n){var r=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=o,this.iframesTimeout=a}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach((function(t){var n=e.filter((function(e){return e.contains(t)})).length>0;-1!==e.indexOf(t)||n||e.push(t)})),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var o=e.contentWindow;if(r=o.document,!o||!r)throw new Error("iframe inaccessible")}catch(a){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,o=!1,a=null,i=function i(){if(!o){o=!0,clearTimeout(a);try{r.isIframeBlank(e)||(e.removeEventListener("load",i),r.getIframeContents(e,t,n))}catch(s){n()}}};e.addEventListener("load",i),a=setTimeout(i,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(r){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,(function(){return!0}),(function(e){r++,n.waitForIframes(e.querySelector("html"),(function(){--r||t()}))}),(function(e){e||t()}))}},{key:"forEachIframe",value:function(t,n,r){var o=this,a=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},i=t.querySelectorAll("iframe"),s=i.length,c=0;i=Array.prototype.slice.call(i);var l=function(){--s<=0&&a(c)};s||l(),i.forEach((function(t){e.matches(t,o.exclude)?l():o.onIframeReady(t,(function(e){n(t)&&(c++,r(e)),l()}),l)}))}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:(null===t||e.nextNode())&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var o=!1,a=!1;return r.forEach((function(e,t){e.val===n&&(o=t,a=e.handled)})),this.compareNodeIframe(e,t,n)?(!1!==o||a?!1===o||a||(r[o].handled=!0):r.push({val:n,handled:!0}),!0):(!1===o&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var o=this;e.forEach((function(e){e.handled||o.getIframeContents(e.val,(function(e){o.createInstanceOnIframe(e).forEachNode(t,n,r)}))}))}},{key:"iterateThroughNodes",value:function(e,t,n,r,o){for(var a=this,i=this.createIterator(t,e,r),s=[],c=[],l=void 0,u=void 0,p=function(){var e=a.getIteratorNode(i);return u=e.prevNode,l=e.node};p();)this.iframes&&this.forEachIframe(t,(function(e){return a.checkIframeFilter(l,u,e,s)}),(function(t){a.createInstanceOnIframe(t).forEachNode(e,(function(e){return c.push(e)}),r)})),c.push(l);c.forEach((function(e){n(e)})),this.iframes&&this.handleOpenIframes(s,e,n,r),o()}},{key:"forEachNode",value:function(e,t,n){var r=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=this.getContexts(),i=a.length;i||o(),a.forEach((function(a){var s=function(){r.iterateThroughNodes(e,a,t,n,(function(){--i<=0&&o()}))};r.iframes?r.waitForIframes(a,s):s()}))}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var o=!1;return n.every((function(t){return!r.call(e,t)||(o=!0,!1)})),o}return!1}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createRegExp",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e)}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var o in t)if(t.hasOwnProperty(o)){var a=t[o],i="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(a):this.escapeStr(a);""!==i&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(i)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynomyms(i)+"|"+this.processSynomyms(s)+")"+r))}return e}},{key:"processSynomyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,(function(e){return"\\"===e.charAt(0)?"?":"\x01"}))).replace(/(?:\\)*\*/g,(function(e){return"\\"===e.charAt(0)?"*":"\x02"}))}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,(function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"}))}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105","A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010d","C\xc7\u0106\u010c","d\u0111\u010f","D\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119","E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012b","I\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142","L\u0141","n\xf1\u0148\u0144","N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014d","O\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159","R\u0158","s\u0161\u015b\u0219\u015f","S\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163","T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016b","U\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xff","Y\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017a","Z\u017d\u017b\u0179"]:["a\xe0\xe1\u1ea3\xe3\u1ea1\u0103\u1eb1\u1eaf\u1eb3\u1eb5\u1eb7\xe2\u1ea7\u1ea5\u1ea9\u1eab\u1ead\xe4\xe5\u0101\u0105A\xc0\xc1\u1ea2\xc3\u1ea0\u0102\u1eb0\u1eae\u1eb2\u1eb4\u1eb6\xc2\u1ea6\u1ea4\u1ea8\u1eaa\u1eac\xc4\xc5\u0100\u0104","c\xe7\u0107\u010dC\xc7\u0106\u010c","d\u0111\u010fD\u0110\u010e","e\xe8\xe9\u1ebb\u1ebd\u1eb9\xea\u1ec1\u1ebf\u1ec3\u1ec5\u1ec7\xeb\u011b\u0113\u0119E\xc8\xc9\u1eba\u1ebc\u1eb8\xca\u1ec0\u1ebe\u1ec2\u1ec4\u1ec6\xcb\u011a\u0112\u0118","i\xec\xed\u1ec9\u0129\u1ecb\xee\xef\u012bI\xcc\xcd\u1ec8\u0128\u1eca\xce\xcf\u012a","l\u0142L\u0141","n\xf1\u0148\u0144N\xd1\u0147\u0143","o\xf2\xf3\u1ecf\xf5\u1ecd\xf4\u1ed3\u1ed1\u1ed5\u1ed7\u1ed9\u01a1\u1edf\u1ee1\u1edb\u1edd\u1ee3\xf6\xf8\u014dO\xd2\xd3\u1ece\xd5\u1ecc\xd4\u1ed2\u1ed0\u1ed4\u1ed6\u1ed8\u01a0\u1ede\u1ee0\u1eda\u1edc\u1ee2\xd6\xd8\u014c","r\u0159R\u0158","s\u0161\u015b\u0219\u015fS\u0160\u015a\u0218\u015e","t\u0165\u021b\u0163T\u0164\u021a\u0162","u\xf9\xfa\u1ee7\u0169\u1ee5\u01b0\u1eeb\u1ee9\u1eed\u1eef\u1ef1\xfb\xfc\u016f\u016bU\xd9\xda\u1ee6\u0168\u1ee4\u01af\u1eea\u1ee8\u1eec\u1eee\u1ef0\xdb\xdc\u016e\u016a","y\xfd\u1ef3\u1ef7\u1ef9\u1ef5\xffY\xdd\u1ef2\u1ef6\u1ef8\u1ef4\u0178","z\u017e\u017c\u017aZ\u017d\u017b\u0179"],r=[];return e.split("").forEach((function(o){n.every((function(n){if(-1!==n.indexOf(o)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0}))})),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n="!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\xa1\xbf",r=this.opt.accuracy,o="string"==typeof r?r:r.value,a="string"==typeof r?[]:r.limiters,i="";switch(a.forEach((function(e){i+="|"+t.escapeStr(e)})),o){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr(n)))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach((function(e){t.opt.separateWordSearch?e.split(" ").forEach((function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)})):e.trim()&&-1===n.indexOf(e)&&n.push(e)})),{keywords:n.sort((function(e,t){return t.length-e.length})),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort((function(e,t){return e.start-t.start})).forEach((function(e){var o=t.callNoMatchOnInvalidRanges(e,r),a=o.start,i=o.end;o.valid&&(e.start=a,e.length=i-a,n.push(e),r=i)})),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,o=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?o=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:o}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,o=!0,a=n.length,i=t-a,s=parseInt(e.start,10)-i;return(r=(s=s>a?a:s)+parseInt(e.length,10))>a&&(r=a,this.log("End range automatically set to the max value of "+a)),s<0||r-s<0||s>a||r>a?(o=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(o=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:o}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,(function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})}),(function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}),(function(){e({value:n,nodes:r})}))}},{key:"matchesExclude",value:function(e){return o.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",o=e.splitText(t),a=o.splitText(n-t),i=document.createElement(r);return i.setAttribute("data-markjs","true"),this.opt.className&&i.setAttribute("class",this.opt.className),i.textContent=o.textContent,o.parentNode.replaceChild(i,o),a}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,o){var a=this;e.nodes.every((function(i,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(i.node))return!1;var l=t-i.start,u=(n>i.end?i.end:n)-i.start,p=e.value.substr(0,i.start),d=e.value.substr(u+i.start);if(i.node=a.wrapRangeInTextNode(i.node,l,u),e.value=p+d,e.nodes.forEach((function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=u),e.nodes[n].end-=u)})),n-=u,o(i.node.previousSibling,i.start),!(n>i.end))return!1;t=i.end}return!0}))}},{key:"wrapMatches",value:function(e,t,n,r,o){var a=this,i=0===t?0:t+1;this.getTextNodes((function(t){t.nodes.forEach((function(t){t=t.node;for(var o=void 0;null!==(o=e.exec(t.textContent))&&""!==o[i];)if(n(o[i],t)){var s=o.index;if(0!==i)for(var c=1;c<i;c++)s+=o[c].length;t=a.wrapRangeInTextNode(t,s,s+o[i].length),r(t.previousSibling),e.lastIndex=0}})),o()}))}},{key:"wrapMatchesAcrossElements",value:function(e,t,n,r,o){var a=this,i=0===t?0:t+1;this.getTextNodes((function(t){for(var s=void 0;null!==(s=e.exec(t.value))&&""!==s[i];){var c=s.index;if(0!==i)for(var l=1;l<i;l++)c+=s[l].length;var u=c+s[i].length;a.wrapRangeInMappedTextNode(t,c,u,(function(e){return n(s[i],e)}),(function(t,n){e.lastIndex=n,r(t)}))}o()}))}},{key:"wrapRangeFromIndex",value:function(e,t,n,r){var o=this;this.getTextNodes((function(a){var i=a.value.length;e.forEach((function(e,r){var s=o.checkWhitespaceRanges(e,i,a.value),c=s.start,l=s.end;s.valid&&o.wrapRangeInMappedTextNode(a,c,l,(function(n){return t(n,e,a.value.substring(c,l),r)}),(function(t){n(t,e)}))})),r()}))}},{key:"unwrapMatches",value:function(e){for(var t=e.parentNode,n=document.createDocumentFragment();e.firstChild;)n.appendChild(e.removeChild(e.firstChild));t.replaceChild(n,e),this.ie?this.normalizeTextNode(t):t.normalize()}},{key:"normalizeTextNode",value:function(e){if(e){if(3===e.nodeType)for(;e.nextSibling&&3===e.nextSibling.nodeType;)e.nodeValue+=e.nextSibling.nodeValue,e.parentNode.removeChild(e.nextSibling);else this.normalizeTextNode(e.firstChild);this.normalizeTextNode(e.nextSibling)}}},{key:"markRegExp",value:function(e,t){var n=this;this.opt=t,this.log('Searching with expression "'+e+'"');var r=0,o="wrapMatches",a=function(e){r++,n.opt.each(e)};this.opt.acrossElements&&(o="wrapMatchesAcrossElements"),this[o](e,this.opt.ignoreGroups,(function(e,t){return n.opt.filter(t,e,r)}),a,(function(){0===r&&n.opt.noMatch(e),n.opt.done(r)}))}},{key:"mark",value:function(e,t){var n=this;this.opt=t;var r=0,o="wrapMatches",a=this.getSeparatedKeywords("string"==typeof e?[e]:e),i=a.keywords,s=a.length,c=this.opt.caseSensitive?"":"i",l=function e(t){var a=new RegExp(n.createRegExp(t),"gm"+c),l=0;n.log('Searching with expression "'+a+'"'),n[o](a,1,(function(e,o){return n.opt.filter(o,t,r,l)}),(function(e){l++,r++,n.opt.each(e)}),(function(){0===l&&n.opt.noMatch(t),i[s-1]===t?n.opt.done(r):e(i[i.indexOf(t)+1])}))};this.opt.acrossElements&&(o="wrapMatchesAcrossElements"),0===s?this.opt.done(r):l(i[0])}},{key:"markRanges",value:function(e,t){var n=this;this.opt=t;var r=0,o=this.checkRanges(e);o&&o.length?(this.log("Starting to mark with the following ranges: "+JSON.stringify(o)),this.wrapRangeFromIndex(o,(function(e,t,r,o){return n.opt.filter(e,t,r,o)}),(function(e,t){r++,n.opt.each(e,t)}),(function(){n.opt.done(r)}))):this.opt.done(r)}},{key:"unmark",value:function(e){var t=this;this.opt=e;var n=this.opt.element?this.opt.element:"*";n+="[data-markjs]",this.opt.className&&(n+="."+this.opt.className),this.log('Removal selector "'+n+'"'),this.iterator.forEachNode(NodeFilter.SHOW_ELEMENT,(function(e){t.unwrapMatches(e)}),(function(e){var r=o.matches(e,n),a=t.matchesExclude(e);return!r||a?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT}),this.opt.done)}},{key:"opt",set:function(e){this._opt=r({},{element:"",className:"",exclude:[],iframes:!1,iframesTimeout:5e3,separateWordSearch:!0,diacritics:!0,synonyms:{},accuracy:"partially",acrossElements:!1,caseSensitive:!1,ignoreJoiners:!1,ignoreGroups:0,ignorePunctuation:[],wildcards:"disabled",each:function(){},noMatch:function(){},filter:function(){return!0},done:function(){},debug:!1,log:window.console},e)},get:function(){return this._opt}},{key:"iterator",get:function(){return new o(this.ctx,this.opt.iframes,this.opt.exclude,this.opt.iframesTimeout)}}]),a}();function i(e){var t=this,n=new a(e);return this.mark=function(e,r){return n.mark(e,r),t},this.markRegExp=function(e,r){return n.markRegExp(e,r),t},this.markRanges=function(e,r){return n.markRanges(e,r),t},this.unmark=function(e){return n.unmark(e),t},this}return i}()},85300:(e,t,n)=>{"use strict";n.r(t)},58252:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),l=a.querySelector(r.barSelector),u=r.speed,p=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,i(e,u,p)),1===e?(c(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){c(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),l=document.querySelector(r.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:d(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=d(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function p(e,t){var n,r=d(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function d(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},57022:()=>{!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var o=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],a=r.variable[1].inside,i=0;i<o.length;i++)a[o[i]]=e.languages.bash[o[i]];e.languages.sh=e.languages.bash,e.languages.shell=e.languages.bash}(Prism)},47839:()=>{!function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],o=[];/^\w+$/.test(n)||o.push(/\w+/.exec(n)[0]),"diff"===n&&o.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:o,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(Prism)},72514:()=>{Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,s=i.length;-1!==n.code.indexOf(o=t(r,s));)++s;return i[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(s){for(var c=0;c<s.length&&!(o>=a.length);c++){var l=s[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var u=a[o],p=n.tokenStack[u],d="string"==typeof l?l:l.content,f=t(r,u),m=d.indexOf(f);if(m>-1){++o;var h=d.substring(0,m),v=new e.Token(r,e.tokenize(p,n.grammar),"language-"+r,p),g=d.substring(m+f.length),b=[];h&&b.push.apply(b,i([h])),b.push(v),g&&b.push.apply(b,i([g])),"string"==typeof l?s.splice.apply(s,[c,1].concat(b)):l.content=b}}else l.content&&i(l.content)}return s}(n.tokens)}}}})}(Prism)},60061:()=>{!function(e){var t=[/"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/.source,/'[^']*'/.source,/\$'(?:[^'\\]|\\[\s\S])*'/.source,/<<-?\s*(["']?)(\w+)\1\s[\s\S]*?[\r\n]\2/.source].join("|");e.languages["shell-session"]={command:{pattern:RegExp(/^/.source+"(?:"+/[^\s@:$#%*!/\\]+@[^\r\n@:$#%*!/\\]+(?::[^\0-\x1F$#%*?"<>:;|]+)?/.source+"|"+/[/~.][^\0-\x1F$#%*?"<>@:;|]*/.source+")?"+/[$#%](?=\s)/.source+/(?:[^\\\r\n \t'"<$]|[ \t](?:(?!#)|#.*$)|\\(?:[^\r]|\r\n?)|\$(?!')|<(?!<)|<<str>>)+/.source.replace(/<<str>>/g,(function(){return t})),"m"),greedy:!0,inside:{info:{pattern:/^[^#$%]+/,alias:"punctuation",inside:{user:/^[^\s@:$#%*!/\\]+@[^\r\n@:$#%*!/\\]+/,punctuation:/:/,path:/[\s\S]+/}},bash:{pattern:/(^[$#%]\s*)\S[\s\S]*/,lookbehind:!0,alias:"language-bash",inside:e.languages.bash},"shell-symbol":{pattern:/^[$#%]/,alias:"important"}}},output:/.(?:.*(?:[\r\n]|.$))*/},e.languages["sh-session"]=e.languages.shellsession=e.languages["shell-session"]}(Prism)},97553:(e,t,n)=>{var r={"./prism-bash":57022,"./prism-diff":47839,"./prism-json":72514,"./prism-shell-session":60061};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=97553},2694:(e,t,n)=>{"use strict";var r=n(6925);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},22551:(e,t,n)=>{"use strict";var r=n(96540),o=n(69982);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var i=new Set,s={};function c(e,t){l(e,t),l(e+"Capture",t)}function l(e,t){for(s[e]=t,e=0;e<t.length;e++)i.add(t[e])}var u=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=Object.prototype.hasOwnProperty,d=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},m={};function h(e,t,n,r,o,a,i){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=i}var v={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){v[e]=new h(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];v[t]=new h(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){v[e]=new h(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){v[e]=new h(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){v[e]=new h(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){v[e]=new h(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){v[e]=new h(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){v[e]=new h(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){v[e]=new h(e,5,!1,e.toLowerCase(),null,!1,!1)}));var g=/[\-:]([a-z])/g;function b(e){return e[1].toUpperCase()}function y(e,t,n,r){var o=v.hasOwnProperty(t)?v[t]:null;(null!==o?0!==o.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!p.call(m,e)||!p.call(f,e)&&(d.test(e)?m[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(g,b);v[t]=new h(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){v[e]=new h(e,1,!1,e.toLowerCase(),null,!1,!1)})),v.xlinkHref=new h("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){v[e]=new h(e,1,!1,e.toLowerCase(),null,!0,!0)}));var w=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,_=Symbol.for("react.element"),x=Symbol.for("react.portal"),S=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),O=Symbol.for("react.provider"),j=Symbol.for("react.context"),P=Symbol.for("react.forward_ref"),C=Symbol.for("react.suspense"),A=Symbol.for("react.suspense_list"),T=Symbol.for("react.memo"),I=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var N=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var L=Symbol.iterator;function R(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=L&&e[L]||e["@@iterator"])?e:null}var D,F=Object.assign;function M(e){if(void 0===D)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);D=t&&t[1]||""}return"\n"+D+e}var B=!1;function z(e,t){if(!e||B)return"";B=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var r=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){r=l}e.call(t.prototype)}else{try{throw Error()}catch(l){r=l}e()}}catch(l){if(l&&r&&"string"==typeof l.stack){for(var o=l.stack.split("\n"),a=r.stack.split("\n"),i=o.length-1,s=a.length-1;1<=i&&0<=s&&o[i]!==a[s];)s--;for(;1<=i&&0<=s;i--,s--)if(o[i]!==a[s]){if(1!==i||1!==s)do{if(i--,0>--s||o[i]!==a[s]){var c="\n"+o[i].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=i&&0<=s);break}}}finally{B=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?M(e):""}function $(e){switch(e.tag){case 5:return M(e.type);case 16:return M("Lazy");case 13:return M("Suspense");case 19:return M("SuspenseList");case 0:case 2:case 15:return e=z(e.type,!1);case 11:return e=z(e.type.render,!1);case 1:return e=z(e.type,!0);default:return""}}function U(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case S:return"Fragment";case x:return"Portal";case E:return"Profiler";case k:return"StrictMode";case C:return"Suspense";case A:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case j:return(e.displayName||"Context")+".Consumer";case O:return(e._context.displayName||"Context")+".Provider";case P:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case T:return null!==(t=e.displayName||null)?t:U(e.type)||"Memo";case I:t=e._payload,e=e._init;try{return U(e(t))}catch(n){}}return null}function H(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return U(t);case 8:return t===k?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function V(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function W(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function Q(e){e._valueTracker||(e._valueTracker=function(e){var t=W(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,a=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,a.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function q(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=W(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function G(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function K(e,t){var n=t.checked;return F({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Y(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=V(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Z(e,t){null!=(t=t.checked)&&y(e,"checked",t,!1)}function X(e,t){Z(e,t);var n=V(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,V(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&G(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+V(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function re(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(a(91));return F({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(a(92));if(te(n)){if(1<n.length)throw Error(a(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:V(n)}}function ae(e,t){var n=V(t.value),r=V(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ie(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function se(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ce(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?se(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var le,ue,pe=(ue=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((le=le||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=le.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return ue(e,t)}))}:ue);function de(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},me=["Webkit","ms","Moz","O"];function he(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function ve(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=he(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(fe).forEach((function(e){me.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]}))}));var ge=F({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function be(e,t){if(t){if(ge[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(a(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(a(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(a(62))}}function ye(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var we=null;function _e(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var xe=null,Se=null,ke=null;function Ee(e){if(e=wo(e)){if("function"!=typeof xe)throw Error(a(280));var t=e.stateNode;t&&(t=xo(t),xe(e.stateNode,e.type,t))}}function Oe(e){Se?ke?ke.push(e):ke=[e]:Se=e}function je(){if(Se){var e=Se,t=ke;if(ke=Se=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Pe(e,t){return e(t)}function Ce(){}var Ae=!1;function Te(e,t,n){if(Ae)return e(t,n);Ae=!0;try{return Pe(e,t,n)}finally{Ae=!1,(null!==Se||null!==ke)&&(Ce(),je())}}function Ie(e,t){var n=e.stateNode;if(null===n)return null;var r=xo(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(a(231,t,typeof n));return n}var Ne=!1;if(u)try{var Le={};Object.defineProperty(Le,"passive",{get:function(){Ne=!0}}),window.addEventListener("test",Le,Le),window.removeEventListener("test",Le,Le)}catch(ue){Ne=!1}function Re(e,t,n,r,o,a,i,s,c){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(u){this.onError(u)}}var De=!1,Fe=null,Me=!1,Be=null,ze={onError:function(e){De=!0,Fe=e}};function $e(e,t,n,r,o,a,i,s,c){De=!1,Fe=null,Re.apply(ze,arguments)}function Ue(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function He(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Ve(e){if(Ue(e)!==e)throw Error(a(188))}function We(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=Ue(e)))throw Error(a(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var i=o.alternate;if(null===i){if(null!==(r=o.return)){n=r;continue}break}if(o.child===i.child){for(i=o.child;i;){if(i===n)return Ve(o),e;if(i===r)return Ve(o),t;i=i.sibling}throw Error(a(188))}if(n.return!==r.return)n=o,r=i;else{for(var s=!1,c=o.child;c;){if(c===n){s=!0,n=o,r=i;break}if(c===r){s=!0,r=o,n=i;break}c=c.sibling}if(!s){for(c=i.child;c;){if(c===n){s=!0,n=i,r=o;break}if(c===r){s=!0,r=i,n=o;break}c=c.sibling}if(!s)throw Error(a(189))}}if(n.alternate!==r)throw Error(a(190))}if(3!==n.tag)throw Error(a(188));return n.stateNode.current===n?e:t}(e))?Qe(e):null}function Qe(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=Qe(e);if(null!==t)return t;e=e.sibling}return null}var qe=o.unstable_scheduleCallback,Ge=o.unstable_cancelCallback,Ke=o.unstable_shouldYield,Ye=o.unstable_requestPaint,Ze=o.unstable_now,Xe=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,rt=o.unstable_IdlePriority,ot=null,at=null;var it=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(st(e)/ct|0)|0},st=Math.log,ct=Math.LN2;var lt=64,ut=4194304;function pt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function dt(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,a=e.pingedLanes,i=268435455&n;if(0!==i){var s=i&~o;0!==s?r=pt(s):0!==(a&=i)&&(r=pt(a))}else 0!==(i=n&~o)?r=pt(i):0!==a&&(r=pt(a));if(0===r)return 0;if(0!==t&&t!==r&&!(t&o)&&((o=r&-r)>=(a=t&-t)||16===o&&4194240&a))return t;if(4&r&&(r|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-it(t)),r|=e[n],t&=~o;return r}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function mt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function ht(){var e=lt;return!(4194240&(lt<<=1))&&(lt=64),e}function vt(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function gt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-it(t)]=n}function bt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-it(n),o=1<<r;o&t|e[r]&t&&(e[r]|=t),n&=~o}}var yt=0;function wt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var _t,xt,St,kt,Et,Ot=!1,jt=[],Pt=null,Ct=null,At=null,Tt=new Map,It=new Map,Nt=[],Lt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Rt(e,t){switch(e){case"focusin":case"focusout":Pt=null;break;case"dragenter":case"dragleave":Ct=null;break;case"mouseover":case"mouseout":At=null;break;case"pointerover":case"pointerout":Tt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":It.delete(t.pointerId)}}function Dt(e,t,n,r,o,a){return null===e||e.nativeEvent!==a?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:a,targetContainers:[o]},null!==t&&(null!==(t=wo(t))&&xt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Ft(e){var t=yo(e.target);if(null!==t){var n=Ue(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=He(n)))return e.blockedOn=t,void Et(e.priority,(function(){St(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Mt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Kt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=wo(n))&&xt(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);we=r,n.target.dispatchEvent(r),we=null,t.shift()}return!0}function Bt(e,t,n){Mt(e)&&n.delete(t)}function zt(){Ot=!1,null!==Pt&&Mt(Pt)&&(Pt=null),null!==Ct&&Mt(Ct)&&(Ct=null),null!==At&&Mt(At)&&(At=null),Tt.forEach(Bt),It.forEach(Bt)}function $t(e,t){e.blockedOn===t&&(e.blockedOn=null,Ot||(Ot=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,zt)))}function Ut(e){function t(t){return $t(t,e)}if(0<jt.length){$t(jt[0],e);for(var n=1;n<jt.length;n++){var r=jt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==Pt&&$t(Pt,e),null!==Ct&&$t(Ct,e),null!==At&&$t(At,e),Tt.forEach(t),It.forEach(t),n=0;n<Nt.length;n++)(r=Nt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<Nt.length&&null===(n=Nt[0]).blockedOn;)Ft(n),null===n.blockedOn&&Nt.shift()}var Ht=w.ReactCurrentBatchConfig,Vt=!0;function Wt(e,t,n,r){var o=yt,a=Ht.transition;Ht.transition=null;try{yt=1,qt(e,t,n,r)}finally{yt=o,Ht.transition=a}}function Qt(e,t,n,r){var o=yt,a=Ht.transition;Ht.transition=null;try{yt=4,qt(e,t,n,r)}finally{yt=o,Ht.transition=a}}function qt(e,t,n,r){if(Vt){var o=Kt(e,t,n,r);if(null===o)Vr(e,t,r,Gt,n),Rt(e,r);else if(function(e,t,n,r,o){switch(t){case"focusin":return Pt=Dt(Pt,e,t,n,r,o),!0;case"dragenter":return Ct=Dt(Ct,e,t,n,r,o),!0;case"mouseover":return At=Dt(At,e,t,n,r,o),!0;case"pointerover":var a=o.pointerId;return Tt.set(a,Dt(Tt.get(a)||null,e,t,n,r,o)),!0;case"gotpointercapture":return a=o.pointerId,It.set(a,Dt(It.get(a)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r))r.stopPropagation();else if(Rt(e,r),4&t&&-1<Lt.indexOf(e)){for(;null!==o;){var a=wo(o);if(null!==a&&_t(a),null===(a=Kt(e,t,n,r))&&Vr(e,t,r,Gt,n),a===o)break;o=a}null!==o&&r.stopPropagation()}else Vr(e,t,r,null,n)}}var Gt=null;function Kt(e,t,n,r){if(Gt=null,null!==(e=yo(e=_e(r))))if(null===(t=Ue(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=He(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Gt=e,null}function Yt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Xe()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case rt:return 536870912;default:return 16}default:return 16}}var Zt=null,Xt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Xt,r=n.length,o="value"in Zt?Zt.value:Zt.textContent,a=o.length;for(e=0;e<r&&n[e]===o[e];e++);var i=r-e;for(t=1;t<=i&&n[r-t]===o[a-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function rn(){return!1}function on(e){function t(t,n,r,o,a){for(var i in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=a,this.currentTarget=null,e)e.hasOwnProperty(i)&&(t=e[i],this[i]=t?t(o):o[i]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:rn,this.isPropagationStopped=rn,this}return F(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var an,sn,cn,ln={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},un=on(ln),pn=F({},ln,{view:0,detail:0}),dn=on(pn),fn=F({},pn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==cn&&(cn&&"mousemove"===e.type?(an=e.screenX-cn.screenX,sn=e.screenY-cn.screenY):sn=an=0,cn=e),an)},movementY:function(e){return"movementY"in e?e.movementY:sn}}),mn=on(fn),hn=on(F({},fn,{dataTransfer:0})),vn=on(F({},pn,{relatedTarget:0})),gn=on(F({},ln,{animationName:0,elapsedTime:0,pseudoElement:0})),bn=F({},ln,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),yn=on(bn),wn=on(F({},ln,{data:0})),_n={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},xn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},Sn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function kn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=Sn[e])&&!!t[e]}function En(){return kn}var On=F({},pn,{key:function(e){if(e.key){var t=_n[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?xn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),jn=on(On),Pn=on(F({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Cn=on(F({},pn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),An=on(F({},ln,{propertyName:0,elapsedTime:0,pseudoElement:0})),Tn=F({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),In=on(Tn),Nn=[9,13,27,32],Ln=u&&"CompositionEvent"in window,Rn=null;u&&"documentMode"in document&&(Rn=document.documentMode);var Dn=u&&"TextEvent"in window&&!Rn,Fn=u&&(!Ln||Rn&&8<Rn&&11>=Rn),Mn=String.fromCharCode(32),Bn=!1;function zn(e,t){switch(e){case"keyup":return-1!==Nn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function $n(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var Un=!1;var Hn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Vn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Hn[e.type]:"textarea"===t}function Wn(e,t,n,r){Oe(r),0<(t=Qr(t,"onChange")).length&&(n=new un("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Qn=null,qn=null;function Gn(e){Mr(e,0)}function Kn(e){if(q(_o(e)))return e}function Yn(e,t){if("change"===e)return t}var Zn=!1;if(u){var Xn;if(u){var Jn="oninput"in document;if(!Jn){var er=document.createElement("div");er.setAttribute("oninput","return;"),Jn="function"==typeof er.oninput}Xn=Jn}else Xn=!1;Zn=Xn&&(!document.documentMode||9<document.documentMode)}function tr(){Qn&&(Qn.detachEvent("onpropertychange",nr),qn=Qn=null)}function nr(e){if("value"===e.propertyName&&Kn(qn)){var t=[];Wn(t,qn,e,_e(e)),Te(Gn,t)}}function rr(e,t,n){"focusin"===e?(tr(),qn=n,(Qn=t).attachEvent("onpropertychange",nr)):"focusout"===e&&tr()}function or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(qn)}function ar(e,t){if("click"===e)return Kn(t)}function ir(e,t){if("input"===e||"change"===e)return Kn(t)}var sr="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function cr(e,t){if(sr(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var o=n[r];if(!p.call(t,o)||!sr(e[o],t[o]))return!1}return!0}function lr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function ur(e,t){var n,r=lr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=lr(r)}}function pr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?pr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function dr(){for(var e=window,t=G();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=G((e=t.contentWindow).document)}return t}function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function mr(e){var t=dr(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&pr(n.ownerDocument.documentElement,n)){if(null!==r&&fr(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,a=Math.min(r.start,o);r=void 0===r.end?a:Math.min(r.end,o),!e.extend&&a>r&&(o=r,r=a,a=o),o=ur(n,a);var i=ur(n,r);o&&i&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==i.node||e.focusOffset!==i.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),a>r?(e.addRange(t),e.extend(i.node,i.offset)):(t.setEnd(i.node,i.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var hr=u&&"documentMode"in document&&11>=document.documentMode,vr=null,gr=null,br=null,yr=!1;function wr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;yr||null==vr||vr!==G(r)||("selectionStart"in(r=vr)&&fr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},br&&cr(br,r)||(br=r,0<(r=Qr(gr,"onSelect")).length&&(t=new un("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=vr)))}function _r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var xr={animationend:_r("Animation","AnimationEnd"),animationiteration:_r("Animation","AnimationIteration"),animationstart:_r("Animation","AnimationStart"),transitionend:_r("Transition","TransitionEnd")},Sr={},kr={};function Er(e){if(Sr[e])return Sr[e];if(!xr[e])return e;var t,n=xr[e];for(t in n)if(n.hasOwnProperty(t)&&t in kr)return Sr[e]=n[t];return e}u&&(kr=document.createElement("div").style,"AnimationEvent"in window||(delete xr.animationend.animation,delete xr.animationiteration.animation,delete xr.animationstart.animation),"TransitionEvent"in window||delete xr.transitionend.transition);var Or=Er("animationend"),jr=Er("animationiteration"),Pr=Er("animationstart"),Cr=Er("transitionend"),Ar=new Map,Tr="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Ir(e,t){Ar.set(e,t),c(t,[e])}for(var Nr=0;Nr<Tr.length;Nr++){var Lr=Tr[Nr];Ir(Lr.toLowerCase(),"on"+(Lr[0].toUpperCase()+Lr.slice(1)))}Ir(Or,"onAnimationEnd"),Ir(jr,"onAnimationIteration"),Ir(Pr,"onAnimationStart"),Ir("dblclick","onDoubleClick"),Ir("focusin","onFocus"),Ir("focusout","onBlur"),Ir(Cr,"onTransitionEnd"),l("onMouseEnter",["mouseout","mouseover"]),l("onMouseLeave",["mouseout","mouseover"]),l("onPointerEnter",["pointerout","pointerover"]),l("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Rr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Dr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Rr));function Fr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,i,s,c,l){if($e.apply(this,arguments),De){if(!De)throw Error(a(198));var u=Fe;De=!1,Fe=null,Me||(Me=!0,Be=u)}}(r,t,void 0,e),e.currentTarget=null}function Mr(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var a=void 0;if(t)for(var i=r.length-1;0<=i;i--){var s=r[i],c=s.instance,l=s.currentTarget;if(s=s.listener,c!==a&&o.isPropagationStopped())break e;Fr(o,s,l),a=c}else for(i=0;i<r.length;i++){if(c=(s=r[i]).instance,l=s.currentTarget,s=s.listener,c!==a&&o.isPropagationStopped())break e;Fr(o,s,l),a=c}}}if(Me)throw e=Be,Me=!1,Be=null,e}function Br(e,t){var n=t[vo];void 0===n&&(n=t[vo]=new Set);var r=e+"__bubble";n.has(r)||(Hr(t,e,2,!1),n.add(r))}function zr(e,t,n){var r=0;t&&(r|=4),Hr(n,e,r,t)}var $r="_reactListening"+Math.random().toString(36).slice(2);function Ur(e){if(!e[$r]){e[$r]=!0,i.forEach((function(t){"selectionchange"!==t&&(Dr.has(t)||zr(t,!1,e),zr(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[$r]||(t[$r]=!0,zr("selectionchange",!1,t))}}function Hr(e,t,n,r){switch(Yt(t)){case 1:var o=Wt;break;case 4:o=Qt;break;default:o=qt}n=o.bind(null,t,n,e),o=void 0,!Ne||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Vr(e,t,n,r,o){var a=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var i=r.tag;if(3===i||4===i){var s=r.stateNode.containerInfo;if(s===o||8===s.nodeType&&s.parentNode===o)break;if(4===i)for(i=r.return;null!==i;){var c=i.tag;if((3===c||4===c)&&((c=i.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;i=i.return}for(;null!==s;){if(null===(i=yo(s)))return;if(5===(c=i.tag)||6===c){r=a=i;continue e}s=s.parentNode}}r=r.return}Te((function(){var r=a,o=_e(n),i=[];e:{var s=Ar.get(e);if(void 0!==s){var c=un,l=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":c=jn;break;case"focusin":l="focus",c=vn;break;case"focusout":l="blur",c=vn;break;case"beforeblur":case"afterblur":c=vn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=mn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=hn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=Cn;break;case Or:case jr:case Pr:c=gn;break;case Cr:c=An;break;case"scroll":c=dn;break;case"wheel":c=In;break;case"copy":case"cut":case"paste":c=yn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=Pn}var u=!!(4&t),p=!u&&"scroll"===e,d=u?null!==s?s+"Capture":null:s;u=[];for(var f,m=r;null!==m;){var h=(f=m).stateNode;if(5===f.tag&&null!==h&&(f=h,null!==d&&(null!=(h=Ie(m,d))&&u.push(Wr(m,h,f)))),p)break;m=m.return}0<u.length&&(s=new c(s,l,null,n,o),i.push({event:s,listeners:u}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(s="mouseover"===e||"pointerover"===e)||n===we||!(l=n.relatedTarget||n.fromElement)||!yo(l)&&!l[ho])&&(c||s)&&(s=o.window===o?o:(s=o.ownerDocument)?s.defaultView||s.parentWindow:window,c?(c=r,null!==(l=(l=n.relatedTarget||n.toElement)?yo(l):null)&&(l!==(p=Ue(l))||5!==l.tag&&6!==l.tag)&&(l=null)):(c=null,l=r),c!==l)){if(u=mn,h="onMouseLeave",d="onMouseEnter",m="mouse","pointerout"!==e&&"pointerover"!==e||(u=Pn,h="onPointerLeave",d="onPointerEnter",m="pointer"),p=null==c?s:_o(c),f=null==l?s:_o(l),(s=new u(h,m+"leave",c,n,o)).target=p,s.relatedTarget=f,h=null,yo(o)===r&&((u=new u(d,m+"enter",l,n,o)).target=f,u.relatedTarget=p,h=u),p=h,c&&l)e:{for(d=l,m=0,f=u=c;f;f=qr(f))m++;for(f=0,h=d;h;h=qr(h))f++;for(;0<m-f;)u=qr(u),m--;for(;0<f-m;)d=qr(d),f--;for(;m--;){if(u===d||null!==d&&u===d.alternate)break e;u=qr(u),d=qr(d)}u=null}else u=null;null!==c&&Gr(i,s,c,u,!1),null!==l&&null!==p&&Gr(i,p,l,u,!0)}if("select"===(c=(s=r?_o(r):window).nodeName&&s.nodeName.toLowerCase())||"input"===c&&"file"===s.type)var v=Yn;else if(Vn(s))if(Zn)v=ir;else{v=or;var g=rr}else(c=s.nodeName)&&"input"===c.toLowerCase()&&("checkbox"===s.type||"radio"===s.type)&&(v=ar);switch(v&&(v=v(e,r))?Wn(i,v,n,o):(g&&g(e,s,r),"focusout"===e&&(g=s._wrapperState)&&g.controlled&&"number"===s.type&&ee(s,"number",s.value)),g=r?_o(r):window,e){case"focusin":(Vn(g)||"true"===g.contentEditable)&&(vr=g,gr=r,br=null);break;case"focusout":br=gr=vr=null;break;case"mousedown":yr=!0;break;case"contextmenu":case"mouseup":case"dragend":yr=!1,wr(i,n,o);break;case"selectionchange":if(hr)break;case"keydown":case"keyup":wr(i,n,o)}var b;if(Ln)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else Un?zn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Fn&&"ko"!==n.locale&&(Un||"onCompositionStart"!==y?"onCompositionEnd"===y&&Un&&(b=en()):(Xt="value"in(Zt=o)?Zt.value:Zt.textContent,Un=!0)),0<(g=Qr(r,y)).length&&(y=new wn(y,e,null,n,o),i.push({event:y,listeners:g}),b?y.data=b:null!==(b=$n(n))&&(y.data=b))),(b=Dn?function(e,t){switch(e){case"compositionend":return $n(t);case"keypress":return 32!==t.which?null:(Bn=!0,Mn);case"textInput":return(e=t.data)===Mn&&Bn?null:e;default:return null}}(e,n):function(e,t){if(Un)return"compositionend"===e||!Ln&&zn(e,t)?(e=en(),Jt=Xt=Zt=null,Un=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Fn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Qr(r,"onBeforeInput")).length&&(o=new wn("onBeforeInput","beforeinput",null,n,o),i.push({event:o,listeners:r}),o.data=b))}Mr(i,t)}))}function Wr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Qr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,a=o.stateNode;5===o.tag&&null!==a&&(o=a,null!=(a=Ie(e,n))&&r.unshift(Wr(e,a,o)),null!=(a=Ie(e,t))&&r.push(Wr(e,a,o))),e=e.return}return r}function qr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Gr(e,t,n,r,o){for(var a=t._reactName,i=[];null!==n&&n!==r;){var s=n,c=s.alternate,l=s.stateNode;if(null!==c&&c===r)break;5===s.tag&&null!==l&&(s=l,o?null!=(c=Ie(n,a))&&i.unshift(Wr(n,c,s)):o||null!=(c=Ie(n,a))&&i.push(Wr(n,c,s))),n=n.return}0!==i.length&&e.push({event:t,listeners:i})}var Kr=/\r\n?/g,Yr=/\u0000|\uFFFD/g;function Zr(e){return("string"==typeof e?e:""+e).replace(Kr,"\n").replace(Yr,"")}function Xr(e,t,n){if(t=Zr(t),Zr(e)!==t&&n)throw Error(a(425))}function Jr(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ro="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,ao="function"==typeof Promise?Promise:void 0,io="function"==typeof queueMicrotask?queueMicrotask:void 0!==ao?function(e){return ao.resolve(null).then(e).catch(so)}:ro;function so(e){setTimeout((function(){throw e}))}function co(e,t){var n=t,r=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===r)return e.removeChild(o),void Ut(t);r--}else"$"!==n&&"$?"!==n&&"$!"!==n||r++;n=o}while(n);Ut(t)}function lo(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function uo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),fo="__reactFiber$"+po,mo="__reactProps$"+po,ho="__reactContainer$"+po,vo="__reactEvents$"+po,go="__reactListeners$"+po,bo="__reactHandles$"+po;function yo(e){var t=e[fo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[ho]||n[fo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=uo(e);null!==e;){if(n=e[fo])return n;e=uo(e)}return t}n=(e=n).parentNode}return null}function wo(e){return!(e=e[fo]||e[ho])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function _o(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function xo(e){return e[mo]||null}var So=[],ko=-1;function Eo(e){return{current:e}}function Oo(e){0>ko||(e.current=So[ko],So[ko]=null,ko--)}function jo(e,t){ko++,So[ko]=e.current,e.current=t}var Po={},Co=Eo(Po),Ao=Eo(!1),To=Po;function Io(e,t){var n=e.type.contextTypes;if(!n)return Po;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,a={};for(o in n)a[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=a),a}function No(e){return null!=(e=e.childContextTypes)}function Lo(){Oo(Ao),Oo(Co)}function Ro(e,t,n){if(Co.current!==Po)throw Error(a(168));jo(Co,t),jo(Ao,n)}function Do(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in t))throw Error(a(108,H(e)||"Unknown",o));return F({},n,r)}function Fo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Po,To=Co.current,jo(Co,e),jo(Ao,Ao.current),!0}function Mo(e,t,n){var r=e.stateNode;if(!r)throw Error(a(169));n?(e=Do(e,t,To),r.__reactInternalMemoizedMergedChildContext=e,Oo(Ao),Oo(Co),jo(Co,e)):Oo(Ao),jo(Ao,n)}var Bo=null,zo=!1,$o=!1;function Uo(e){null===Bo?Bo=[e]:Bo.push(e)}function Ho(){if(!$o&&null!==Bo){$o=!0;var e=0,t=yt;try{var n=Bo;for(yt=1;e<n.length;e++){var r=n[e];do{r=r(!0)}while(null!==r)}Bo=null,zo=!1}catch(o){throw null!==Bo&&(Bo=Bo.slice(e+1)),qe(Je,Ho),o}finally{yt=t,$o=!1}}return null}var Vo=[],Wo=0,Qo=null,qo=0,Go=[],Ko=0,Yo=null,Zo=1,Xo="";function Jo(e,t){Vo[Wo++]=qo,Vo[Wo++]=Qo,Qo=e,qo=t}function ea(e,t,n){Go[Ko++]=Zo,Go[Ko++]=Xo,Go[Ko++]=Yo,Yo=e;var r=Zo;e=Xo;var o=32-it(r)-1;r&=~(1<<o),n+=1;var a=32-it(t)+o;if(30<a){var i=o-o%5;a=(r&(1<<i)-1).toString(32),r>>=i,o-=i,Zo=1<<32-it(t)+o|n<<o|r,Xo=a+e}else Zo=1<<a|n<<o|r,Xo=e}function ta(e){null!==e.return&&(Jo(e,1),ea(e,1,0))}function na(e){for(;e===Qo;)Qo=Vo[--Wo],Vo[Wo]=null,qo=Vo[--Wo],Vo[Wo]=null;for(;e===Yo;)Yo=Go[--Ko],Go[Ko]=null,Xo=Go[--Ko],Go[Ko]=null,Zo=Go[--Ko],Go[Ko]=null}var ra=null,oa=null,aa=!1,ia=null;function sa(e,t){var n=Tl(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function ca(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,ra=e,oa=lo(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,ra=e,oa=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Yo?{id:Zo,overflow:Xo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Tl(18,null,null,0)).stateNode=t,n.return=e,e.child=n,ra=e,oa=null,!0);default:return!1}}function la(e){return!(!(1&e.mode)||128&e.flags)}function ua(e){if(aa){var t=oa;if(t){var n=t;if(!ca(e,t)){if(la(e))throw Error(a(418));t=lo(n.nextSibling);var r=ra;t&&ca(e,t)?sa(r,n):(e.flags=-4097&e.flags|2,aa=!1,ra=e)}}else{if(la(e))throw Error(a(418));e.flags=-4097&e.flags|2,aa=!1,ra=e}}}function pa(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;ra=e}function da(e){if(e!==ra)return!1;if(!aa)return pa(e),aa=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=oa)){if(la(e))throw fa(),Error(a(418));for(;t;)sa(e,t),t=lo(t.nextSibling)}if(pa(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){oa=lo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}oa=null}}else oa=ra?lo(e.stateNode.nextSibling):null;return!0}function fa(){for(var e=oa;e;)e=lo(e.nextSibling)}function ma(){oa=ra=null,aa=!1}function ha(e){null===ia?ia=[e]:ia.push(e)}var va=w.ReactCurrentBatchConfig;function ga(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(a(309));var r=n.stateNode}if(!r)throw Error(a(147,e));var o=r,i=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===i?t.ref:(t=function(e){var t=o.refs;null===e?delete t[i]:t[i]=e},t._stringRef=i,t)}if("string"!=typeof e)throw Error(a(284));if(!n._owner)throw Error(a(290,e))}return e}function ba(e,t){throw e=Object.prototype.toString.call(t),Error(a(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function ya(e){return(0,e._init)(e._payload)}function wa(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Nl(e,t)).index=0,e.sibling=null,e}function i(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=2,n):r:(t.flags|=2,n):(t.flags|=1048576,n)}function s(t){return e&&null===t.alternate&&(t.flags|=2),t}function c(e,t,n,r){return null===t||6!==t.tag?((t=Fl(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function l(e,t,n,r){var a=n.type;return a===S?p(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===a||"object"==typeof a&&null!==a&&a.$$typeof===I&&ya(a)===t.type)?((r=o(t,n.props)).ref=ga(e,t,n),r.return=e,r):((r=Ll(n.type,n.key,n.props,null,e.mode,r)).ref=ga(e,t,n),r.return=e,r)}function u(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Ml(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function p(e,t,n,r,a){return null===t||7!==t.tag?((t=Rl(n,e.mode,r,a)).return=e,t):((t=o(t,n)).return=e,t)}function d(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Fl(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case _:return(n=Ll(t.type,t.key,t.props,null,e.mode,n)).ref=ga(e,null,t),n.return=e,n;case x:return(t=Ml(t,e.mode,n)).return=e,t;case I:return d(e,(0,t._init)(t._payload),n)}if(te(t)||R(t))return(t=Rl(t,e.mode,n,null)).return=e,t;ba(e,t)}return null}function f(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:c(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case _:return n.key===o?l(e,t,n,r):null;case x:return n.key===o?u(e,t,n,r):null;case I:return f(e,t,(o=n._init)(n._payload),r)}if(te(n)||R(n))return null!==o?null:p(e,t,n,r,null);ba(e,n)}return null}function m(e,t,n,r,o){if("string"==typeof r&&""!==r||"number"==typeof r)return c(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case _:return l(t,e=e.get(null===r.key?n:r.key)||null,r,o);case x:return u(t,e=e.get(null===r.key?n:r.key)||null,r,o);case I:return m(e,t,n,(0,r._init)(r._payload),o)}if(te(r)||R(r))return p(t,e=e.get(n)||null,r,o,null);ba(t,r)}return null}function h(o,a,s,c){for(var l=null,u=null,p=a,h=a=0,v=null;null!==p&&h<s.length;h++){p.index>h?(v=p,p=null):v=p.sibling;var g=f(o,p,s[h],c);if(null===g){null===p&&(p=v);break}e&&p&&null===g.alternate&&t(o,p),a=i(g,a,h),null===u?l=g:u.sibling=g,u=g,p=v}if(h===s.length)return n(o,p),aa&&Jo(o,h),l;if(null===p){for(;h<s.length;h++)null!==(p=d(o,s[h],c))&&(a=i(p,a,h),null===u?l=p:u.sibling=p,u=p);return aa&&Jo(o,h),l}for(p=r(o,p);h<s.length;h++)null!==(v=m(p,o,h,s[h],c))&&(e&&null!==v.alternate&&p.delete(null===v.key?h:v.key),a=i(v,a,h),null===u?l=v:u.sibling=v,u=v);return e&&p.forEach((function(e){return t(o,e)})),aa&&Jo(o,h),l}function v(o,s,c,l){var u=R(c);if("function"!=typeof u)throw Error(a(150));if(null==(c=u.call(c)))throw Error(a(151));for(var p=u=null,h=s,v=s=0,g=null,b=c.next();null!==h&&!b.done;v++,b=c.next()){h.index>v?(g=h,h=null):g=h.sibling;var y=f(o,h,b.value,l);if(null===y){null===h&&(h=g);break}e&&h&&null===y.alternate&&t(o,h),s=i(y,s,v),null===p?u=y:p.sibling=y,p=y,h=g}if(b.done)return n(o,h),aa&&Jo(o,v),u;if(null===h){for(;!b.done;v++,b=c.next())null!==(b=d(o,b.value,l))&&(s=i(b,s,v),null===p?u=b:p.sibling=b,p=b);return aa&&Jo(o,v),u}for(h=r(o,h);!b.done;v++,b=c.next())null!==(b=m(h,o,v,b.value,l))&&(e&&null!==b.alternate&&h.delete(null===b.key?v:b.key),s=i(b,s,v),null===p?u=b:p.sibling=b,p=b);return e&&h.forEach((function(e){return t(o,e)})),aa&&Jo(o,v),u}return function e(r,a,i,c){if("object"==typeof i&&null!==i&&i.type===S&&null===i.key&&(i=i.props.children),"object"==typeof i&&null!==i){switch(i.$$typeof){case _:e:{for(var l=i.key,u=a;null!==u;){if(u.key===l){if((l=i.type)===S){if(7===u.tag){n(r,u.sibling),(a=o(u,i.props.children)).return=r,r=a;break e}}else if(u.elementType===l||"object"==typeof l&&null!==l&&l.$$typeof===I&&ya(l)===u.type){n(r,u.sibling),(a=o(u,i.props)).ref=ga(r,u,i),a.return=r,r=a;break e}n(r,u);break}t(r,u),u=u.sibling}i.type===S?((a=Rl(i.props.children,r.mode,c,i.key)).return=r,r=a):((c=Ll(i.type,i.key,i.props,null,r.mode,c)).ref=ga(r,a,i),c.return=r,r=c)}return s(r);case x:e:{for(u=i.key;null!==a;){if(a.key===u){if(4===a.tag&&a.stateNode.containerInfo===i.containerInfo&&a.stateNode.implementation===i.implementation){n(r,a.sibling),(a=o(a,i.children||[])).return=r,r=a;break e}n(r,a);break}t(r,a),a=a.sibling}(a=Ml(i,r.mode,c)).return=r,r=a}return s(r);case I:return e(r,a,(u=i._init)(i._payload),c)}if(te(i))return h(r,a,i,c);if(R(i))return v(r,a,i,c);ba(r,i)}return"string"==typeof i&&""!==i||"number"==typeof i?(i=""+i,null!==a&&6===a.tag?(n(r,a.sibling),(a=o(a,i)).return=r,r=a):(n(r,a),(a=Fl(i,r.mode,c)).return=r,r=a),s(r)):n(r,a)}}var _a=wa(!0),xa=wa(!1),Sa=Eo(null),ka=null,Ea=null,Oa=null;function ja(){Oa=Ea=ka=null}function Pa(e){var t=Sa.current;Oo(Sa),e._currentValue=t}function Ca(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Aa(e,t){ka=e,Oa=Ea=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&t)&&(ys=!0),e.firstContext=null)}function Ta(e){var t=e._currentValue;if(Oa!==e)if(e={context:e,memoizedValue:t,next:null},null===Ea){if(null===ka)throw Error(a(308));Ea=e,ka.dependencies={lanes:0,firstContext:e}}else Ea=Ea.next=e;return t}var Ia=null;function Na(e){null===Ia?Ia=[e]:Ia.push(e)}function La(e,t,n,r){var o=t.interleaved;return null===o?(n.next=n,Na(t)):(n.next=o.next,o.next=n),t.interleaved=n,Ra(e,r)}function Ra(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Da=!1;function Fa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ma(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Ba(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function za(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&Pc){var o=r.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),r.pending=t,Ra(e,n)}return null===(o=r.interleaved)?(t.next=t,Na(r)):(t.next=o.next,o.next=t),r.interleaved=t,Ra(e,n)}function $a(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,bt(e,n)}}function Ua(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,a=null;if(null!==(n=n.firstBaseUpdate)){do{var i={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===a?o=a=i:a=a.next=i,n=n.next}while(null!==n);null===a?o=a=t:a=a.next=t}else o=a=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:a,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Ha(e,t,n,r){var o=e.updateQueue;Da=!1;var a=o.firstBaseUpdate,i=o.lastBaseUpdate,s=o.shared.pending;if(null!==s){o.shared.pending=null;var c=s,l=c.next;c.next=null,null===i?a=l:i.next=l,i=c;var u=e.alternate;null!==u&&((s=(u=u.updateQueue).lastBaseUpdate)!==i&&(null===s?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(null!==a){var p=o.baseState;for(i=0,u=l=c=null,s=a;;){var d=s.lane,f=s.eventTime;if((r&d)===d){null!==u&&(u=u.next={eventTime:f,lane:0,tag:s.tag,payload:s.payload,callback:s.callback,next:null});e:{var m=e,h=s;switch(d=t,f=n,h.tag){case 1:if("function"==typeof(m=h.payload)){p=m.call(f,p,d);break e}p=m;break e;case 3:m.flags=-65537&m.flags|128;case 0:if(null==(d="function"==typeof(m=h.payload)?m.call(f,p,d):m))break e;p=F({},p,d);break e;case 2:Da=!0}}null!==s.callback&&0!==s.lane&&(e.flags|=64,null===(d=o.effects)?o.effects=[s]:d.push(s))}else f={eventTime:f,lane:d,tag:s.tag,payload:s.payload,callback:s.callback,next:null},null===u?(l=u=f,c=p):u=u.next=f,i|=d;if(null===(s=s.next)){if(null===(s=o.shared.pending))break;s=(d=s).next,d.next=null,o.lastBaseUpdate=d,o.shared.pending=null}}if(null===u&&(c=p),o.baseState=c,o.firstBaseUpdate=l,o.lastBaseUpdate=u,null!==(t=o.shared.interleaved)){o=t;do{i|=o.lane,o=o.next}while(o!==t)}else null===a&&(o.shared.lanes=0);Dc|=i,e.lanes=i,e.memoizedState=p}}function Va(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(a(191,o));o.call(r)}}}var Wa={},Qa=Eo(Wa),qa=Eo(Wa),Ga=Eo(Wa);function Ka(e){if(e===Wa)throw Error(a(174));return e}function Ya(e,t){switch(jo(Ga,t),jo(qa,e),jo(Qa,Wa),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ce(null,"");break;default:t=ce(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Oo(Qa),jo(Qa,t)}function Za(){Oo(Qa),Oo(qa),Oo(Ga)}function Xa(e){Ka(Ga.current);var t=Ka(Qa.current),n=ce(t,e.type);t!==n&&(jo(qa,e),jo(Qa,n))}function Ja(e){qa.current===e&&(Oo(Qa),Oo(qa))}var ei=Eo(0);function ti(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var ni=[];function ri(){for(var e=0;e<ni.length;e++)ni[e]._workInProgressVersionPrimary=null;ni.length=0}var oi=w.ReactCurrentDispatcher,ai=w.ReactCurrentBatchConfig,ii=0,si=null,ci=null,li=null,ui=!1,pi=!1,di=0,fi=0;function mi(){throw Error(a(321))}function hi(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!sr(e[n],t[n]))return!1;return!0}function vi(e,t,n,r,o,i){if(ii=i,si=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,oi.current=null===e||null===e.memoizedState?Ji:es,e=n(r,o),pi){i=0;do{if(pi=!1,di=0,25<=i)throw Error(a(301));i+=1,li=ci=null,t.updateQueue=null,oi.current=ts,e=n(r,o)}while(pi)}if(oi.current=Xi,t=null!==ci&&null!==ci.next,ii=0,li=ci=si=null,ui=!1,t)throw Error(a(300));return e}function gi(){var e=0!==di;return di=0,e}function bi(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===li?si.memoizedState=li=e:li=li.next=e,li}function yi(){if(null===ci){var e=si.alternate;e=null!==e?e.memoizedState:null}else e=ci.next;var t=null===li?si.memoizedState:li.next;if(null!==t)li=t,ci=e;else{if(null===e)throw Error(a(310));e={memoizedState:(ci=e).memoizedState,baseState:ci.baseState,baseQueue:ci.baseQueue,queue:ci.queue,next:null},null===li?si.memoizedState=li=e:li=li.next=e}return li}function wi(e,t){return"function"==typeof t?t(e):t}function _i(e){var t=yi(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=ci,o=r.baseQueue,i=n.pending;if(null!==i){if(null!==o){var s=o.next;o.next=i.next,i.next=s}r.baseQueue=o=i,n.pending=null}if(null!==o){i=o.next,r=r.baseState;var c=s=null,l=null,u=i;do{var p=u.lane;if((ii&p)===p)null!==l&&(l=l.next={lane:0,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null}),r=u.hasEagerState?u.eagerState:e(r,u.action);else{var d={lane:p,action:u.action,hasEagerState:u.hasEagerState,eagerState:u.eagerState,next:null};null===l?(c=l=d,s=r):l=l.next=d,si.lanes|=p,Dc|=p}u=u.next}while(null!==u&&u!==i);null===l?s=r:l.next=c,sr(r,t.memoizedState)||(ys=!0),t.memoizedState=r,t.baseState=s,t.baseQueue=l,n.lastRenderedState=r}if(null!==(e=n.interleaved)){o=e;do{i=o.lane,si.lanes|=i,Dc|=i,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function xi(e){var t=yi(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,i=t.memoizedState;if(null!==o){n.pending=null;var s=o=o.next;do{i=e(i,s.action),s=s.next}while(s!==o);sr(i,t.memoizedState)||(ys=!0),t.memoizedState=i,null===t.baseQueue&&(t.baseState=i),n.lastRenderedState=i}return[i,r]}function Si(){}function ki(e,t){var n=si,r=yi(),o=t(),i=!sr(r.memoizedState,o);if(i&&(r.memoizedState=o,ys=!0),r=r.queue,Di(ji.bind(null,n,r,e),[e]),r.getSnapshot!==t||i||null!==li&&1&li.memoizedState.tag){if(n.flags|=2048,Ti(9,Oi.bind(null,n,r,o,t),void 0,null),null===Cc)throw Error(a(349));30&ii||Ei(n,t,o)}return o}function Ei(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=si.updateQueue)?(t={lastEffect:null,stores:null},si.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Oi(e,t,n,r){t.value=n,t.getSnapshot=r,Pi(t)&&Ci(e)}function ji(e,t,n){return n((function(){Pi(t)&&Ci(e)}))}function Pi(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!sr(e,n)}catch(r){return!0}}function Ci(e){var t=Ra(e,1);null!==t&&nl(t,e,1,-1)}function Ai(e){var t=bi();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:wi,lastRenderedState:e},t.queue=e,e=e.dispatch=Gi.bind(null,si,e),[t.memoizedState,e]}function Ti(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=si.updateQueue)?(t={lastEffect:null,stores:null},si.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function Ii(){return yi().memoizedState}function Ni(e,t,n,r){var o=bi();si.flags|=e,o.memoizedState=Ti(1|t,n,void 0,void 0===r?null:r)}function Li(e,t,n,r){var o=yi();r=void 0===r?null:r;var a=void 0;if(null!==ci){var i=ci.memoizedState;if(a=i.destroy,null!==r&&hi(r,i.deps))return void(o.memoizedState=Ti(t,n,a,r))}si.flags|=e,o.memoizedState=Ti(1|t,n,a,r)}function Ri(e,t){return Ni(8390656,8,e,t)}function Di(e,t){return Li(2048,8,e,t)}function Fi(e,t){return Li(4,2,e,t)}function Mi(e,t){return Li(4,4,e,t)}function Bi(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function zi(e,t,n){return n=null!=n?n.concat([e]):null,Li(4,4,Bi.bind(null,t,e),n)}function $i(){}function Ui(e,t){var n=yi();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&hi(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Hi(e,t){var n=yi();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&hi(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Vi(e,t,n){return 21&ii?(sr(n,t)||(n=ht(),si.lanes|=n,Dc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,ys=!0),e.memoizedState=n)}function Wi(e,t){var n=yt;yt=0!==n&&4>n?n:4,e(!0);var r=ai.transition;ai.transition={};try{e(!1),t()}finally{yt=n,ai.transition=r}}function Qi(){return yi().memoizedState}function qi(e,t,n){var r=tl(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Ki(e))Yi(t,n);else if(null!==(n=La(e,t,n,r))){nl(n,e,r,el()),Zi(n,t,r)}}function Gi(e,t,n){var r=tl(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ki(e))Yi(t,o);else{var a=e.alternate;if(0===e.lanes&&(null===a||0===a.lanes)&&null!==(a=t.lastRenderedReducer))try{var i=t.lastRenderedState,s=a(i,n);if(o.hasEagerState=!0,o.eagerState=s,sr(s,i)){var c=t.interleaved;return null===c?(o.next=o,Na(t)):(o.next=c.next,c.next=o),void(t.interleaved=o)}}catch(l){}null!==(n=La(e,t,o,r))&&(nl(n,e,r,o=el()),Zi(n,t,r))}}function Ki(e){var t=e.alternate;return e===si||null!==t&&t===si}function Yi(e,t){pi=ui=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Zi(e,t,n){if(4194240&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,bt(e,n)}}var Xi={readContext:Ta,useCallback:mi,useContext:mi,useEffect:mi,useImperativeHandle:mi,useInsertionEffect:mi,useLayoutEffect:mi,useMemo:mi,useReducer:mi,useRef:mi,useState:mi,useDebugValue:mi,useDeferredValue:mi,useTransition:mi,useMutableSource:mi,useSyncExternalStore:mi,useId:mi,unstable_isNewReconciler:!1},Ji={readContext:Ta,useCallback:function(e,t){return bi().memoizedState=[e,void 0===t?null:t],e},useContext:Ta,useEffect:Ri,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,Ni(4194308,4,Bi.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Ni(4194308,4,e,t)},useInsertionEffect:function(e,t){return Ni(4,2,e,t)},useMemo:function(e,t){var n=bi();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=bi();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=qi.bind(null,si,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},bi().memoizedState=e},useState:Ai,useDebugValue:$i,useDeferredValue:function(e){return bi().memoizedState=e},useTransition:function(){var e=Ai(!1),t=e[0];return e=Wi.bind(null,e[1]),bi().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=si,o=bi();if(aa){if(void 0===n)throw Error(a(407));n=n()}else{if(n=t(),null===Cc)throw Error(a(349));30&ii||Ei(r,t,n)}o.memoizedState=n;var i={value:n,getSnapshot:t};return o.queue=i,Ri(ji.bind(null,r,i,e),[e]),r.flags|=2048,Ti(9,Oi.bind(null,r,i,n,t),void 0,null),n},useId:function(){var e=bi(),t=Cc.identifierPrefix;if(aa){var n=Xo;t=":"+t+"R"+(n=(Zo&~(1<<32-it(Zo)-1)).toString(32)+n),0<(n=di++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=fi++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},es={readContext:Ta,useCallback:Ui,useContext:Ta,useEffect:Di,useImperativeHandle:zi,useInsertionEffect:Fi,useLayoutEffect:Mi,useMemo:Hi,useReducer:_i,useRef:Ii,useState:function(){return _i(wi)},useDebugValue:$i,useDeferredValue:function(e){return Vi(yi(),ci.memoizedState,e)},useTransition:function(){return[_i(wi)[0],yi().memoizedState]},useMutableSource:Si,useSyncExternalStore:ki,useId:Qi,unstable_isNewReconciler:!1},ts={readContext:Ta,useCallback:Ui,useContext:Ta,useEffect:Di,useImperativeHandle:zi,useInsertionEffect:Fi,useLayoutEffect:Mi,useMemo:Hi,useReducer:xi,useRef:Ii,useState:function(){return xi(wi)},useDebugValue:$i,useDeferredValue:function(e){var t=yi();return null===ci?t.memoizedState=e:Vi(t,ci.memoizedState,e)},useTransition:function(){return[xi(wi)[0],yi().memoizedState]},useMutableSource:Si,useSyncExternalStore:ki,useId:Qi,unstable_isNewReconciler:!1};function ns(e,t){if(e&&e.defaultProps){for(var n in t=F({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}function rs(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:F({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var os={isMounted:function(e){return!!(e=e._reactInternals)&&Ue(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),a=Ba(r,o);a.payload=t,null!=n&&(a.callback=n),null!==(t=za(e,a,o))&&(nl(t,e,o,r),$a(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),a=Ba(r,o);a.tag=1,a.payload=t,null!=n&&(a.callback=n),null!==(t=za(e,a,o))&&(nl(t,e,o,r),$a(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=el(),r=tl(e),o=Ba(n,r);o.tag=2,null!=t&&(o.callback=t),null!==(t=za(e,o,r))&&(nl(t,e,r,n),$a(t,e,r))}};function as(e,t,n,r,o,a,i){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,a,i):!t.prototype||!t.prototype.isPureReactComponent||(!cr(n,r)||!cr(o,a))}function is(e,t,n){var r=!1,o=Po,a=t.contextType;return"object"==typeof a&&null!==a?a=Ta(a):(o=No(t)?To:Co.current,a=(r=null!=(r=t.contextTypes))?Io(e,o):Po),t=new t(n,a),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=os,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=a),t}function ss(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&os.enqueueReplaceState(t,t.state,null)}function cs(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs={},Fa(e);var a=t.contextType;"object"==typeof a&&null!==a?o.context=Ta(a):(a=No(t)?To:Co.current,o.context=Io(e,a)),o.state=e.memoizedState,"function"==typeof(a=t.getDerivedStateFromProps)&&(rs(e,t,a,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&os.enqueueReplaceState(o,o.state,null),Ha(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function ls(e,t){try{var n="",r=t;do{n+=$(r),r=r.return}while(r);var o=n}catch(a){o="\nError generating stack: "+a.message+"\n"+a.stack}return{value:e,source:t,stack:o,digest:null}}function us(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function ps(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var ds="function"==typeof WeakMap?WeakMap:Map;function fs(e,t,n){(n=Ba(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Vc||(Vc=!0,Wc=r),ps(0,t)},n}function ms(e,t,n){(n=Ba(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return r(o)},n.callback=function(){ps(0,t)}}var a=e.stateNode;return null!==a&&"function"==typeof a.componentDidCatch&&(n.callback=function(){ps(0,t),"function"!=typeof r&&(null===Qc?Qc=new Set([this]):Qc.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function hs(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new ds;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(o.add(n),e=El.bind(null,e,t,n),t.then(e,e))}function vs(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function gs(e,t,n,r,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Ba(-1,1)).tag=2,za(n,t,1))),n.lanes|=1),e)}var bs=w.ReactCurrentOwner,ys=!1;function ws(e,t,n,r){t.child=null===e?xa(t,null,n,r):_a(t,e.child,n,r)}function _s(e,t,n,r,o){n=n.render;var a=t.ref;return Aa(t,o),r=vi(e,t,n,r,a,o),n=gi(),null===e||ys?(aa&&n&&ta(t),t.flags|=1,ws(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Vs(e,t,o))}function xs(e,t,n,r,o){if(null===e){var a=n.type;return"function"!=typeof a||Il(a)||void 0!==a.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Ll(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=a,Ss(e,t,a,r,o))}if(a=e.child,!(e.lanes&o)){var i=a.memoizedProps;if((n=null!==(n=n.compare)?n:cr)(i,r)&&e.ref===t.ref)return Vs(e,t,o)}return t.flags|=1,(e=Nl(a,r)).ref=t.ref,e.return=t,t.child=e}function Ss(e,t,n,r,o){if(null!==e){var a=e.memoizedProps;if(cr(a,r)&&e.ref===t.ref){if(ys=!1,t.pendingProps=r=a,!(e.lanes&o))return t.lanes=e.lanes,Vs(e,t,o);131072&e.flags&&(ys=!0)}}return Os(e,t,n,r,o)}function ks(e,t,n){var r=t.pendingProps,o=r.children,a=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==a?a.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,jo(Nc,Ic),Ic|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==a?a.baseLanes:n,jo(Nc,Ic),Ic|=r}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},jo(Nc,Ic),Ic|=n;else null!==a?(r=a.baseLanes|n,t.memoizedState=null):r=n,jo(Nc,Ic),Ic|=r;return ws(e,t,o,n),t.child}function Es(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Os(e,t,n,r,o){var a=No(n)?To:Co.current;return a=Io(t,a),Aa(t,o),n=vi(e,t,n,r,a,o),r=gi(),null===e||ys?(aa&&r&&ta(t),t.flags|=1,ws(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Vs(e,t,o))}function js(e,t,n,r,o){if(No(n)){var a=!0;Fo(t)}else a=!1;if(Aa(t,o),null===t.stateNode)Hs(e,t),is(t,n,r),cs(t,n,r,o),r=!0;else if(null===e){var i=t.stateNode,s=t.memoizedProps;i.props=s;var c=i.context,l=n.contextType;"object"==typeof l&&null!==l?l=Ta(l):l=Io(t,l=No(n)?To:Co.current);var u=n.getDerivedStateFromProps,p="function"==typeof u||"function"==typeof i.getSnapshotBeforeUpdate;p||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==r||c!==l)&&ss(t,i,r,l),Da=!1;var d=t.memoizedState;i.state=d,Ha(t,r,i,o),c=t.memoizedState,s!==r||d!==c||Ao.current||Da?("function"==typeof u&&(rs(t,n,u,r),c=t.memoizedState),(s=Da||as(t,n,s,r,d,c,l))?(p||"function"!=typeof i.UNSAFE_componentWillMount&&"function"!=typeof i.componentWillMount||("function"==typeof i.componentWillMount&&i.componentWillMount(),"function"==typeof i.UNSAFE_componentWillMount&&i.UNSAFE_componentWillMount()),"function"==typeof i.componentDidMount&&(t.flags|=4194308)):("function"==typeof i.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=c),i.props=r,i.state=c,i.context=l,r=s):("function"==typeof i.componentDidMount&&(t.flags|=4194308),r=!1)}else{i=t.stateNode,Ma(e,t),s=t.memoizedProps,l=t.type===t.elementType?s:ns(t.type,s),i.props=l,p=t.pendingProps,d=i.context,"object"==typeof(c=n.contextType)&&null!==c?c=Ta(c):c=Io(t,c=No(n)?To:Co.current);var f=n.getDerivedStateFromProps;(u="function"==typeof f||"function"==typeof i.getSnapshotBeforeUpdate)||"function"!=typeof i.UNSAFE_componentWillReceiveProps&&"function"!=typeof i.componentWillReceiveProps||(s!==p||d!==c)&&ss(t,i,r,c),Da=!1,d=t.memoizedState,i.state=d,Ha(t,r,i,o);var m=t.memoizedState;s!==p||d!==m||Ao.current||Da?("function"==typeof f&&(rs(t,n,f,r),m=t.memoizedState),(l=Da||as(t,n,l,r,d,m,c)||!1)?(u||"function"!=typeof i.UNSAFE_componentWillUpdate&&"function"!=typeof i.componentWillUpdate||("function"==typeof i.componentWillUpdate&&i.componentWillUpdate(r,m,c),"function"==typeof i.UNSAFE_componentWillUpdate&&i.UNSAFE_componentWillUpdate(r,m,c)),"function"==typeof i.componentDidUpdate&&(t.flags|=4),"function"==typeof i.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=m),i.props=r,i.state=m,i.context=c,r=l):("function"!=typeof i.componentDidUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=4),"function"!=typeof i.getSnapshotBeforeUpdate||s===e.memoizedProps&&d===e.memoizedState||(t.flags|=1024),r=!1)}return Ps(e,t,n,r,a,o)}function Ps(e,t,n,r,o,a){Es(e,t);var i=!!(128&t.flags);if(!r&&!i)return o&&Mo(t,n,!1),Vs(e,t,a);r=t.stateNode,bs.current=t;var s=i&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&i?(t.child=_a(t,e.child,null,a),t.child=_a(t,null,s,a)):ws(e,t,s,a),t.memoizedState=r.state,o&&Mo(t,n,!0),t.child}function Cs(e){var t=e.stateNode;t.pendingContext?Ro(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Ro(0,t.context,!1),Ya(e,t.containerInfo)}function As(e,t,n,r,o){return ma(),ha(o),t.flags|=256,ws(e,t,n,r),t.child}var Ts,Is,Ns,Ls,Rs={dehydrated:null,treeContext:null,retryLane:0};function Ds(e){return{baseLanes:e,cachePool:null,transitions:null}}function Fs(e,t,n){var r,o=t.pendingProps,i=ei.current,s=!1,c=!!(128&t.flags);if((r=c)||(r=(null===e||null!==e.memoizedState)&&!!(2&i)),r?(s=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(i|=1),jo(ei,1&i),null===e)return ua(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(c=o.children,e=o.fallback,s?(o=t.mode,s=t.child,c={mode:"hidden",children:c},1&o||null===s?s=Dl(c,o,0,null):(s.childLanes=0,s.pendingProps=c),e=Rl(e,o,n,null),s.return=t,e.return=t,s.sibling=e,t.child=s,t.child.memoizedState=Ds(n),t.memoizedState=Rs,e):Ms(t,c));if(null!==(i=e.memoizedState)&&null!==(r=i.dehydrated))return function(e,t,n,r,o,i,s){if(n)return 256&t.flags?(t.flags&=-257,Bs(e,t,s,r=us(Error(a(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(i=r.fallback,o=t.mode,r=Dl({mode:"visible",children:r.children},o,0,null),(i=Rl(i,o,s,null)).flags|=2,r.return=t,i.return=t,r.sibling=i,t.child=r,1&t.mode&&_a(t,e.child,null,s),t.child.memoizedState=Ds(s),t.memoizedState=Rs,i);if(!(1&t.mode))return Bs(e,t,s,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var c=r.dgst;return r=c,Bs(e,t,s,r=us(i=Error(a(419)),r,void 0))}if(c=!!(s&e.childLanes),ys||c){if(null!==(r=Cc)){switch(s&-s){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(r.suspendedLanes|s)?0:o)&&o!==i.retryLane&&(i.retryLane=o,Ra(e,o),nl(r,e,o,-1))}return hl(),Bs(e,t,s,r=us(Error(a(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=jl.bind(null,e),o._reactRetry=t,null):(e=i.treeContext,oa=lo(o.nextSibling),ra=t,aa=!0,ia=null,null!==e&&(Go[Ko++]=Zo,Go[Ko++]=Xo,Go[Ko++]=Yo,Zo=e.id,Xo=e.overflow,Yo=t),t=Ms(t,r.children),t.flags|=4096,t)}(e,t,c,o,r,i,n);if(s){s=o.fallback,c=t.mode,r=(i=e.child).sibling;var l={mode:"hidden",children:o.children};return 1&c||t.child===i?(o=Nl(i,l)).subtreeFlags=14680064&i.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=l,t.deletions=null),null!==r?s=Nl(r,s):(s=Rl(s,c,n,null)).flags|=2,s.return=t,o.return=t,o.sibling=s,t.child=o,o=s,s=t.child,c=null===(c=e.child.memoizedState)?Ds(n):{baseLanes:c.baseLanes|n,cachePool:null,transitions:c.transitions},s.memoizedState=c,s.childLanes=e.childLanes&~n,t.memoizedState=Rs,o}return e=(s=e.child).sibling,o=Nl(s,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Ms(e,t){return(t=Dl({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function Bs(e,t,n,r){return null!==r&&ha(r),_a(t,e.child,null,n),(e=Ms(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function zs(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),Ca(e.return,t,n)}function $s(e,t,n,r,o){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(a.isBackwards=t,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=n,a.tailMode=o)}function Us(e,t,n){var r=t.pendingProps,o=r.revealOrder,a=r.tail;if(ws(e,t,r.children,n),2&(r=ei.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&zs(e,n,t);else if(19===e.tag)zs(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(jo(ei,r),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===ti(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),$s(t,!1,o,n,a);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===ti(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}$s(t,!0,n,null,a);break;case"together":$s(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function Hs(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Vs(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dc|=t.lanes,!(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(a(153));if(null!==t.child){for(n=Nl(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Nl(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Ws(e,t){if(!aa)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Qs(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function qs(e,t,n){var r=t.pendingProps;switch(na(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Qs(t),null;case 1:case 17:return No(t.type)&&Lo(),Qs(t),null;case 3:return r=t.stateNode,Za(),Oo(Ao),Oo(Co),ri(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(da(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==ia&&(il(ia),ia=null))),Is(e,t),Qs(t),null;case 5:Ja(t);var o=Ka(Ga.current);if(n=t.type,null!==e&&null!=t.stateNode)Ns(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(null===t.stateNode)throw Error(a(166));return Qs(t),null}if(e=Ka(Qa.current),da(t)){r=t.stateNode,n=t.type;var i=t.memoizedProps;switch(r[fo]=t,r[mo]=i,e=!!(1&t.mode),n){case"dialog":Br("cancel",r),Br("close",r);break;case"iframe":case"object":case"embed":Br("load",r);break;case"video":case"audio":for(o=0;o<Rr.length;o++)Br(Rr[o],r);break;case"source":Br("error",r);break;case"img":case"image":case"link":Br("error",r),Br("load",r);break;case"details":Br("toggle",r);break;case"input":Y(r,i),Br("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!i.multiple},Br("invalid",r);break;case"textarea":oe(r,i),Br("invalid",r)}for(var c in be(n,i),o=null,i)if(i.hasOwnProperty(c)){var l=i[c];"children"===c?"string"==typeof l?r.textContent!==l&&(!0!==i.suppressHydrationWarning&&Xr(r.textContent,l,e),o=["children",l]):"number"==typeof l&&r.textContent!==""+l&&(!0!==i.suppressHydrationWarning&&Xr(r.textContent,l,e),o=["children",""+l]):s.hasOwnProperty(c)&&null!=l&&"onScroll"===c&&Br("scroll",r)}switch(n){case"input":Q(r),J(r,i,!0);break;case"textarea":Q(r),ie(r);break;case"select":case"option":break;default:"function"==typeof i.onClick&&(r.onclick=Jr)}r=o,t.updateQueue=r,null!==r&&(t.flags|=4)}else{c=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=se(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[fo]=t,e[mo]=r,Ts(e,t,!1,!1),t.stateNode=e;e:{switch(c=ye(n,r),n){case"dialog":Br("cancel",e),Br("close",e),o=r;break;case"iframe":case"object":case"embed":Br("load",e),o=r;break;case"video":case"audio":for(o=0;o<Rr.length;o++)Br(Rr[o],e);o=r;break;case"source":Br("error",e),o=r;break;case"img":case"image":case"link":Br("error",e),Br("load",e),o=r;break;case"details":Br("toggle",e),o=r;break;case"input":Y(e,r),o=K(e,r),Br("invalid",e);break;case"option":default:o=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=F({},r,{value:void 0}),Br("invalid",e);break;case"textarea":oe(e,r),o=re(e,r),Br("invalid",e)}for(i in be(n,o),l=o)if(l.hasOwnProperty(i)){var u=l[i];"style"===i?ve(e,u):"dangerouslySetInnerHTML"===i?null!=(u=u?u.__html:void 0)&&pe(e,u):"children"===i?"string"==typeof u?("textarea"!==n||""!==u)&&de(e,u):"number"==typeof u&&de(e,""+u):"suppressContentEditableWarning"!==i&&"suppressHydrationWarning"!==i&&"autoFocus"!==i&&(s.hasOwnProperty(i)?null!=u&&"onScroll"===i&&Br("scroll",e):null!=u&&y(e,i,u,c))}switch(n){case"input":Q(e),J(e,r,!1);break;case"textarea":Q(e),ie(e);break;case"option":null!=r.value&&e.setAttribute("value",""+V(r.value));break;case"select":e.multiple=!!r.multiple,null!=(i=r.value)?ne(e,!!r.multiple,i,!1):null!=r.defaultValue&&ne(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Jr)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Qs(t),null;case 6:if(e&&null!=t.stateNode)Ls(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(a(166));if(n=Ka(Ga.current),Ka(Qa.current),da(t)){if(r=t.stateNode,n=t.memoizedProps,r[fo]=t,(i=r.nodeValue!==n)&&null!==(e=ra))switch(e.tag){case 3:Xr(r.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Xr(r.nodeValue,n,!!(1&e.mode))}i&&(t.flags|=4)}else(r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[fo]=t,t.stateNode=r}return Qs(t),null;case 13:if(Oo(ei),r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(aa&&null!==oa&&1&t.mode&&!(128&t.flags))fa(),ma(),t.flags|=98560,i=!1;else if(i=da(t),null!==r&&null!==r.dehydrated){if(null===e){if(!i)throw Error(a(318));if(!(i=null!==(i=t.memoizedState)?i.dehydrated:null))throw Error(a(317));i[fo]=t}else ma(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Qs(t),i=!1}else null!==ia&&(il(ia),ia=null),i=!0;if(!i)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(t.child.flags|=8192,1&t.mode&&(null===e||1&ei.current?0===Lc&&(Lc=3):hl())),null!==t.updateQueue&&(t.flags|=4),Qs(t),null);case 4:return Za(),Is(e,t),null===e&&Ur(t.stateNode.containerInfo),Qs(t),null;case 10:return Pa(t.type._context),Qs(t),null;case 19:if(Oo(ei),null===(i=t.memoizedState))return Qs(t),null;if(r=!!(128&t.flags),null===(c=i.rendering))if(r)Ws(i,!1);else{if(0!==Lc||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(c=ti(e))){for(t.flags|=128,Ws(i,!1),null!==(r=c.updateQueue)&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;null!==n;)e=r,(i=n).flags&=14680066,null===(c=i.alternate)?(i.childLanes=0,i.lanes=e,i.child=null,i.subtreeFlags=0,i.memoizedProps=null,i.memoizedState=null,i.updateQueue=null,i.dependencies=null,i.stateNode=null):(i.childLanes=c.childLanes,i.lanes=c.lanes,i.child=c.child,i.subtreeFlags=0,i.deletions=null,i.memoizedProps=c.memoizedProps,i.memoizedState=c.memoizedState,i.updateQueue=c.updateQueue,i.type=c.type,e=c.dependencies,i.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return jo(ei,1&ei.current|2),t.child}e=e.sibling}null!==i.tail&&Ze()>Uc&&(t.flags|=128,r=!0,Ws(i,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=ti(c))){if(t.flags|=128,r=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Ws(i,!0),null===i.tail&&"hidden"===i.tailMode&&!c.alternate&&!aa)return Qs(t),null}else 2*Ze()-i.renderingStartTime>Uc&&1073741824!==n&&(t.flags|=128,r=!0,Ws(i,!1),t.lanes=4194304);i.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=i.last)?n.sibling=c:t.child=c,i.last=c)}return null!==i.tail?(t=i.tail,i.rendering=t,i.tail=t.sibling,i.renderingStartTime=Ze(),t.sibling=null,n=ei.current,jo(ei,r?1&n|2:1&n),t):(Qs(t),null);case 22:case 23:return pl(),r=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==r&&(t.flags|=8192),r&&1&t.mode?!!(1073741824&Ic)&&(Qs(t),6&t.subtreeFlags&&(t.flags|=8192)):Qs(t),null;case 24:case 25:return null}throw Error(a(156,t.tag))}function Gs(e,t){switch(na(t),t.tag){case 1:return No(t.type)&&Lo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return Za(),Oo(Ao),Oo(Co),ri(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return Ja(t),null;case 13:if(Oo(ei),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(a(340));ma()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Oo(ei),null;case 4:return Za(),null;case 10:return Pa(t.type._context),null;case 22:case 23:return pl(),null;default:return null}}Ts=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Is=function(){},Ns=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ka(Qa.current);var a,i=null;switch(n){case"input":o=K(e,o),r=K(e,r),i=[];break;case"select":o=F({},o,{value:void 0}),r=F({},r,{value:void 0}),i=[];break;case"textarea":o=re(e,o),r=re(e,r),i=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Jr)}for(u in be(n,r),n=null,o)if(!r.hasOwnProperty(u)&&o.hasOwnProperty(u)&&null!=o[u])if("style"===u){var c=o[u];for(a in c)c.hasOwnProperty(a)&&(n||(n={}),n[a]="")}else"dangerouslySetInnerHTML"!==u&&"children"!==u&&"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&"autoFocus"!==u&&(s.hasOwnProperty(u)?i||(i=[]):(i=i||[]).push(u,null));for(u in r){var l=r[u];if(c=null!=o?o[u]:void 0,r.hasOwnProperty(u)&&l!==c&&(null!=l||null!=c))if("style"===u)if(c){for(a in c)!c.hasOwnProperty(a)||l&&l.hasOwnProperty(a)||(n||(n={}),n[a]="");for(a in l)l.hasOwnProperty(a)&&c[a]!==l[a]&&(n||(n={}),n[a]=l[a])}else n||(i||(i=[]),i.push(u,n)),n=l;else"dangerouslySetInnerHTML"===u?(l=l?l.__html:void 0,c=c?c.__html:void 0,null!=l&&c!==l&&(i=i||[]).push(u,l)):"children"===u?"string"!=typeof l&&"number"!=typeof l||(i=i||[]).push(u,""+l):"suppressContentEditableWarning"!==u&&"suppressHydrationWarning"!==u&&(s.hasOwnProperty(u)?(null!=l&&"onScroll"===u&&Br("scroll",e),i||c===l||(i=[])):(i=i||[]).push(u,l))}n&&(i=i||[]).push("style",n);var u=i;(t.updateQueue=u)&&(t.flags|=4)}},Ls=function(e,t,n,r){n!==r&&(t.flags|=4)};var Ks=!1,Ys=!1,Zs="function"==typeof WeakSet?WeakSet:Set,Xs=null;function Js(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){kl(e,t,r)}else n.current=null}function ec(e,t,n){try{n()}catch(r){kl(e,t,r)}}var tc=!1;function nc(e,t,n){var r=t.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&e)===e){var a=o.destroy;o.destroy=void 0,void 0!==a&&ec(t,n,a)}o=o.next}while(o!==r)}}function rc(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function oc(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function ac(e){var t=e.alternate;null!==t&&(e.alternate=null,ac(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[fo],delete t[mo],delete t[vo],delete t[go],delete t[bo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function ic(e){return 5===e.tag||3===e.tag||4===e.tag}function sc(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||ic(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Jr));else if(4!==r&&null!==(e=e.child))for(cc(e,t,n),e=e.sibling;null!==e;)cc(e,t,n),e=e.sibling}function lc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(lc(e,t,n),e=e.sibling;null!==e;)lc(e,t,n),e=e.sibling}var uc=null,pc=!1;function dc(e,t,n){for(n=n.child;null!==n;)fc(e,t,n),n=n.sibling}function fc(e,t,n){if(at&&"function"==typeof at.onCommitFiberUnmount)try{at.onCommitFiberUnmount(ot,n)}catch(s){}switch(n.tag){case 5:Ys||Js(n,t);case 6:var r=uc,o=pc;uc=null,dc(e,t,n),pc=o,null!==(uc=r)&&(pc?(e=uc,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):uc.removeChild(n.stateNode));break;case 18:null!==uc&&(pc?(e=uc,n=n.stateNode,8===e.nodeType?co(e.parentNode,n):1===e.nodeType&&co(e,n),Ut(e)):co(uc,n.stateNode));break;case 4:r=uc,o=pc,uc=n.stateNode.containerInfo,pc=!0,dc(e,t,n),uc=r,pc=o;break;case 0:case 11:case 14:case 15:if(!Ys&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var a=o,i=a.destroy;a=a.tag,void 0!==i&&(2&a||4&a)&&ec(n,t,i),o=o.next}while(o!==r)}dc(e,t,n);break;case 1:if(!Ys&&(Js(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(s){kl(n,t,s)}dc(e,t,n);break;case 21:dc(e,t,n);break;case 22:1&n.mode?(Ys=(r=Ys)||null!==n.memoizedState,dc(e,t,n),Ys=r):dc(e,t,n);break;default:dc(e,t,n)}}function mc(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Zs),t.forEach((function(t){var r=Pl.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function hc(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var o=n[r];try{var i=e,s=t,c=s;e:for(;null!==c;){switch(c.tag){case 5:uc=c.stateNode,pc=!1;break e;case 3:case 4:uc=c.stateNode.containerInfo,pc=!0;break e}c=c.return}if(null===uc)throw Error(a(160));fc(i,s,o),uc=null,pc=!1;var l=o.alternate;null!==l&&(l.return=null),o.return=null}catch(u){kl(o,t,u)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)vc(t,e),t=t.sibling}function vc(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(hc(t,e),gc(e),4&r){try{nc(3,e,e.return),rc(3,e)}catch(v){kl(e,e.return,v)}try{nc(5,e,e.return)}catch(v){kl(e,e.return,v)}}break;case 1:hc(t,e),gc(e),512&r&&null!==n&&Js(n,n.return);break;case 5:if(hc(t,e),gc(e),512&r&&null!==n&&Js(n,n.return),32&e.flags){var o=e.stateNode;try{de(o,"")}catch(v){kl(e,e.return,v)}}if(4&r&&null!=(o=e.stateNode)){var i=e.memoizedProps,s=null!==n?n.memoizedProps:i,c=e.type,l=e.updateQueue;if(e.updateQueue=null,null!==l)try{"input"===c&&"radio"===i.type&&null!=i.name&&Z(o,i),ye(c,s);var u=ye(c,i);for(s=0;s<l.length;s+=2){var p=l[s],d=l[s+1];"style"===p?ve(o,d):"dangerouslySetInnerHTML"===p?pe(o,d):"children"===p?de(o,d):y(o,p,d,u)}switch(c){case"input":X(o,i);break;case"textarea":ae(o,i);break;case"select":var f=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!i.multiple;var m=i.value;null!=m?ne(o,!!i.multiple,m,!1):f!==!!i.multiple&&(null!=i.defaultValue?ne(o,!!i.multiple,i.defaultValue,!0):ne(o,!!i.multiple,i.multiple?[]:"",!1))}o[mo]=i}catch(v){kl(e,e.return,v)}}break;case 6:if(hc(t,e),gc(e),4&r){if(null===e.stateNode)throw Error(a(162));o=e.stateNode,i=e.memoizedProps;try{o.nodeValue=i}catch(v){kl(e,e.return,v)}}break;case 3:if(hc(t,e),gc(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{Ut(t.containerInfo)}catch(v){kl(e,e.return,v)}break;case 4:default:hc(t,e),gc(e);break;case 13:hc(t,e),gc(e),8192&(o=e.child).flags&&(i=null!==o.memoizedState,o.stateNode.isHidden=i,!i||null!==o.alternate&&null!==o.alternate.memoizedState||($c=Ze())),4&r&&mc(e);break;case 22:if(p=null!==n&&null!==n.memoizedState,1&e.mode?(Ys=(u=Ys)||p,hc(t,e),Ys=u):hc(t,e),gc(e),8192&r){if(u=null!==e.memoizedState,(e.stateNode.isHidden=u)&&!p&&1&e.mode)for(Xs=e,p=e.child;null!==p;){for(d=Xs=p;null!==Xs;){switch(m=(f=Xs).child,f.tag){case 0:case 11:case 14:case 15:nc(4,f,f.return);break;case 1:Js(f,f.return);var h=f.stateNode;if("function"==typeof h.componentWillUnmount){r=f,n=f.return;try{t=r,h.props=t.memoizedProps,h.state=t.memoizedState,h.componentWillUnmount()}catch(v){kl(r,n,v)}}break;case 5:Js(f,f.return);break;case 22:if(null!==f.memoizedState){_c(d);continue}}null!==m?(m.return=f,Xs=m):_c(d)}p=p.sibling}e:for(p=null,d=e;;){if(5===d.tag){if(null===p){p=d;try{o=d.stateNode,u?"function"==typeof(i=o.style).setProperty?i.setProperty("display","none","important"):i.display="none":(c=d.stateNode,s=null!=(l=d.memoizedProps.style)&&l.hasOwnProperty("display")?l.display:null,c.style.display=he("display",s))}catch(v){kl(e,e.return,v)}}}else if(6===d.tag){if(null===p)try{d.stateNode.nodeValue=u?"":d.memoizedProps}catch(v){kl(e,e.return,v)}}else if((22!==d.tag&&23!==d.tag||null===d.memoizedState||d===e)&&null!==d.child){d.child.return=d,d=d.child;continue}if(d===e)break e;for(;null===d.sibling;){if(null===d.return||d.return===e)break e;p===d&&(p=null),d=d.return}p===d&&(p=null),d.sibling.return=d.return,d=d.sibling}}break;case 19:hc(t,e),gc(e),4&r&&mc(e);case 21:}}function gc(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(ic(n)){var r=n;break e}n=n.return}throw Error(a(160))}switch(r.tag){case 5:var o=r.stateNode;32&r.flags&&(de(o,""),r.flags&=-33),lc(e,sc(e),o);break;case 3:case 4:var i=r.stateNode.containerInfo;cc(e,sc(e),i);break;default:throw Error(a(161))}}catch(s){kl(e,e.return,s)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function bc(e,t,n){Xs=e,yc(e,t,n)}function yc(e,t,n){for(var r=!!(1&e.mode);null!==Xs;){var o=Xs,a=o.child;if(22===o.tag&&r){var i=null!==o.memoizedState||Ks;if(!i){var s=o.alternate,c=null!==s&&null!==s.memoizedState||Ys;s=Ks;var l=Ys;if(Ks=i,(Ys=c)&&!l)for(Xs=o;null!==Xs;)c=(i=Xs).child,22===i.tag&&null!==i.memoizedState?xc(o):null!==c?(c.return=i,Xs=c):xc(o);for(;null!==a;)Xs=a,yc(a,t,n),a=a.sibling;Xs=o,Ks=s,Ys=l}wc(e)}else 8772&o.subtreeFlags&&null!==a?(a.return=o,Xs=a):wc(e)}}function wc(e){for(;null!==Xs;){var t=Xs;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Ys||rc(5,t);break;case 1:var r=t.stateNode;if(4&t.flags&&!Ys)if(null===n)r.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ns(t.type,n.memoizedProps);r.componentDidUpdate(o,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var i=t.updateQueue;null!==i&&Va(t,i,r);break;case 3:var s=t.updateQueue;if(null!==s){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Va(t,s,n)}break;case 5:var c=t.stateNode;if(null===n&&4&t.flags){n=c;var l=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":l.autoFocus&&n.focus();break;case"img":l.src&&(n.src=l.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var u=t.alternate;if(null!==u){var p=u.memoizedState;if(null!==p){var d=p.dehydrated;null!==d&&Ut(d)}}}break;default:throw Error(a(163))}Ys||512&t.flags&&oc(t)}catch(f){kl(t,t.return,f)}}if(t===e){Xs=null;break}if(null!==(n=t.sibling)){n.return=t.return,Xs=n;break}Xs=t.return}}function _c(e){for(;null!==Xs;){var t=Xs;if(t===e){Xs=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Xs=n;break}Xs=t.return}}function xc(e){for(;null!==Xs;){var t=Xs;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{rc(4,t)}catch(c){kl(t,n,c)}break;case 1:var r=t.stateNode;if("function"==typeof r.componentDidMount){var o=t.return;try{r.componentDidMount()}catch(c){kl(t,o,c)}}var a=t.return;try{oc(t)}catch(c){kl(t,a,c)}break;case 5:var i=t.return;try{oc(t)}catch(c){kl(t,i,c)}}}catch(c){kl(t,t.return,c)}if(t===e){Xs=null;break}var s=t.sibling;if(null!==s){s.return=t.return,Xs=s;break}Xs=t.return}}var Sc,kc=Math.ceil,Ec=w.ReactCurrentDispatcher,Oc=w.ReactCurrentOwner,jc=w.ReactCurrentBatchConfig,Pc=0,Cc=null,Ac=null,Tc=0,Ic=0,Nc=Eo(0),Lc=0,Rc=null,Dc=0,Fc=0,Mc=0,Bc=null,zc=null,$c=0,Uc=1/0,Hc=null,Vc=!1,Wc=null,Qc=null,qc=!1,Gc=null,Kc=0,Yc=0,Zc=null,Xc=-1,Jc=0;function el(){return 6&Pc?Ze():-1!==Xc?Xc:Xc=Ze()}function tl(e){return 1&e.mode?2&Pc&&0!==Tc?Tc&-Tc:null!==va.transition?(0===Jc&&(Jc=ht()),Jc):0!==(e=yt)?e:e=void 0===(e=window.event)?16:Yt(e.type):1}function nl(e,t,n,r){if(50<Yc)throw Yc=0,Zc=null,Error(a(185));gt(e,n,r),2&Pc&&e===Cc||(e===Cc&&(!(2&Pc)&&(Fc|=n),4===Lc&&sl(e,Tc)),rl(e,r),1===n&&0===Pc&&!(1&t.mode)&&(Uc=Ze()+500,zo&&Ho()))}function rl(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,a=e.pendingLanes;0<a;){var i=31-it(a),s=1<<i,c=o[i];-1===c?s&n&&!(s&r)||(o[i]=ft(s,t)):c<=t&&(e.expiredLanes|=s),a&=~s}}(e,t);var r=dt(e,e===Cc?Tc:0);if(0===r)null!==n&&Ge(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(null!=n&&Ge(n),1===t)0===e.tag?function(e){zo=!0,Uo(e)}(cl.bind(null,e)):Uo(cl.bind(null,e)),io((function(){!(6&Pc)&&Ho()})),n=null;else{switch(wt(r)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=rt}n=Cl(n,ol.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function ol(e,t){if(Xc=-1,Jc=0,6&Pc)throw Error(a(327));var n=e.callbackNode;if(xl()&&e.callbackNode!==n)return null;var r=dt(e,e===Cc?Tc:0);if(0===r)return null;if(30&r||r&e.expiredLanes||t)t=vl(e,r);else{t=r;var o=Pc;Pc|=2;var i=ml();for(Cc===e&&Tc===t||(Hc=null,Uc=Ze()+500,dl(e,t));;)try{bl();break}catch(c){fl(e,c)}ja(),Ec.current=i,Pc=o,null!==Ac?t=0:(Cc=null,Tc=0,t=Lc)}if(0!==t){if(2===t&&(0!==(o=mt(e))&&(r=o,t=al(e,o))),1===t)throw n=Rc,dl(e,0),sl(e,r),rl(e,Ze()),n;if(6===t)sl(e,r);else{if(o=e.current.alternate,!(30&r||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var r=0;r<n.length;r++){var o=n[r],a=o.getSnapshot;o=o.value;try{if(!sr(a(),o))return!1}catch(s){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=vl(e,r),2===t&&(i=mt(e),0!==i&&(r=i,t=al(e,i))),1!==t)))throw n=Rc,dl(e,0),sl(e,r),rl(e,Ze()),n;switch(e.finishedWork=o,e.finishedLanes=r,t){case 0:case 1:throw Error(a(345));case 2:case 5:_l(e,zc,Hc);break;case 3:if(sl(e,r),(130023424&r)===r&&10<(t=$c+500-Ze())){if(0!==dt(e,0))break;if(((o=e.suspendedLanes)&r)!==r){el(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ro(_l.bind(null,e,zc,Hc),t);break}_l(e,zc,Hc);break;case 4:if(sl(e,r),(4194240&r)===r)break;for(t=e.eventTimes,o=-1;0<r;){var s=31-it(r);i=1<<s,(s=t[s])>o&&(o=s),r&=~i}if(r=o,10<(r=(120>(r=Ze()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*kc(r/1960))-r)){e.timeoutHandle=ro(_l.bind(null,e,zc,Hc),r);break}_l(e,zc,Hc);break;default:throw Error(a(329))}}}return rl(e,Ze()),e.callbackNode===n?ol.bind(null,e):null}function al(e,t){var n=Bc;return e.current.memoizedState.isDehydrated&&(dl(e,t).flags|=256),2!==(e=vl(e,t))&&(t=zc,zc=n,null!==t&&il(t)),e}function il(e){null===zc?zc=e:zc.push.apply(zc,e)}function sl(e,t){for(t&=~Mc,t&=~Fc,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-it(t),r=1<<n;e[n]=-1,t&=~r}}function cl(e){if(6&Pc)throw Error(a(327));xl();var t=dt(e,0);if(!(1&t))return rl(e,Ze()),null;var n=vl(e,t);if(0!==e.tag&&2===n){var r=mt(e);0!==r&&(t=r,n=al(e,r))}if(1===n)throw n=Rc,dl(e,0),sl(e,t),rl(e,Ze()),n;if(6===n)throw Error(a(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,_l(e,zc,Hc),rl(e,Ze()),null}function ll(e,t){var n=Pc;Pc|=1;try{return e(t)}finally{0===(Pc=n)&&(Uc=Ze()+500,zo&&Ho())}}function ul(e){null!==Gc&&0===Gc.tag&&!(6&Pc)&&xl();var t=Pc;Pc|=1;var n=jc.transition,r=yt;try{if(jc.transition=null,yt=1,e)return e()}finally{yt=r,jc.transition=n,!(6&(Pc=t))&&Ho()}}function pl(){Ic=Nc.current,Oo(Nc)}function dl(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Ac)for(n=Ac.return;null!==n;){var r=n;switch(na(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Lo();break;case 3:Za(),Oo(Ao),Oo(Co),ri();break;case 5:Ja(r);break;case 4:Za();break;case 13:case 19:Oo(ei);break;case 10:Pa(r.type._context);break;case 22:case 23:pl()}n=n.return}if(Cc=e,Ac=e=Nl(e.current,null),Tc=Ic=t,Lc=0,Rc=null,Mc=Fc=Dc=0,zc=Bc=null,null!==Ia){for(t=0;t<Ia.length;t++)if(null!==(r=(n=Ia[t]).interleaved)){n.interleaved=null;var o=r.next,a=n.pending;if(null!==a){var i=a.next;a.next=o,r.next=i}n.pending=r}Ia=null}return e}function fl(e,t){for(;;){var n=Ac;try{if(ja(),oi.current=Xi,ui){for(var r=si.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ui=!1}if(ii=0,li=ci=si=null,pi=!1,di=0,Oc.current=null,null===n||null===n.return){Lc=1,Rc=t,Ac=null;break}e:{var i=e,s=n.return,c=n,l=t;if(t=Tc,c.flags|=32768,null!==l&&"object"==typeof l&&"function"==typeof l.then){var u=l,p=c,d=p.tag;if(!(1&p.mode||0!==d&&11!==d&&15!==d)){var f=p.alternate;f?(p.updateQueue=f.updateQueue,p.memoizedState=f.memoizedState,p.lanes=f.lanes):(p.updateQueue=null,p.memoizedState=null)}var m=vs(s);if(null!==m){m.flags&=-257,gs(m,s,c,0,t),1&m.mode&&hs(i,u,t),l=u;var h=(t=m).updateQueue;if(null===h){var v=new Set;v.add(l),t.updateQueue=v}else h.add(l);break e}if(!(1&t)){hs(i,u,t),hl();break e}l=Error(a(426))}else if(aa&&1&c.mode){var g=vs(s);if(null!==g){!(65536&g.flags)&&(g.flags|=256),gs(g,s,c,0,t),ha(ls(l,c));break e}}i=l=ls(l,c),4!==Lc&&(Lc=2),null===Bc?Bc=[i]:Bc.push(i),i=s;do{switch(i.tag){case 3:i.flags|=65536,t&=-t,i.lanes|=t,Ua(i,fs(0,l,t));break e;case 1:c=l;var b=i.type,y=i.stateNode;if(!(128&i.flags||"function"!=typeof b.getDerivedStateFromError&&(null===y||"function"!=typeof y.componentDidCatch||null!==Qc&&Qc.has(y)))){i.flags|=65536,t&=-t,i.lanes|=t,Ua(i,ms(i,c,t));break e}}i=i.return}while(null!==i)}wl(n)}catch(w){t=w,Ac===n&&null!==n&&(Ac=n=n.return);continue}break}}function ml(){var e=Ec.current;return Ec.current=Xi,null===e?Xi:e}function hl(){0!==Lc&&3!==Lc&&2!==Lc||(Lc=4),null===Cc||!(268435455&Dc)&&!(268435455&Fc)||sl(Cc,Tc)}function vl(e,t){var n=Pc;Pc|=2;var r=ml();for(Cc===e&&Tc===t||(Hc=null,dl(e,t));;)try{gl();break}catch(o){fl(e,o)}if(ja(),Pc=n,Ec.current=r,null!==Ac)throw Error(a(261));return Cc=null,Tc=0,Lc}function gl(){for(;null!==Ac;)yl(Ac)}function bl(){for(;null!==Ac&&!Ke();)yl(Ac)}function yl(e){var t=Sc(e.alternate,e,Ic);e.memoizedProps=e.pendingProps,null===t?wl(e):Ac=t,Oc.current=null}function wl(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Gs(n,t)))return n.flags&=32767,void(Ac=n);if(null===e)return Lc=6,void(Ac=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=qs(n,t,Ic)))return void(Ac=n);if(null!==(t=t.sibling))return void(Ac=t);Ac=t=e}while(null!==t);0===Lc&&(Lc=5)}function _l(e,t,n){var r=yt,o=jc.transition;try{jc.transition=null,yt=1,function(e,t,n,r){do{xl()}while(null!==Gc);if(6&Pc)throw Error(a(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackPriority=0;var i=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-it(n),a=1<<o;t[o]=0,r[o]=-1,e[o]=-1,n&=~a}}(e,i),e===Cc&&(Ac=Cc=null,Tc=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||qc||(qc=!0,Cl(tt,(function(){return xl(),null}))),i=!!(15990&n.flags),!!(15990&n.subtreeFlags)||i){i=jc.transition,jc.transition=null;var s=yt;yt=1;var c=Pc;Pc|=4,Oc.current=null,function(e,t){if(eo=Vt,fr(e=dr())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var o=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch(_){n=null;break e}var s=0,c=-1,l=-1,u=0,p=0,d=e,f=null;t:for(;;){for(var m;d!==n||0!==o&&3!==d.nodeType||(c=s+o),d!==i||0!==r&&3!==d.nodeType||(l=s+r),3===d.nodeType&&(s+=d.nodeValue.length),null!==(m=d.firstChild);)f=d,d=m;for(;;){if(d===e)break t;if(f===n&&++u===o&&(c=s),f===i&&++p===r&&(l=s),null!==(m=d.nextSibling))break;f=(d=f).parentNode}d=m}n=-1===c||-1===l?null:{start:c,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Vt=!1,Xs=t;null!==Xs;)if(e=(t=Xs).child,1028&t.subtreeFlags&&null!==e)e.return=t,Xs=e;else for(;null!==Xs;){t=Xs;try{var h=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==h){var v=h.memoizedProps,g=h.memoizedState,b=t.stateNode,y=b.getSnapshotBeforeUpdate(t.elementType===t.type?v:ns(t.type,v),g);b.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;1===w.nodeType?w.textContent="":9===w.nodeType&&w.documentElement&&w.removeChild(w.documentElement);break;default:throw Error(a(163))}}catch(_){kl(t,t.return,_)}if(null!==(e=t.sibling)){e.return=t.return,Xs=e;break}Xs=t.return}h=tc,tc=!1}(e,n),vc(n,e),mr(to),Vt=!!eo,to=eo=null,e.current=n,bc(n,e,o),Ye(),Pc=c,yt=s,jc.transition=i}else e.current=n;if(qc&&(qc=!1,Gc=e,Kc=o),i=e.pendingLanes,0===i&&(Qc=null),function(e){if(at&&"function"==typeof at.onCommitFiberRoot)try{at.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),rl(e,Ze()),null!==t)for(r=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],r(o.value,{componentStack:o.stack,digest:o.digest});if(Vc)throw Vc=!1,e=Wc,Wc=null,e;!!(1&Kc)&&0!==e.tag&&xl(),i=e.pendingLanes,1&i?e===Zc?Yc++:(Yc=0,Zc=e):Yc=0,Ho()}(e,t,n,r)}finally{jc.transition=o,yt=r}return null}function xl(){if(null!==Gc){var e=wt(Kc),t=jc.transition,n=yt;try{if(jc.transition=null,yt=16>e?16:e,null===Gc)var r=!1;else{if(e=Gc,Gc=null,Kc=0,6&Pc)throw Error(a(331));var o=Pc;for(Pc|=4,Xs=e.current;null!==Xs;){var i=Xs,s=i.child;if(16&Xs.flags){var c=i.deletions;if(null!==c){for(var l=0;l<c.length;l++){var u=c[l];for(Xs=u;null!==Xs;){var p=Xs;switch(p.tag){case 0:case 11:case 15:nc(8,p,i)}var d=p.child;if(null!==d)d.return=p,Xs=d;else for(;null!==Xs;){var f=(p=Xs).sibling,m=p.return;if(ac(p),p===u){Xs=null;break}if(null!==f){f.return=m,Xs=f;break}Xs=m}}}var h=i.alternate;if(null!==h){var v=h.child;if(null!==v){h.child=null;do{var g=v.sibling;v.sibling=null,v=g}while(null!==v)}}Xs=i}}if(2064&i.subtreeFlags&&null!==s)s.return=i,Xs=s;else e:for(;null!==Xs;){if(2048&(i=Xs).flags)switch(i.tag){case 0:case 11:case 15:nc(9,i,i.return)}var b=i.sibling;if(null!==b){b.return=i.return,Xs=b;break e}Xs=i.return}}var y=e.current;for(Xs=y;null!==Xs;){var w=(s=Xs).child;if(2064&s.subtreeFlags&&null!==w)w.return=s,Xs=w;else e:for(s=y;null!==Xs;){if(2048&(c=Xs).flags)try{switch(c.tag){case 0:case 11:case 15:rc(9,c)}}catch(x){kl(c,c.return,x)}if(c===s){Xs=null;break e}var _=c.sibling;if(null!==_){_.return=c.return,Xs=_;break e}Xs=c.return}}if(Pc=o,Ho(),at&&"function"==typeof at.onPostCommitFiberRoot)try{at.onPostCommitFiberRoot(ot,e)}catch(x){}r=!0}return r}finally{yt=n,jc.transition=t}}return!1}function Sl(e,t,n){e=za(e,t=fs(0,t=ls(n,t),1),1),t=el(),null!==e&&(gt(e,1,t),rl(e,t))}function kl(e,t,n){if(3===e.tag)Sl(e,e,n);else for(;null!==t;){if(3===t.tag){Sl(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Qc||!Qc.has(r))){t=za(t,e=ms(t,e=ls(n,e),1),1),e=el(),null!==t&&(gt(t,1,e),rl(t,e));break}}t=t.return}}function El(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=el(),e.pingedLanes|=e.suspendedLanes&n,Cc===e&&(Tc&n)===n&&(4===Lc||3===Lc&&(130023424&Tc)===Tc&&500>Ze()-$c?dl(e,0):Mc|=n),rl(e,t)}function Ol(e,t){0===t&&(1&e.mode?(t=ut,!(130023424&(ut<<=1))&&(ut=4194304)):t=1);var n=el();null!==(e=Ra(e,t))&&(gt(e,t,n),rl(e,n))}function jl(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Ol(e,n)}function Pl(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(a(314))}null!==r&&r.delete(t),Ol(e,n)}function Cl(e,t){return qe(e,t)}function Al(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Tl(e,t,n,r){return new Al(e,t,n,r)}function Il(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Nl(e,t){var n=e.alternate;return null===n?((n=Tl(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ll(e,t,n,r,o,i){var s=2;if(r=e,"function"==typeof e)Il(e)&&(s=1);else if("string"==typeof e)s=5;else e:switch(e){case S:return Rl(n.children,o,i,t);case k:s=8,o|=8;break;case E:return(e=Tl(12,n,t,2|o)).elementType=E,e.lanes=i,e;case C:return(e=Tl(13,n,t,o)).elementType=C,e.lanes=i,e;case A:return(e=Tl(19,n,t,o)).elementType=A,e.lanes=i,e;case N:return Dl(n,o,i,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case O:s=10;break e;case j:s=9;break e;case P:s=11;break e;case T:s=14;break e;case I:s=16,r=null;break e}throw Error(a(130,null==e?e:typeof e,""))}return(t=Tl(s,n,t,o)).elementType=e,t.type=r,t.lanes=i,t}function Rl(e,t,n,r){return(e=Tl(7,e,r,t)).lanes=n,e}function Dl(e,t,n,r){return(e=Tl(22,e,r,t)).elementType=N,e.lanes=n,e.stateNode={isHidden:!1},e}function Fl(e,t,n){return(e=Tl(6,e,null,t)).lanes=n,e}function Ml(e,t,n){return(t=Tl(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Bl(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=vt(0),this.expirationTimes=vt(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=vt(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function zl(e,t,n,r,o,a,i,s,c){return e=new Bl(e,t,n,s,c),1===t?(t=1,!0===a&&(t|=8)):t=0,a=Tl(3,null,null,t),e.current=a,a.stateNode=e,a.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Fa(a),e}function $l(e){if(!e)return Po;e:{if(Ue(e=e._reactInternals)!==e||1!==e.tag)throw Error(a(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(No(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(a(171))}if(1===e.tag){var n=e.type;if(No(n))return Do(e,n,t)}return t}function Ul(e,t,n,r,o,a,i,s,c){return(e=zl(n,r,!0,e,0,a,0,s,c)).context=$l(null),n=e.current,(a=Ba(r=el(),o=tl(n))).callback=null!=t?t:null,za(n,a,o),e.current.lanes=o,gt(e,o,r),rl(e,r),e}function Hl(e,t,n,r){var o=t.current,a=el(),i=tl(o);return n=$l(n),null===t.context?t.context=n:t.pendingContext=n,(t=Ba(a,i)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),null!==(e=za(o,t,i))&&(nl(e,o,i,a),$a(e,o,i)),i}function Vl(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Wl(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Ql(e,t){Wl(e,t),(e=e.alternate)&&Wl(e,t)}Sc=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Ao.current)ys=!0;else{if(!(e.lanes&n||128&t.flags))return ys=!1,function(e,t,n){switch(t.tag){case 3:Cs(t),ma();break;case 5:Xa(t);break;case 1:No(t.type)&&Fo(t);break;case 4:Ya(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;jo(Sa,r._currentValue),r._currentValue=o;break;case 13:if(null!==(r=t.memoizedState))return null!==r.dehydrated?(jo(ei,1&ei.current),t.flags|=128,null):n&t.child.childLanes?Fs(e,t,n):(jo(ei,1&ei.current),null!==(e=Vs(e,t,n))?e.sibling:null);jo(ei,1&ei.current);break;case 19:if(r=!!(n&t.childLanes),128&e.flags){if(r)return Us(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),jo(ei,ei.current),r)break;return null;case 22:case 23:return t.lanes=0,ks(e,t,n)}return Vs(e,t,n)}(e,t,n);ys=!!(131072&e.flags)}else ys=!1,aa&&1048576&t.flags&&ea(t,qo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Hs(e,t),e=t.pendingProps;var o=Io(t,Co.current);Aa(t,n),o=vi(null,t,r,e,o,n);var i=gi();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,No(r)?(i=!0,Fo(t)):i=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Fa(t),o.updater=os,t.stateNode=o,o._reactInternals=t,cs(t,r,e,n),t=Ps(null,t,r,!0,i,n)):(t.tag=0,aa&&i&&ta(t),ws(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Hs(e,t),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Il(e)?1:0;if(null!=e){if((e=e.$$typeof)===P)return 11;if(e===T)return 14}return 2}(r),e=ns(r,e),o){case 0:t=Os(null,t,r,e,n);break e;case 1:t=js(null,t,r,e,n);break e;case 11:t=_s(null,t,r,e,n);break e;case 14:t=xs(null,t,r,ns(r.type,e),n);break e}throw Error(a(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,Os(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 1:return r=t.type,o=t.pendingProps,js(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 3:e:{if(Cs(t),null===e)throw Error(a(387));r=t.pendingProps,o=(i=t.memoizedState).element,Ma(e,t),Ha(t,r,null,n);var s=t.memoizedState;if(r=s.element,i.isDehydrated){if(i={element:r,isDehydrated:!1,cache:s.cache,pendingSuspenseBoundaries:s.pendingSuspenseBoundaries,transitions:s.transitions},t.updateQueue.baseState=i,t.memoizedState=i,256&t.flags){t=As(e,t,r,n,o=ls(Error(a(423)),t));break e}if(r!==o){t=As(e,t,r,n,o=ls(Error(a(424)),t));break e}for(oa=lo(t.stateNode.containerInfo.firstChild),ra=t,aa=!0,ia=null,n=xa(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(ma(),r===o){t=Vs(e,t,n);break e}ws(e,t,r,n)}t=t.child}return t;case 5:return Xa(t),null===e&&ua(t),r=t.type,o=t.pendingProps,i=null!==e?e.memoizedProps:null,s=o.children,no(r,o)?s=null:null!==i&&no(r,i)&&(t.flags|=32),Es(e,t),ws(e,t,s,n),t.child;case 6:return null===e&&ua(t),null;case 13:return Fs(e,t,n);case 4:return Ya(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=_a(t,null,r,n):ws(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,_s(e,t,r,o=t.elementType===r?o:ns(r,o),n);case 7:return ws(e,t,t.pendingProps,n),t.child;case 8:case 12:return ws(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,i=t.memoizedProps,s=o.value,jo(Sa,r._currentValue),r._currentValue=s,null!==i)if(sr(i.value,s)){if(i.children===o.children&&!Ao.current){t=Vs(e,t,n);break e}}else for(null!==(i=t.child)&&(i.return=t);null!==i;){var c=i.dependencies;if(null!==c){s=i.child;for(var l=c.firstContext;null!==l;){if(l.context===r){if(1===i.tag){(l=Ba(-1,n&-n)).tag=2;var u=i.updateQueue;if(null!==u){var p=(u=u.shared).pending;null===p?l.next=l:(l.next=p.next,p.next=l),u.pending=l}}i.lanes|=n,null!==(l=i.alternate)&&(l.lanes|=n),Ca(i.return,n,t),c.lanes|=n;break}l=l.next}}else if(10===i.tag)s=i.type===t.type?null:i.child;else if(18===i.tag){if(null===(s=i.return))throw Error(a(341));s.lanes|=n,null!==(c=s.alternate)&&(c.lanes|=n),Ca(s,n,t),s=i.sibling}else s=i.child;if(null!==s)s.return=i;else for(s=i;null!==s;){if(s===t){s=null;break}if(null!==(i=s.sibling)){i.return=s.return,s=i;break}s=s.return}i=s}ws(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Aa(t,n),r=r(o=Ta(o)),t.flags|=1,ws(e,t,r,n),t.child;case 14:return o=ns(r=t.type,t.pendingProps),xs(e,t,r,o=ns(r.type,o),n);case 15:return Ss(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:ns(r,o),Hs(e,t),t.tag=1,No(r)?(e=!0,Fo(t)):e=!1,Aa(t,n),is(t,r,o),cs(t,r,o,n),Ps(null,t,r,!0,e,n);case 19:return Us(e,t,n);case 22:return ks(e,t,n)}throw Error(a(156,t.tag))};var ql="function"==typeof reportError?reportError:function(e){console.error(e)};function Gl(e){this._internalRoot=e}function Kl(e){this._internalRoot=e}function Yl(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Zl(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Xl(){}function Jl(e,t,n,r,o){var a=n._reactRootContainer;if(a){var i=a;if("function"==typeof o){var s=o;o=function(){var e=Vl(i);s.call(e)}}Hl(t,i,e,o)}else i=function(e,t,n,r,o){if(o){if("function"==typeof r){var a=r;r=function(){var e=Vl(i);a.call(e)}}var i=Ul(t,r,e,0,null,!1,0,"",Xl);return e._reactRootContainer=i,e[ho]=i.current,Ur(8===e.nodeType?e.parentNode:e),ul(),i}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof r){var s=r;r=function(){var e=Vl(c);s.call(e)}}var c=zl(e,0,!1,null,0,!1,0,"",Xl);return e._reactRootContainer=c,e[ho]=c.current,Ur(8===e.nodeType?e.parentNode:e),ul((function(){Hl(t,c,n,r)})),c}(n,t,e,o,r);return Vl(i)}Kl.prototype.render=Gl.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(a(409));Hl(e,t,null,null)},Kl.prototype.unmount=Gl.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;ul((function(){Hl(null,e,null,null)})),t[ho]=null}},Kl.prototype.unstable_scheduleHydration=function(e){if(e){var t=kt();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Nt.length&&0!==t&&t<Nt[n].priority;n++);Nt.splice(n,0,e),0===n&&Ft(e)}},_t=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=pt(t.pendingLanes);0!==n&&(bt(t,1|n),rl(t,Ze()),!(6&Pc)&&(Uc=Ze()+500,Ho()))}break;case 13:ul((function(){var t=Ra(e,1);if(null!==t){var n=el();nl(t,e,1,n)}})),Ql(e,1)}},xt=function(e){if(13===e.tag){var t=Ra(e,134217728);if(null!==t)nl(t,e,134217728,el());Ql(e,134217728)}},St=function(e){if(13===e.tag){var t=tl(e),n=Ra(e,t);if(null!==n)nl(n,e,t,el());Ql(e,t)}},kt=function(){return yt},Et=function(e,t){var n=yt;try{return yt=e,t()}finally{yt=n}},xe=function(e,t,n){switch(t){case"input":if(X(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=xo(r);if(!o)throw Error(a(90));q(r),X(r,o)}}}break;case"textarea":ae(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Pe=ll,Ce=ul;var eu={usingClientEntryPoint:!1,Events:[wo,_o,xo,Oe,je,ll]},tu={findFiberByHostInstance:yo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},nu={bundleType:tu.bundleType,version:tu.version,rendererPackageName:tu.rendererPackageName,rendererConfig:tu.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:w.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=We(e))?null:e.stateNode},findFiberByHostInstance:tu.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ru=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ru.isDisabled&&ru.supportsFiber)try{ot=ru.inject(nu),at=ru}catch(ue){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=eu,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Yl(t))throw Error(a(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:x,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Yl(e))throw Error(a(299));var n=!1,r="",o=ql;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=zl(e,1,!1,null,0,n,0,r,o),e[ho]=t.current,Ur(8===e.nodeType?e.parentNode:e),new Gl(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(a(188));throw e=Object.keys(e).join(","),Error(a(268,e))}return e=null===(e=We(t))?null:e.stateNode},t.flushSync=function(e){return ul(e)},t.hydrate=function(e,t,n){if(!Zl(t))throw Error(a(200));return Jl(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Yl(e))throw Error(a(405));var r=null!=n&&n.hydratedSources||null,o=!1,i="",s=ql;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(i=n.identifierPrefix),void 0!==n.onRecoverableError&&(s=n.onRecoverableError)),t=Ul(t,null,e,1,null!=n?n:null,o,0,i,s),e[ho]=t.current,Ur(e),r)for(e=0;e<r.length;e++)o=(o=(n=r[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Kl(t)},t.render=function(e,t,n){if(!Zl(t))throw Error(a(200));return Jl(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Zl(e))throw Error(a(40));return!!e._reactRootContainer&&(ul((function(){Jl(null,null,e,!1,(function(){e._reactRootContainer=null,e[ho]=null}))})),!0)},t.unstable_batchedUpdates=ll,t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Zl(n))throw Error(a(200));if(null==e||void 0===e._reactInternals)throw Error(a(38));return Jl(e,t,n,!1,r)},t.version="18.3.1-next-f1338f8080-20240426"},5338:(e,t,n)=>{"use strict";var r=n(40961);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function a(e,i){if(e===i)return!0;if(e&&i&&"object"==typeof e&&"object"==typeof i){if(e.constructor!==i.constructor)return!1;var s,c,l,u;if(Array.isArray(e)){if((s=e.length)!=i.length)return!1;for(c=s;0!=c--;)if(!a(e[c],i[c]))return!1;return!0}if(n&&e instanceof Map&&i instanceof Map){if(e.size!==i.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!i.has(c.value[0]))return!1;for(u=e.entries();!(c=u.next()).done;)if(!a(c.value[1],i.get(c.value[0])))return!1;return!0}if(r&&e instanceof Set&&i instanceof Set){if(e.size!==i.size)return!1;for(u=e.entries();!(c=u.next()).done;)if(!i.has(c.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(i)){if((s=e.length)!=i.length)return!1;for(c=s;0!=c--;)if(e[c]!==i[c])return!1;return!0}if(e.constructor===RegExp)return e.source===i.source&&e.flags===i.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof i.valueOf)return e.valueOf()===i.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof i.toString)return e.toString()===i.toString();if((s=(l=Object.keys(e)).length)!==Object.keys(i).length)return!1;for(c=s;0!=c--;)if(!Object.prototype.hasOwnProperty.call(i,l[c]))return!1;if(t&&e instanceof Element)return!1;for(c=s;0!=c--;)if(("_owner"!==l[c]&&"__v"!==l[c]&&"__o"!==l[c]||!e.$$typeof)&&!a(e[l[c]],i[l[c]]))return!1;return!0}return e!=e&&i!=i}e.exports=function(e,t){try{return a(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>W});var r=n(96540),o=n(5556),a=n.n(o),i=n(30115),s=n.n(i),c=n(20311),l=n.n(c),u=n(2833),p=n.n(u);function d(){return d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},d.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,m(e,t)}function m(e,t){return m=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},m(e,t)}function h(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r<a.length;r++)t.indexOf(n=a[r])>=0||(o[n]=e[n]);return o}var v={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},g={rel:["amphtml","canonical","alternate"]},b={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(v).map((function(e){return v[e]})),_={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},x=Object.keys(_).reduce((function(e,t){return e[_[t]]=t,e}),{}),S=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},k=function(e){var t=S(e,v.TITLE),n=S(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=S(e,"defaultTitle");return t||r||void 0},E=function(e){return S(e,"onChangeClientState")||function(){}},O=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return d({},e,t)}),{})},j=function(e,t){return t.filter((function(e){return void 0!==e[v.BASE]})).map((function(e){return e[v.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var a=r[o].toLowerCase();if(-1!==e.indexOf(a)&&n[a])return t.concat(n)}return t}),[])},P=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,a=Object.keys(e),i=0;i<a.length;i+=1){var s=a[i],c=s.toLowerCase();-1===t.indexOf(c)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===c&&"stylesheet"===e[c].toLowerCase()||(n=c),-1===t.indexOf(s)||"innerHTML"!==s&&"cssText"!==s&&"itemprop"!==s||(n=s)}if(!n||!e[n])return!1;var l=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][l]&&(o[n][l]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var a=Object.keys(o),i=0;i<a.length;i+=1){var s=a[i],c=d({},r[s],o[s]);r[s]=c}return e}),[]).reverse()},C=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},A=function(e){return Array.isArray(e)?e.join(""):e},T=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},I=function(e,t){var n;return d({},e,((n={})[t]=void 0,n))},N=[v.NOSCRIPT,v.SCRIPT,v.STYLE],L=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},R=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[_[n]||n]=e[n],t}),t)},F=function(e,t){return t.map((function(t,n){var o,a=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=_[e]||e;"innerHTML"===n||"cssText"===n?a.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:a[n]=t[e]})),r.createElement(e,a)}))},M=function(e,t,n){switch(e){case v.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,a=D(n,o),[r.createElement(v.TITLE,a,e)];var e,n,o,a},toString:function(){return function(e,t,n,r){var o=R(n),a=A(t);return o?"<"+e+' data-rh="true" '+o+">"+L(a,r)+"</"+e+">":"<"+e+' data-rh="true">'+L(a,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return R(t)}};default:return{toComponent:function(){return F(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+L(r[t],n)+'"';return e?e+" "+o:o}),""),a=r.innerHTML||r.cssText||"",i=-1===N.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(i?"/>":">"+a+"</"+e+">")}),"")}(e,t,n)}}}},B=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,a=e.noscriptTags,i=e.styleTags,s=e.title,c=void 0===s?"":s,l=e.titleAttributes,u=e.linkTags,p=e.metaTags,d=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var m=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=T(e.metaTags,y),a=T(t,g),i=T(n,b);return{priorityMethods:{toComponent:function(){return[].concat(F(v.META,o.priority),F(v.LINK,a.priority),F(v.SCRIPT,i.priority))},toString:function(){return M(v.META,o.priority,r)+" "+M(v.LINK,a.priority,r)+" "+M(v.SCRIPT,i.priority,r)}},metaTags:o.default,linkTags:a.default,scriptTags:i.default}}(e);f=m.priorityMethods,u=m.linkTags,p=m.metaTags,d=m.scriptTags}return{priority:f,base:M(v.BASE,t,r),bodyAttributes:M("bodyAttributes",n,r),htmlAttributes:M("htmlAttributes",o,r),link:M(v.LINK,u,r),meta:M(v.META,p,r),noscript:M(v.NOSCRIPT,a,r),script:M(v.SCRIPT,d,r),style:M(v.STYLE,i,r),title:M(v.TITLE,{title:c,titleAttributes:l},r)}},z=[],$=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=B({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},U=r.createContext({}),H=a().shape({setHelmet:a().func,helmetInstances:a().shape({get:a().func,add:a().func,remove:a().func})}),V="undefined"!=typeof document,W=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new $(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement(U.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);W.canUseDOM=V,W.propTypes={context:a().shape({helmet:a().shape()}),children:a().node.isRequired},W.defaultProps={context:{}},W.displayName="HelmetProvider";var Q=function(e,t){var n,r=document.head||document.querySelector(v.HEAD),o=r.querySelectorAll(e+"[data-rh]"),a=[].slice.call(o),i=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),a.some((function(e,t){return n=t,r.isEqualNode(e)}))?a.splice(n,1):i.push(r)})),a.forEach((function(e){return e.parentNode.removeChild(e)})),i.forEach((function(e){return r.appendChild(e)})),{oldTags:a,newTags:i}},q=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],a=[].concat(o),i=Object.keys(t),s=0;s<i.length;s+=1){var c=i[s],l=t[c]||"";n.getAttribute(c)!==l&&n.setAttribute(c,l),-1===o.indexOf(c)&&o.push(c);var u=a.indexOf(c);-1!==u&&a.splice(u,1)}for(var p=a.length-1;p>=0;p-=1)n.removeAttribute(a[p]);o.length===a.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==i.join(",")&&n.setAttribute("data-rh",i.join(","))}},G=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,a=e.metaTags,i=e.noscriptTags,s=e.onChangeClientState,c=e.scriptTags,l=e.styleTags,u=e.title,p=e.titleAttributes;q(v.BODY,e.bodyAttributes),q(v.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=A(e)),q(v.TITLE,t)}(u,p);var d={baseTag:Q(v.BASE,n),linkTags:Q(v.LINK,o),metaTags:Q(v.META,a),noscriptTags:Q(v.NOSCRIPT,i),scriptTags:Q(v.SCRIPT,c),styleTags:Q(v.STYLE,l)},f={},m={};Object.keys(d).forEach((function(e){var t=d[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(m[e]=d[e].oldTags)})),t&&t(),s(e,f,m)},K=null,Y=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!p()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,a=(e=n.helmetInstances.get().map((function(e){var t=d({},e.props);return delete t.context,t})),{baseTag:j(["href"],e),bodyAttributes:O("bodyAttributes",e),defer:S(e,"defer"),encode:S(e,"encodeSpecialCharacters"),htmlAttributes:O("htmlAttributes",e),linkTags:P(v.LINK,["rel","href"],e),metaTags:P(v.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:P(v.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:P(v.SCRIPT,["src","innerHTML"],e),styleTags:P(v.STYLE,["cssText"],e),title:k(e),titleAttributes:O("titleAttributes",e),prioritizeSeoTags:C(e,"prioritizeSeoTags")});W.canUseDOM?(t=a,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){G(t,(function(){K=null}))})):(G(t),K=null)):B&&(o=B(a)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Y.propTypes={context:H.isRequired},Y.displayName="HelmetDispatcher";var Z=["children"],X=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!s()(I(this.props,"helmetData"),I(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case v.SCRIPT:case v.NOSCRIPT:return{innerHTML:t};case v.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return d({},r,((t={})[n.type]=[].concat(r[n.type]||[],[d({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,a=e.newChildProps,i=e.nestedChildren;switch(r.type){case v.TITLE:return d({},o,((t={})[r.type]=i,t.titleAttributes=d({},a),t));case v.BODY:return d({},o,{bodyAttributes:d({},a)});case v.HTML:return d({},o,{htmlAttributes:d({},a)});default:return d({},o,((n={})[r.type]=d({},a),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=d({},t);return Object.keys(e).forEach((function(t){var r;n=d({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return l()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),l()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,a=r.children,i=h(r,Z),s=Object.keys(i).reduce((function(e,t){return e[x[t]||t]=i[t],e}),{}),c=e.type;switch("symbol"==typeof c?c=c.toString():n.warnOnInvalidChildren(e,a),c){case v.FRAGMENT:t=n.mapChildrenToProps(a,t);break;case v.LINK:case v.META:case v.NOSCRIPT:case v.SCRIPT:case v.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:s,nestedChildren:a});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:s,nestedChildren:a})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=h(e,X),o=d({},n),a=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!a||a instanceof $||(a=new $(a.context,a.instances)),a?r.createElement(Y,d({},o,{context:a.value,helmetData:void 0})):r.createElement(U.Consumer,null,(function(e){return r.createElement(Y,d({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:a().object,bodyAttributes:a().object,children:a().oneOfType([a().arrayOf(a().node),a().node]),defaultTitle:a().string,defer:a().bool,encodeSpecialCharacters:a().bool,htmlAttributes:a().object,link:a().arrayOf(a().object),meta:a().arrayOf(a().object),noscript:a().arrayOf(a().object),onChangeClientState:a().func,script:a().arrayOf(a().object),style:a().arrayOf(a().object),title:a().string,titleAttributes:a().object,titleTemplate:a().string,prioritizeSeoTags:a().bool,helmetData:a().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,a=n?Symbol.for("react.fragment"):60107,i=n?Symbol.for("react.strict_mode"):60108,s=n?Symbol.for("react.profiler"):60114,c=n?Symbol.for("react.provider"):60109,l=n?Symbol.for("react.context"):60110,u=n?Symbol.for("react.async_mode"):60111,p=n?Symbol.for("react.concurrent_mode"):60111,d=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,m=n?Symbol.for("react.suspense_list"):60120,h=n?Symbol.for("react.memo"):60115,v=n?Symbol.for("react.lazy"):60116,g=n?Symbol.for("react.block"):60121,b=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case u:case p:case a:case s:case i:case f:return e;default:switch(e=e&&e.$$typeof){case l:case d:case v:case h:case c:return e;default:return t}}case o:return t}}}function x(e){return _(e)===p}t.AsyncMode=u,t.ConcurrentMode=p,t.ContextConsumer=l,t.ContextProvider=c,t.Element=r,t.ForwardRef=d,t.Fragment=a,t.Lazy=v,t.Memo=h,t.Portal=o,t.Profiler=s,t.StrictMode=i,t.Suspense=f,t.isAsyncMode=function(e){return x(e)||_(e)===u},t.isConcurrentMode=x,t.isContextConsumer=function(e){return _(e)===l},t.isContextProvider=function(e){return _(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return _(e)===d},t.isFragment=function(e){return _(e)===a},t.isLazy=function(e){return _(e)===v},t.isMemo=function(e){return _(e)===h},t.isPortal=function(e){return _(e)===o},t.isProfiler=function(e){return _(e)===s},t.isStrictMode=function(e){return _(e)===i},t.isSuspense=function(e){return _(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===a||e===p||e===s||e===i||e===f||e===m||"object"==typeof e&&null!==e&&(e.$$typeof===v||e.$$typeof===h||e.$$typeof===c||e.$$typeof===l||e.$$typeof===d||e.$$typeof===b||e.$$typeof===y||e.$$typeof===w||e.$$typeof===g)},t.typeOf=_},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},53259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},i.apply(this,arguments)}var s=n(96540),c=[],l=[];var u=s.createContext(null);function p(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function d(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=p(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return s.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function m(e,t){var p,d;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var m=i({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),h=null;function v(){return h||(h=e(m.loader)),h.promise}return c.push(v),"function"==typeof m.webpack&&l.push((function(){if((0,m.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return v()})),d=p=function(t){function n(n){var r;return a(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),h=e(m.loader),r._loadModule()})),v(),r.state={error:h.error,pastDelay:!1,timedOut:!1,loading:h.loading,loaded:h.loaded},r}r(n,t),n.preload=function(){return v()};var i=n.prototype;return i.UNSAFE_componentWillMount=function(){this._loadModule()},i.componentDidMount=function(){this._mounted=!0},i._loadModule=function(){var e=this;if(this.context&&Array.isArray(m.modules)&&m.modules.forEach((function(t){e.context.report(t)})),h.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof m.delay&&(0===m.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),m.delay)),"number"==typeof m.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),m.timeout));var n=function(){t({error:h.error,loaded:h.loaded,loading:h.loading}),e._clearTimeouts()};h.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},i.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},i._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},i.render=function(){return this.state.loading||this.state.error?s.createElement(m.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?m.render(this.state.loaded,this.props):null},n}(s.Component),a(p,"contextType",u),d}function h(e){return m(p,e)}h.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return m(d,e)};var v=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return s.createElement(u.Provider,{value:{report:this.props.report}},s.Children.only(this.props.children))},t}(s.Component);function g(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return g(e)}))}h.Capture=v,h.preloadAll=function(){return new Promise((function(e,t){g(c).then(e,t)}))},h.preloadReady=function(){return new Promise((function(e,t){g(l).then(e,e)}))},e.exports=h},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>i,v:()=>s});var r=n(56347),o=n(58168),a=n(96540);function i(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&i(e.routes,t,n)),o})),n}function s(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?a.createElement(r.dO,n,e.map((function(e,n){return a.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):a.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})}))):null}},54625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>p,Kd:()=>u,N_:()=>g,k2:()=>w});var r=n(56347),o=n(42892),a=n(96540),i=n(31513),s=n(58168),c=n(98587),l=n(11561),u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return a.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(a.Component);var p=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,i.TM)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return a.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(a.Component);var d=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,i.yJ)(e,null,null,t):e},m=function(e){return e},h=a.forwardRef;void 0===h&&(h=m);var v=h((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,i=(0,c.A)(e,["innerRef","navigate","onClick"]),l=i.target,u=(0,s.A)({},i,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||l&&"_self"!==l||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return u.ref=m!==h&&t||n,a.createElement("a",u)}));var g=h((function(e,t){var n=e.component,o=void 0===n?v:n,u=e.replace,p=e.to,g=e.innerRef,b=(0,c.A)(e,["component","replace","to","innerRef"]);return a.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=e.history,r=f(d(p,e.location),e.location),c=r?n.createHref(r):"",v=(0,s.A)({},b,{href:c,navigate:function(){var t=d(p,e.location),r=(0,i.AO)(e.location)===(0,i.AO)(f(t));(u||r?n.replace:n.push)(t)}});return m!==h?v.ref=t||g:v.innerRef=g,a.createElement(o,v)}))})),b=function(e){return e},y=a.forwardRef;void 0===y&&(y=b);var w=y((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,i=e.activeClassName,u=void 0===i?"active":i,p=e.activeStyle,m=e.className,h=e.exact,v=e.isActive,w=e.location,_=e.sensitive,x=e.strict,S=e.style,k=e.to,E=e.innerRef,O=(0,c.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return a.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=w||e.location,i=f(d(k,n),n),c=i.pathname,j=c&&c.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),P=j?(0,r.B6)(n.pathname,{path:j,exact:h,sensitive:_,strict:x}):null,C=!!(v?v(P,n):P),A="function"==typeof m?m(C):m,T="function"==typeof S?S(C):S;C&&(A=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(A,u),T=(0,s.A)({},T,p));var I=(0,s.A)({"aria-current":C&&o||null,className:A,style:T,to:i},O);return b!==y?I.ref=t||E:I.innerRef=E,a.createElement(g,I)}))}))},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>S,Ix:()=>y,W6:()=>I,XZ:()=>b,dO:()=>A,qh:()=>k,zy:()=>N});var r=n(42892),o=n(96540),a=n(5556),i=n.n(a),s=n(31513),c=n(11561),l=n(58168),u=n(8505),p=n.n(u),d=(n(44363),n(98587)),f=(n(4146),1073741823),m="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var h=o.createContext||function(e,t){var n,a,s="__create-react-context-"+function(){var e="__global_unique_id__";return m[e]=(m[e]||0)+1}()+"__",c=function(e){function n(){for(var t,n,r,o=arguments.length,a=new Array(o),i=0;i<o;i++)a[i]=arguments[i];return(t=e.call.apply(e,[this].concat(a))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[s]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((a=r)===(i=o)?0!==a||1/a==1/i:a!=a&&i!=i)?n=0:(n="function"==typeof t?t(r,o):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var a,i},o.render=function(){return this.props.children},n}(o.Component);c.childContextTypes=((n={})[s]=i().object.isRequired,n);var l=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){(0|e.observedBits)&n&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},o.componentDidMount=function(){this.context[s]&&this.context[s].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},o.componentWillUnmount=function(){this.context[s]&&this.context[s].off(this.onUpdate)},o.getValue=function(){return this.context[s]?this.context[s].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return l.contextTypes=((a={})[s]=i().object,a),{Provider:c,Consumer:l}},v=function(e){var t=h();return t.displayName=e,t},g=v("Router-History"),b=v("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(b.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(g.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var w={},_=1e4,x=0;function S(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,a=void 0!==o&&o,i=n.strict,s=void 0!==i&&i,c=n.sensitive,l=void 0!==c&&c;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var o=[],a={regexp:p()(e,o,t),keys:o};return x<_&&(r[e]=a,x++),a}(n,{end:a,strict:s,sensitive:l}),o=r.regexp,i=r.keys,c=o.exec(e);if(!c)return null;var u=c[0],d=c.slice(1),f=e===u;return a&&!f?null:{path:n,url:"/"===n&&""===u?"/":u,isExact:f,params:i.reduce((function(e,t,n){return e[t.name]=d[n],e}),{})}}),null)}var k=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(b.Consumer,null,(function(t){t||(0,c.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?S(n.pathname,e.props):t.match,a=(0,l.A)({},t,{location:n,match:r}),i=e.props,s=i.children,u=i.component,p=i.render;return Array.isArray(s)&&function(e){return 0===o.Children.count(e)}(s)&&(s=null),o.createElement(b.Provider,{value:a},a.match?s?"function"==typeof s?s(a):s:u?o.createElement(u,a):p?p(a):null:"function"==typeof s?s(a):null)}))},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function O(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,l.A)({},t,{pathname:t.pathname.substr(n.length)})}function j(e){return"string"==typeof e?e:(0,s.AO)(e)}function P(e){return function(){(0,c.A)(!1)}}function C(){}o.Component;var A=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(b.Consumer,null,(function(t){t||(0,c.A)(!1);var n,r,a=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var i=e.props.path||e.props.from;r=i?S(a.pathname,(0,l.A)({},e.props,{path:i})):t.match}})),r?o.cloneElement(n,{location:a,computedMatch:r}):null}))},t}(o.Component);var T=o.useContext;function I(){return T(g)}function N(){return T(b).location}},8505:(e,t,n)=>{var r=n(64634);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return s(a(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=d;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var p=n[0],d=n[1],f=n.index;if(s+=e.slice(i,f),i=f+p.length,d)s+=d[1];else{var m=e[i],h=n[2],v=n[3],g=n[4],b=n[5],y=n[6],w=n[7];s&&(r.push(s),s="");var _=null!=h&&null!=m&&m!==h,x="+"===y||"*"===y,S="?"===y||"*"===y,k=n[2]||u,E=g||b;r.push({name:v||a++,prefix:h||"",delimiter:k,optional:S,repeat:x,partial:_,asterisk:!!w,pattern:E?l(E):w?".*":"[^"+c(k)+"]+?"})}}return i<e.length&&(s+=e.substr(i)),s&&r.push(s),r}function i(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function s(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",p(t)));return function(t,o){for(var a="",s=t||{},c=(o||{}).pretty?i:encodeURIComponent,l=0;l<e.length;l++){var u=e[l];if("string"!=typeof u){var p,d=s[u.name];if(null==d){if(u.optional){u.partial&&(a+=u.prefix);continue}throw new TypeError('Expected "'+u.name+'" to be defined')}if(r(d)){if(!u.repeat)throw new TypeError('Expected "'+u.name+'" to not repeat, but received `'+JSON.stringify(d)+"`");if(0===d.length){if(u.optional)continue;throw new TypeError('Expected "'+u.name+'" to not be empty')}for(var f=0;f<d.length;f++){if(p=c(d[f]),!n[l].test(p))throw new TypeError('Expected all "'+u.name+'" to match "'+u.pattern+'", but received `'+JSON.stringify(p)+"`");a+=(0===f?u.prefix:u.delimiter)+p}}else{if(p=u.asterisk?encodeURI(d).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):c(d),!n[l].test(p))throw new TypeError('Expected "'+u.name+'" to match "'+u.pattern+'", but received "'+p+'"');a+=u.prefix+p}}else a+=u}return a}}function c(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function l(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function u(e,t){return e.keys=t,e}function p(e){return e&&e.sensitive?"":"i"}function d(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,a=!1!==n.end,i="",s=0;s<e.length;s++){var l=e[s];if("string"==typeof l)i+=c(l);else{var d=c(l.prefix),f="(?:"+l.pattern+")";t.push(l),l.repeat&&(f+="(?:"+d+f+")*"),i+=f=l.optional?l.partial?d+"("+f+")?":"(?:"+d+"("+f+"))?":d+"("+f+")"}}var m=c(n.delimiter||"/"),h=i.slice(-m.length)===m;return o||(i=(h?i.slice(0,-m.length):i)+"(?:"+m+"(?=$))?"),i+=a?"$":o&&h?"":"(?="+m+"|$)",u(new RegExp("^"+i,p(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return u(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(f(e[o],t,n).source);return u(new RegExp("(?:"+r.join("|")+")",p(n)),t)}(e,t,n):function(e,t,n){return d(a(e,n),t,n)}(e,t,n)}},21020:(e,t,n)=>{"use strict";var r=n(96540),o=Symbol.for("react.element"),a=Symbol.for("react.fragment"),i=Object.prototype.hasOwnProperty,s=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function l(e,t,n){var r,a={},l=null,u=null;for(r in void 0!==n&&(l=""+n),void 0!==t.key&&(l=""+t.key),void 0!==t.ref&&(u=t.ref),t)i.call(t,r)&&!c.hasOwnProperty(r)&&(a[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===a[r]&&(a[r]=t[r]);return{$$typeof:o,type:e,key:l,ref:u,props:a,_owner:s.current}}t.Fragment=a,t.jsx=l,t.jsxs=l},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),a=Symbol.for("react.strict_mode"),i=Symbol.for("react.profiler"),s=Symbol.for("react.provider"),c=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),u=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),d=Symbol.for("react.lazy"),f=Symbol.iterator;var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h=Object.assign,v={};function g(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||m}function b(){}function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||m}g.prototype.isReactComponent={},g.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},b.prototype=g.prototype;var w=y.prototype=new b;w.constructor=y,h(w,g.prototype),w.isPureReactComponent=!0;var _=Array.isArray,x=Object.prototype.hasOwnProperty,S={current:null},k={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,r){var o,a={},i=null,s=null;if(null!=t)for(o in void 0!==t.ref&&(s=t.ref),void 0!==t.key&&(i=""+t.key),t)x.call(t,o)&&!k.hasOwnProperty(o)&&(a[o]=t[o]);var c=arguments.length-2;if(1===c)a.children=r;else if(1<c){for(var l=Array(c),u=0;u<c;u++)l[u]=arguments[u+2];a.children=l}if(e&&e.defaultProps)for(o in c=e.defaultProps)void 0===a[o]&&(a[o]=c[o]);return{$$typeof:n,type:e,key:i,ref:s,props:a,_owner:S.current}}function O(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var j=/\/+/g;function P(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function C(e,t,o,a,i){var s=typeof e;"undefined"!==s&&"boolean"!==s||(e=null);var c=!1;if(null===e)c=!0;else switch(s){case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case r:c=!0}}if(c)return i=i(c=e),e=""===a?"."+P(c,0):a,_(i)?(o="",null!=e&&(o=e.replace(j,"$&/")+"/"),C(i,t,o,"",(function(e){return e}))):null!=i&&(O(i)&&(i=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(i,o+(!i.key||c&&c.key===i.key?"":(""+i.key).replace(j,"$&/")+"/")+e)),t.push(i)),1;if(c=0,a=""===a?".":a+":",_(e))for(var l=0;l<e.length;l++){var u=a+P(s=e[l],l);c+=C(s,t,o,u,i)}else if(u=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof u)for(e=u.call(e),l=0;!(s=e.next()).done;)c+=C(s=s.value,t,o,u=a+P(s,l++),i);else if("object"===s)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return c}function A(e,t,n){if(null==e)return e;var r=[],o=0;return C(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function T(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var I={current:null},N={transition:null},L={ReactCurrentDispatcher:I,ReactCurrentBatchConfig:N,ReactCurrentOwner:S};function R(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:A,forEach:function(e,t,n){A(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return A(e,(function(){t++})),t},toArray:function(e){return A(e,(function(e){return e}))||[]},only:function(e){if(!O(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=g,t.Fragment=o,t.Profiler=i,t.PureComponent=y,t.StrictMode=a,t.Suspense=u,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=L,t.act=R,t.cloneElement=function(e,t,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=h({},e.props),a=e.key,i=e.ref,s=e._owner;if(null!=t){if(void 0!==t.ref&&(i=t.ref,s=S.current),void 0!==t.key&&(a=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(l in t)x.call(t,l)&&!k.hasOwnProperty(l)&&(o[l]=void 0===t[l]&&void 0!==c?c[l]:t[l])}var l=arguments.length-2;if(1===l)o.children=r;else if(1<l){c=Array(l);for(var u=0;u<l;u++)c[u]=arguments[u+2];o.children=c}return{$$typeof:n,type:e.type,key:a,ref:i,props:o,_owner:s}},t.createContext=function(e){return(e={$$typeof:c,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:s,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:l,render:e}},t.isValidElement=O,t.lazy=function(e){return{$$typeof:d,_payload:{_status:-1,_result:e},_init:T}},t.memo=function(e,t){return{$$typeof:p,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=N.transition;N.transition={};try{e()}finally{N.transition=t}},t.unstable_act=R,t.useCallback=function(e,t){return I.current.useCallback(e,t)},t.useContext=function(e){return I.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return I.current.useDeferredValue(e)},t.useEffect=function(e,t){return I.current.useEffect(e,t)},t.useId=function(){return I.current.useId()},t.useImperativeHandle=function(e,t,n){return I.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return I.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return I.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return I.current.useMemo(e,t)},t.useReducer=function(e,t,n){return I.current.useReducer(e,t,n)},t.useRef=function(e){return I.current.useRef(e)},t.useState=function(e){return I.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return I.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return I.current.useTransition()},t.version="18.3.1"},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,o=e[r];if(!(0<a(o,t)))break e;e[r]=t,e[n]=o,n=r}}function r(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length,i=o>>>1;r<i;){var s=2*(r+1)-1,c=e[s],l=s+1,u=e[l];if(0>a(c,n))l<o&&0>a(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else{if(!(l<o&&0>a(u,n)))break e;e[r]=u,e[l]=n,r=l}}}return t}function a(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var i=performance;t.unstable_now=function(){return i.now()}}else{var s=Date,c=s.now();t.unstable_now=function(){return s.now()-c}}var l=[],u=[],p=1,d=null,f=3,m=!1,h=!1,v=!1,g="function"==typeof setTimeout?setTimeout:null,b="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function w(e){for(var t=r(u);null!==t;){if(null===t.callback)o(u);else{if(!(t.startTime<=e))break;o(u),t.sortIndex=t.expirationTime,n(l,t)}t=r(u)}}function _(e){if(v=!1,w(e),!h)if(null!==r(l))h=!0,N(x);else{var t=r(u);null!==t&&L(_,t.startTime-e)}}function x(e,n){h=!1,v&&(v=!1,b(O),O=-1),m=!0;var a=f;try{for(w(n),d=r(l);null!==d&&(!(d.expirationTime>n)||e&&!C());){var i=d.callback;if("function"==typeof i){d.callback=null,f=d.priorityLevel;var s=i(d.expirationTime<=n);n=t.unstable_now(),"function"==typeof s?d.callback=s:d===r(l)&&o(l),w(n)}else o(l);d=r(l)}if(null!==d)var c=!0;else{var p=r(u);null!==p&&L(_,p.startTime-n),c=!1}return c}finally{d=null,f=a,m=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var S,k=!1,E=null,O=-1,j=5,P=-1;function C(){return!(t.unstable_now()-P<j)}function A(){if(null!==E){var e=t.unstable_now();P=e;var n=!0;try{n=E(!0,e)}finally{n?S():(k=!1,E=null)}}else k=!1}if("function"==typeof y)S=function(){y(A)};else if("undefined"!=typeof MessageChannel){var T=new MessageChannel,I=T.port2;T.port1.onmessage=A,S=function(){I.postMessage(null)}}else S=function(){g(A,0)};function N(e){E=e,k||(k=!0,S())}function L(e,n){O=g((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){h||m||(h=!0,N(x))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):j=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return r(l)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,o,a){var i=t.unstable_now();switch("object"==typeof a&&null!==a?a="number"==typeof(a=a.delay)&&0<a?i+a:i:a=i,e){case 1:var s=-1;break;case 2:s=250;break;case 5:s=1073741823;break;case 4:s=1e4;break;default:s=5e3}return e={id:p++,callback:o,priorityLevel:e,startTime:a,expirationTime:s=a+s,sortIndex:-1},a>i?(e.sortIndex=a,n(u,e),null===r(l)&&e===r(u)&&(v?(b(O),O=-1):v=!0,L(_,a-i))):(e.sortIndex=s,n(l,e),h||m||(h=!0,N(x))),e},t.unstable_shouldYield=C,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},2833:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var a=Object.keys(e),i=Object.keys(t);if(a.length!==i.length)return!1;for(var s=Object.prototype.hasOwnProperty.bind(t),c=0;c<a.length;c++){var l=a[c];if(!s(l))return!1;var u=e[l],p=t[l];if(!1===(o=n?n.call(r,u,p,l):void 0)||void 0===o&&u!==p)return!1}return!0}},4784:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r={title:"Contrast",tagline:"Contrast: Confidential Containers at scale",url:"https://docs.edgeless.systems",baseUrl:"/contrast/pr-preview/pr-976/",trailingSlash:!1,onBrokenLinks:"throw",onBrokenMarkdownLinks:"throw",onBrokenAnchors:"throw",favicon:"img/favicon.ico",organizationName:"edgelesssys",projectName:"contrast",deploymentBranch:"gh-pages",scripts:[{id:"Cookiebot",src:"https://consent.cookiebot.com/uc.js","data-cbid":"a0cc864f-0b67-49be-8d65-9ed354de2ee6","data-blockingmode":"auto"},{id:"CookieDeclaration",src:"https://consent.cookiebot.com/a0cc864f-0b67-49be-8d65-9ed354de2ee6/cd.js"}],i18n:{defaultLocale:"en",locales:["en"],path:"i18n",localeConfigs:{}},markdown:{mermaid:!0,format:"mdx",mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}},themes:["@docusaurus/theme-mermaid"],presets:[["classic",{docs:{sidebarPath:"/build/docs/sidebars.js",editUrl:"https://github.com/edgelesssys/contrast/edit/main/docs",routeBasePath:"/"},blog:!1,theme:{customCss:"/build/docs/src/css/custom.css"},gtag:{trackingID:"G-3DVYB2CHLG",anonymizeIP:!0}}]],themeConfig:{navbar:{hideOnScroll:!1,logo:{alt:"Contrast Logo",src:"img/logos/contrast_icon.svg"},items:[{type:"docsVersionDropdown",position:"right",dropdownItemsBefore:[],dropdownItemsAfter:[]},{href:"https://github.com/edgelesssys/contrast",position:"right",className:"header-github-link"}]},colorMode:{defaultMode:"light",disableSwitch:!0,respectPrefersColorScheme:!1},announcementBar:{content:'Contrast is now open source! Check it out on <a target="_blank" rel="noopener noreferrer" href="https://github.com/edgelesssys/contrast">GitHub</a> and leave us a \u2b50\ufe0f if you like it!',backgroundColor:"#E7E6E6",id:"announcement-bar",isCloseable:!0},footer:{style:"dark",links:[{title:"Community",items:[{label:"Newsletter",href:"https://www.edgeless.systems/#footer-id"}]},{title:"Social",items:[{label:"Blog",href:"https://www.edgeless.systems/blog/"},{label:"Twitter",href:"https://twitter.com/EdgelessSystems"},{label:"LinkedIn",href:"https://www.linkedin.com/company/edgeless-systems/"},{label:"Youtube",href:"https://www.youtube.com/channel/UCOOInN0sCv6icUesisYIDeA"}]},{title:"Company",items:[{label:"Imprint",href:"https://www.edgeless.systems/imprint/"},{label:"Privacy Policy",href:"https://www.edgeless.systems/privacy/"},{html:'<a href="javascript: Cookiebot.renew()" class="footer__link-item">Cookie Settings</a>'},{label:"Contact Us",href:"https://www.edgeless.systems/contact-us/"}]}],copyright:"Copyright \xa9 2024 Edgeless Systems"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:["shell-session","bash","json","diff"],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},mermaid:{theme:{light:"base",dark:"base"},options:{themeVariables:{fontFamily:'"Open Sans", sans-serif',primaryColor:"#90FF99",primaryTextColor:"#000000",secondaryColor:"#A5A5A5",secondaryTextColor:"#000000",tertiaryColor:"#E7E6E6",tertiaryTextColor:"#000000",clusterBorder:"#A5A5A5",clusterBkg:"#ffffff",edgeLabelBackground:"#ffffff",activationBorderColor:"#000000",actorBorder:"#A5A5A5",actorFontFamily:'"Open Sans", sans-serif',noteBkgColor:"#8B04DD",noteTextColor:"#ffffff"},startOnLoad:!0}},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},plugins:[["/build/docs/node_modules/@cmfcmf/docusaurus-search-local/lib/server/index.js",{indexDocs:!0,indexDocSidebarParentCategories:0,indexBlog:!1,indexPages:!1,language:"en",maxSearchResults:8,lunr:{tokenizerSeparator:{},b:.75,k1:1.2,titleBoost:5,contentBoost:1,tagsBoost:3,parentCategoriesBoost:2}}]],baseUrlIssueBanner:!0,future:{experimental_faster:{swcJsLoader:!1,swcJsMinimizer:!1,swcHtmlMinimizer:!1,lightningCssMinimizer:!1,mdxCrossCompilerCache:!1,rspackBundler:!1},experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},onDuplicateRoutes:"warn",staticDirectories:["static"],customFields:{},headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},58168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},42892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>o})},98587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.includes(r))continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})},34164:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var a=e.length;for(t=0;t<a;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",a=arguments.length;n<a;n++)(e=arguments[n])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},71765:(e,t,n)=>{"use strict";n.d(t,{My:()=>j,f4:()=>ee});var r,o,a,i,s,c,l,u=n(96540),p=n(34164),d=Object.create,f=Object.defineProperty,m=Object.defineProperties,h=Object.getOwnPropertyDescriptor,v=Object.getOwnPropertyDescriptors,g=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable,x=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,S=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&x(e,n,t[n]);if(b)for(var n of b(t))_.call(t,n)&&x(e,n,t[n]);return e},k=(e,t)=>m(e,v(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&b)for(var r of b(e))t.indexOf(r)<0&&_.call(e,r)&&(n[r]=e[r]);return n},O=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,a;switch(n=n||{},r.util.type(t)){case"Object":if(a=r.util.objId(t),n[a])return n[a];for(var i in o={},n[a]=o,t)t.hasOwnProperty(i)&&(o[i]=e(t[i],n));return o;case"Array":return a=r.util.objId(t),n[a]?n[a]:(o=[],n[a]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var a=(o=o||r.languages)[e],i={};for(var s in a)if(a.hasOwnProperty(s)){if(s==t)for(var c in n)n.hasOwnProperty(c)&&(i[c]=n[c]);n.hasOwnProperty(s)||(i[s]=a[s])}var l=o[e];return o[e]=i,r.languages.DFS(r.languages,(function(t,n){n===l&&t!=e&&(this[t]=i)})),i},DFS:function e(t,n,o,a){a=a||{};var i=r.util.objId;for(var s in t)if(t.hasOwnProperty(s)){n.call(t,s,t[s],o||s);var c=t[s],l=r.util.type(c);"Object"!==l||a[i(c)]?"Array"!==l||a[i(c)]||(a[i(c)]=!0,e(c,n,s,a)):(a[i(c)]=!0,e(c,n,null,a))}}},plugins:{},highlight:function(e,t,n){var a={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",a),!a.grammar)throw new Error('The language "'+a.language+'" has no grammar.');return a.tokens=r.tokenize(a.code,a.grammar),r.hooks.run("after-tokenize",a),o.stringify(r.util.encode(a.tokens),a.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new s;return c(o,o.head,e),i(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,a=0;o=n[a++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function a(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var a=o[1].length;o.index+=a,o[0]=o[0].slice(a)}return o}function i(e,t,n,s,u,p){for(var d in n)if(n.hasOwnProperty(d)&&n[d]){var f=n[d];f=Array.isArray(f)?f:[f];for(var m=0;m<f.length;++m){if(p&&p.cause==d+","+m)return;var h=f[m],v=h.inside,g=!!h.lookbehind,b=!!h.greedy,y=h.alias;if(b&&!h.pattern.global){var w=h.pattern.toString().match(/[imsuy]*$/)[0];h.pattern=RegExp(h.pattern.source,w+"g")}for(var _=h.pattern||h,x=s.next,S=u;x!==t.tail&&!(p&&S>=p.reach);S+=x.value.length,x=x.next){var k=x.value;if(t.length>e.length)return;if(!(k instanceof o)){var E,O=1;if(b){if(!(E=a(_,S,e,g))||E.index>=e.length)break;var j=E.index,P=E.index+E[0].length,C=S;for(C+=x.value.length;j>=C;)C+=(x=x.next).value.length;if(S=C-=x.value.length,x.value instanceof o)continue;for(var A=x;A!==t.tail&&(C<P||"string"==typeof A.value);A=A.next)O++,C+=A.value.length;O--,k=e.slice(S,C),E.index-=S}else if(!(E=a(_,0,k,g)))continue;j=E.index;var T=E[0],I=k.slice(0,j),N=k.slice(j+T.length),L=S+k.length;p&&L>p.reach&&(p.reach=L);var R=x.prev;if(I&&(R=c(t,R,I),S+=I.length),l(t,R,O),x=c(t,R,new o(d,v?r.tokenize(T,v):T,y,T)),N&&c(t,x,N),O>1){var D={cause:d+","+m,reach:L};i(e,t,n,x.prev,S,D),p&&D.reach>p.reach&&(p.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function l(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var a={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},i=t.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),r.hooks.run("wrap",a);var s="";for(var c in a.attributes)s+=" "+c+'="'+(a.attributes[c]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+s+">"+a.content+"</"+a.tag+">"},r}();t.exports=n,n.default=n}},function(){return o||(0,r[g(r)[0]])((o={exports:{}}).exports,o),o.exports}),j=((e,t,n)=>(n=null!=e?d(y(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of g(t))w.call(e,o)||o===n||f(e,o,{get:()=>t[o],enumerable:!(r=h(t,o))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(O());j.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},j.languages.markup.tag.inside["attr-value"].inside.entity=j.languages.markup.entity,j.languages.markup.doctype.inside["internal-subset"].inside=j.languages.markup,j.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(j.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:j.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:j.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},j.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(j.languages.markup.tag,"addAttribute",{value:function(e,t){j.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:j.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),j.languages.html=j.languages.markup,j.languages.mathml=j.languages.markup,j.languages.svg=j.languages.markup,j.languages.xml=j.languages.extend("markup",{}),j.languages.ssml=j.languages.xml,j.languages.atom=j.languages.xml,j.languages.rss=j.languages.xml,a=j,i={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},c="(?:[^\\\\-]|"+(s=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",c=RegExp(c+"-"+c),l={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},a.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:c,inside:{escape:s,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":i,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:s}},"special-escape":i,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":l}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:s,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":l}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},j.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},j.languages.javascript=j.languages.extend("clike",{"class-name":[j.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),j.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,j.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:j.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:j.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:j.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:j.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:j.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),j.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:j.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),j.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),j.languages.markup&&(j.languages.markup.tag.addInlined("script","javascript"),j.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),j.languages.js=j.languages.javascript,j.languages.actionscript=j.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),j.languages.actionscript["class-name"].alias="function",delete j.languages.actionscript.parameter,delete j.languages.actionscript["literal-property"],j.languages.markup&&j.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:j.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(j),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(a=e.languages[t]){var a,i=a[o];if((i=i||(a=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(i=a[o]={pattern:i}),Array.isArray(i))for(var s=0,c=i.length;s<c;s++)i[s]instanceof RegExp&&(i[s]={pattern:i[s]}),r(i[s]);else r(i)}}))}}),t.addSupport(["java","javascript","php"],t)}(j),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(j),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(j),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),a=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+a+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(a),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(j),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),a=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,i=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+a+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+a+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+a+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o,a=t[n];"code"!==a.type?e(a.content):(o=a.content[1],a=a.content[3],o&&a&&"code-language"===o.type&&"code-block"===a.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),a.alias?"string"==typeof a.alias?a.alias=[a.alias,o]:a.alias.push(o):a.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var a=t.classes[r];if(a=/language-(.+)/.exec(a)){n=a[1];break}}var l,u=e.languages[n];u?t.content=e.highlight(t.content.replace(i,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),c(n)):s[t]||e})),u,n):n&&"none"!==n&&e.plugins.autoloader&&(l="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=l,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(l);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),s={amp:"&",lt:"<",gt:">",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(j),j.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:j.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},j.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(p(["definition-mutation","punctuation"])&&"("===u(1).content){n+=2;var a=d(/^\($/,/^\)$/);if(-1===a)continue;for(;n<a;n++){var i=u(0);"variable"===i.type&&(f(i,"variable-input"),o.push(i.content))}n=a+1}if(p(["punctuation","property-query"])&&"{"===u(0).content&&(n++,f(u(0),"property-mutation"),0<o.length)){var s=d(/^\{$/,/^\}$/);if(-1!==s)for(var c=n;c<s;c++){var l=t[c];"variable"===l.type&&0<=o.indexOf(l.content)&&f(l,"variable-input")}}}}function u(e){return t[n+e]}function p(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=u(n+t);if(!r||r.type!==e[n])return}return 1}function d(e,r){for(var o=1,a=n;a<t.length;a++){var i=t[a],s=i.content;if("punctuation"===i.type&&"string"==typeof s)if(e.test(s))o++;else if(r.test(s)&&0==--o)return a}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),j.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],a=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function s(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function c(t,n,i){var c=e.tokenize(t,{interpolation:{pattern:RegExp(a),lookbehind:!0}}),l=0,u={},p=(c=s(c.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=l++,n="___"+i.toUpperCase()+"_"+r+"___")););return u[n]=e,n})).join(""),n,i),Object.keys(u));return l=0,function t(n){for(var a=0;a<n.length;a++){if(l>=p.length)return;var i,c,d,f,m,h,v,g=n[a];"string"==typeof g||"string"==typeof g.content?(i=p[l],-1!==(v=(h="string"==typeof g?g:g.content).indexOf(i))&&(++l,c=h.substring(0,v),m=u[i],d=void 0,(f={})["interpolation-punctuation"]=o,3===(f=e.tokenize(m,f)).length&&((d=[1,1]).push.apply(d,s(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,d)),d=new e.Token("interpolation",f,r.alias,m),f=h.substring(v+i.length),m=[],c&&m.push(c),m.push(d),f&&(t(h=[f]),m.push.apply(m,h)),"string"==typeof g?(n.splice.apply(n,[a,1].concat(m)),a+=m.length-1):g.content=m)):(v=g.content,Array.isArray(v)?t(v):t([v]))}}(c),new e.Token(i,c,"language-"+i,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var l={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function u(e){return"string"==typeof e?e:Array.isArray(e)?e.map(u).join(""):u(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in l&&function t(n){for(var r=0,o=n.length;r<o;r++){var a,i,s,l=n[r];"string"!=typeof l&&(a=l.content,Array.isArray(a)?"template-string"===l.type?(l=a[1],3===a.length&&"string"!=typeof l&&"embedded-code"===l.type&&(i=u(l),l=l.alias,l=Array.isArray(l)?l[0]:l,s=e.languages[l])&&(a[1]=c(i,s,l))):t(a):"string"!=typeof a&&t([a]))}}(t.tokens)}))}(j),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(j),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(j),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(j),j.languages.n4js=j.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),j.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),j.languages.n4jsd=j.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],a=e.languages.javascript[o];o=(a="RegExp"===e.util.type(a)?e.languages.javascript[o]={pattern:a}:a).inside||{};(a.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(j),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function a(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function i(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],a=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===s(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:s(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:a=!0),(a||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(a=s(o),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(a+=s(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(a=s(t[r-1])+a,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",a,null,a)),o.content&&"string"!=typeof o.content&&i(o.content)}}o=a(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=a(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:a(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:a(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var s=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(s).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||i(e.tokens)}))}(j),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(j),j.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},j.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=j.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(j),j.languages.c=j.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),j.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),j.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},j.languages.c.string],char:j.languages.c.char,comment:j.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:j.languages.c}}}}),j.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete j.languages.c.boolean,j.languages.objectivec=j.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete j.languages.objectivec["class-name"],j.languages.objc=j.languages.objectivec,j.languages.reason=j.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),j.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete j.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(j),j.languages.go=j.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),j.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete j.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(j),j.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},j.languages.python["string-interpolation"].inside.interpolation.inside.rest=j.languages.python,j.languages.py=j.languages.python;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>P,duotoneDark:()=>C,duotoneLight:()=>A,github:()=>T,jettwaveDark:()=>V,jettwaveLight:()=>W,nightOwl:()=>I,nightOwlLight:()=>N,oceanicNext:()=>D,okaidia:()=>F,oneDark:()=>Q,oneLight:()=>q,palenight:()=>M,shadesOfPurple:()=>B,synthwave84:()=>z,ultramin:()=>$,vsDark:()=>U,vsLight:()=>H});var P={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},C={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},A={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},T={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},I={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},N={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},L="#c5a5c5",R="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:L}},{types:["attr-value"],style:{color:R}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:R}},{types:["punctuation"],style:{color:R}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:L}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},F={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},M={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},B={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},$={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},U={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},H={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},V={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},W={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},Q={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},q={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},G=(e,t)=>{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:o}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=S(S({},e[t]),o);e[t]=n})),e}),{});return r.root=n,r.plain=k(S({},n),{backgroundColor:void 0}),r},K=/\r\n|\r|\n/,Y=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Z=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},X=e=>{const t=[[]],n=[e],r=[0],o=[e.length];let a=0,i=0,s=[];const c=[s];for(;i>-1;){for(;(a=r[i]++)<o[i];){let e,l=t[i];const u=n[i][a];if("string"==typeof u?(l=i>0?l:["plain"],e=u):(l=Z(l,u.type),u.alias&&(l=Z(l,u.alias)),e=u.content),"string"!=typeof e){i++,t.push(l),n.push(e),r.push(0),o.push(e.length);continue}const p=e.split(K),d=p.length;s.push({types:l,content:p[0]});for(let t=1;t<d;t++)Y(s),c.push(s=[]),s.push({types:l,content:p[t]})}i--,t.pop(),n.pop(),r.pop(),o.pop()}return Y(s),c},J=({children:e,language:t,code:n,theme:r,prism:o})=>{const a=t.toLowerCase(),i=((e,t)=>{const[n,r]=(0,u.useState)(G(t,e)),o=(0,u.useRef)(),a=(0,u.useRef)();return(0,u.useEffect)((()=>{t===o.current&&e===a.current||(o.current=t,a.current=e,r(G(t,e)))}),[e,t]),n})(a,r),s=(e=>(0,u.useCallback)((t=>{var n=t,{className:r,style:o,line:a}=n,i=E(n,["className","style","line"]);const s=k(S({},i),{className:(0,p.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(s.style=e.plain),"object"==typeof o&&(s.style=S(S({},s.style||{}),o)),s}),[e]))(i),c=(e=>{const t=(0,u.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,u.useCallback)((e=>{var n=e,{token:r,className:o,style:a}=n,i=E(n,["token","className","style"]);const s=k(S({},i),{className:(0,p.A)("token",...r.types,o),children:r.content,style:t(r)});return null!=a&&(s.style=S(S({},s.style||{}),a)),s}),[t])})(i),l=(({prism:e,code:t,grammar:n,language:r})=>{const o=(0,u.useRef)(e);return(0,u.useMemo)((()=>{if(null==n)return X([t]);const e={code:t,grammar:n,language:r,tokens:[]};return o.current.hooks.run("before-tokenize",e),e.tokens=o.current.tokenize(t,n),o.current.hooks.run("after-tokenize",e),X(e.tokens)}),[t,n,r])})({prism:o,language:a,code:n,grammar:o.languages[a]});return e({tokens:l,className:`prism-code language-${a}`,style:null!=i?i.root:{},getLineProps:s,getTokenProps:c})},ee=e=>(0,u.createElement)(J,k(S({},e),{prism:e.prism||j,theme:e.theme||U,code:e.code,language:e.language}))},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=!0,o="Invariant failed";function a(e,t){if(!e){if(r)throw new Error(o);var n="function"==typeof t?t():t,a=n?"".concat(o,": ").concat(n):o;throw new Error(a)}}},31635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>L,__assign:()=>a,__asyncDelegator:()=>E,__asyncGenerator:()=>k,__asyncValues:()=>O,__await:()=>S,__awaiter:()=>m,__classPrivateFieldGet:()=>T,__classPrivateFieldIn:()=>N,__classPrivateFieldSet:()=>I,__createBinding:()=>v,__decorate:()=>s,__disposeResources:()=>D,__esDecorate:()=>l,__exportStar:()=>g,__extends:()=>o,__generator:()=>h,__importDefault:()=>A,__importStar:()=>C,__makeTemplateObject:()=>j,__metadata:()=>f,__param:()=>c,__propKey:()=>p,__read:()=>y,__rest:()=>i,__runInitializers:()=>u,__setFunctionName:()=>d,__spread:()=>w,__spreadArray:()=>x,__spreadArrays:()=>_,__values:()=>b,default:()=>F});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var a=function(){return a=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},a.apply(this,arguments)};function i(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function s(e,t,n,r){var o,a=arguments.length,i=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)i=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(i=(a<3?o(i):a>3?o(t,n,i):o(t,n))||i);return a>3&&i&&Object.defineProperty(t,n,i),i}function c(e,t){return function(n,r){t(n,r,e)}}function l(e,t,n,r,o,a){function i(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var s,c=r.kind,l="getter"===c?"get":"setter"===c?"set":"value",u=!t&&e?r.static?e:e.prototype:null,p=t||(u?Object.getOwnPropertyDescriptor(u,r.name):{}),d=!1,f=n.length-1;f>=0;f--){var m={};for(var h in r)m[h]="access"===h?{}:r[h];for(var h in r.access)m.access[h]=r.access[h];m.addInitializer=function(e){if(d)throw new TypeError("Cannot add initializers after decoration has completed");a.push(i(e||null))};var v=(0,n[f])("accessor"===c?{get:p.get,set:p.set}:p[l],m);if("accessor"===c){if(void 0===v)continue;if(null===v||"object"!=typeof v)throw new TypeError("Object expected");(s=i(v.get))&&(p.get=s),(s=i(v.set))&&(p.set=s),(s=i(v.init))&&o.unshift(s)}else(s=i(v))&&("field"===c?o.unshift(s):p[l]=s)}u&&Object.defineProperty(u,r.name,p),d=!0}function u(e,t,n){for(var r=arguments.length>2,o=0;o<t.length;o++)n=r?t[o].call(e,n):t[o].call(e);return r?n:void 0}function p(e){return"symbol"==typeof e?e:"".concat(e)}function d(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function f(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function m(e,t,n,r){return new(n||(n=Promise))((function(o,a){function i(e){try{c(r.next(e))}catch(t){a(t)}}function s(e){try{c(r.throw(e))}catch(t){a(t)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(i,s)}c((r=r.apply(e,t||[])).next())}))}function h(e,t){var n,r,o,a,i={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return a={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function s(s){return function(c){return function(s){if(n)throw new TypeError("Generator is already executing.");for(;a&&(a=0,s[0]&&(i=0)),i;)try{if(n=1,r&&(o=2&s[0]?r.return:s[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,s[1])).done)return o;switch(r=0,o&&(s=[2&s[0],o.value]),s[0]){case 0:case 1:o=s;break;case 4:return i.label++,{value:s[1],done:!1};case 5:i.label++,r=s[1],s=[0];continue;case 7:s=i.ops.pop(),i.trys.pop();continue;default:if(!(o=i.trys,(o=o.length>0&&o[o.length-1])||6!==s[0]&&2!==s[0])){i=0;continue}if(3===s[0]&&(!o||s[1]>o[0]&&s[1]<o[3])){i.label=s[1];break}if(6===s[0]&&i.label<o[1]){i.label=o[1],o=s;break}if(o&&i.label<o[2]){i.label=o[2],i.ops.push(s);break}o[2]&&i.ops.pop(),i.trys.pop();continue}s=t.call(e,i)}catch(c){s=[6,c],r=0}finally{n=o=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([s,c])}}}var v=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function g(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||v(t,e,n)}function b(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function y(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,a=n.call(e),i=[];try{for(;(void 0===t||t-- >0)&&!(r=a.next()).done;)i.push(r.value)}catch(s){o={error:s}}finally{try{r&&!r.done&&(n=a.return)&&n.call(a)}finally{if(o)throw o.error}}return i}function w(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(y(arguments[t]));return e}function _(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var a=arguments[t],i=0,s=a.length;i<s;i++,o++)r[o]=a[i];return r}function x(e,t,n){if(n||2===arguments.length)for(var r,o=0,a=t.length;o<a;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function S(e){return this instanceof S?(this.v=e,this):new S(e)}function k(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),a=[];return r={},i("next"),i("throw"),i("return",(function(e){return function(t){return Promise.resolve(t).then(e,l)}})),r[Symbol.asyncIterator]=function(){return this},r;function i(e,t){o[e]&&(r[e]=function(t){return new Promise((function(n,r){a.push([e,t,n,r])>1||s(e,t)}))},t&&(r[e]=t(r[e])))}function s(e,t){try{(n=o[e](t)).value instanceof S?Promise.resolve(n.value.v).then(c,l):u(a[0][2],n)}catch(r){u(a[0][3],r)}var n}function c(e){s("next",e)}function l(e){s("throw",e)}function u(e,t){e(t),a.shift(),a.length&&s(a[0][0],a[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:S(e[r](t)),done:!1}:o?o(t):t}:o}}function O(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=b(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}function j(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var P=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function C(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&v(t,e,n);return P(t,e),t}function A(e){return e&&e.__esModule?e:{default:e}}function T(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function I(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function N(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function L(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,o;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(o=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");o&&(r=function(){try{o.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var R="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function D(e){function t(t){e.error=e.hasError?new R(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}return function n(){for(;e.stack.length;){var r=e.stack.pop();try{var o=r.dispose&&r.dispose.call(r.value);if(r.async)return Promise.resolve(o).then(n,(function(e){return t(e),n()}))}catch(a){t(a)}}if(e.hasError)throw e.error}()}const F={__extends:o,__assign:a,__rest:i,__decorate:s,__param:c,__metadata:f,__awaiter:m,__generator:h,__createBinding:v,__exportStar:g,__values:b,__read:y,__spread:w,__spreadArrays:_,__spreadArray:x,__await:S,__asyncGenerator:k,__asyncDelegator:E,__asyncValues:O,__makeTemplateObject:j,__importStar:C,__importDefault:A,__classPrivateFieldGet:T,__classPrivateFieldSet:I,__classPrivateFieldIn:N,__addDisposableResource:L,__disposeResources:D}},22654:e=>{"use strict";e.exports=JSON.parse('{"cmfcmf/d-s-l.searchBar.placeholder":"Search...","cmfcmf/d-s-l.searchBar.noResults":"No results found.","cmfcmf/d-s-l.searchBar.clearButtonTitle":"Clear","cmfcmf/d-s-l.searchBar.detachedCancelButtonText":"Cancel","cmfcmf/d-s-l.searchBar.submitButtonTitle":"Submit"}')},84054:e=>{"use strict";e.exports=JSON.parse('{"/contrast/pr-preview/pr-976/-a12":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/contrast/pr-preview/pr-976/0.5-78d":{"__comp":"a7bd4aaa","__props":"b3a88889"},"/contrast/pr-preview/pr-976/0.5-895":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/0.5-7f7":{"__comp":"17896441","content":"f47dd6e5"},"/contrast/pr-preview/pr-976/0.5/architecture-83c":{"__comp":"17896441","content":"9d9e06f4"},"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator-a64":{"__comp":"17896441","content":"64d58a39"},"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware-2f5":{"__comp":"17896441","content":"04102e85"},"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest-963":{"__comp":"17896441","content":"9397123b"},"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm-aea":{"__comp":"17896441","content":"4f453872"},"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies-bf9":{"__comp":"17896441","content":"20382dd7"},"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki-89c":{"__comp":"17896441","content":"3e02a241"},"/contrast/pr-preview/pr-976/0.5/architecture/components/cli-2f7":{"__comp":"17896441","content":"966b9f47"},"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator-257":{"__comp":"17896441","content":"e446d98f"},"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container-56a":{"__comp":"17896441","content":"d580a1fd"},"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers-19b":{"__comp":"17896441","content":"15b9bf06"},"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys-f9c":{"__comp":"17896441","content":"d2630e76"},"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar-973":{"__comp":"17896441","content":"b3916dd3"},"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers-62c":{"__comp":"17896441","content":"8dca39c2"},"/contrast/pr-preview/pr-976/0.5/basics/features-87d":{"__comp":"17896441","content":"6903d0da"},"/contrast/pr-preview/pr-976/0.5/basics/security-benefits-004":{"__comp":"17896441","content":"ee8b52db"},"/contrast/pr-preview/pr-976/0.5/category/attestation-00d":{"__comp":"14eb3368","__props":"5aa90309"},"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities-968":{"__comp":"14eb3368","__props":"f5272de0"},"/contrast/pr-preview/pr-976/0.5/category/components-c39":{"__comp":"14eb3368","__props":"8f09b871"},"/contrast/pr-preview/pr-976/0.5/category/network-encryption-633":{"__comp":"14eb3368","__props":"8965cb1f"},"/contrast/pr-preview/pr-976/0.5/deployment-b43":{"__comp":"17896441","content":"69ec948c"},"/contrast/pr-preview/pr-976/0.5/examples-4f4":{"__comp":"17896441","content":"018595b3"},"/contrast/pr-preview/pr-976/0.5/examples/emojivoto-811":{"__comp":"17896441","content":"3d9be0cc"},"/contrast/pr-preview/pr-976/0.5/getting-started-7dd":{"__comp":"17896441","content":"baef5027"},"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup-26d":{"__comp":"17896441","content":"3a77bb3e"},"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps-ce9":{"__comp":"17896441","content":"327db732"},"/contrast/pr-preview/pr-976/0.5/getting-started/install-437":{"__comp":"17896441","content":"a161c24f"},"/contrast/pr-preview/pr-976/0.6-6f5":{"__comp":"a7bd4aaa","__props":"1ea8f7a3"},"/contrast/pr-preview/pr-976/0.6-a86":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/0.6-f27":{"__comp":"17896441","content":"f593d43a"},"/contrast/pr-preview/pr-976/0.6/about-67b":{"__comp":"17896441","content":"207bb774"},"/contrast/pr-preview/pr-976/0.6/about/telemetry-61b":{"__comp":"17896441","content":"27d05faa"},"/contrast/pr-preview/pr-976/0.6/architecture-ce6":{"__comp":"17896441","content":"75100f0d"},"/contrast/pr-preview/pr-976/0.6/architecture/attestation-c3a":{"__comp":"17896441","content":"e1e441c9"},"/contrast/pr-preview/pr-976/0.6/architecture/certificates-7cc":{"__comp":"17896441","content":"c09e49b9"},"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers-24c":{"__comp":"17896441","content":"50474e10"},"/contrast/pr-preview/pr-976/0.6/basics/features-3b5":{"__comp":"17896441","content":"dfd9c366"},"/contrast/pr-preview/pr-976/0.6/basics/security-benefits-7a8":{"__comp":"17896441","content":"0c24bc66"},"/contrast/pr-preview/pr-976/0.6/components-f96":{"__comp":"17896441","content":"45c98560"},"/contrast/pr-preview/pr-976/0.6/components/policies-d35":{"__comp":"17896441","content":"567e04ee"},"/contrast/pr-preview/pr-976/0.6/components/runtime-570":{"__comp":"17896441","content":"90af0d0d"},"/contrast/pr-preview/pr-976/0.6/components/service-mesh-2a9":{"__comp":"17896441","content":"54c6367b"},"/contrast/pr-preview/pr-976/0.6/deployment-ee0":{"__comp":"17896441","content":"75d659e1"},"/contrast/pr-preview/pr-976/0.6/examples-e8d":{"__comp":"17896441","content":"cdb2b1a5"},"/contrast/pr-preview/pr-976/0.6/examples/emojivoto-7eb":{"__comp":"17896441","content":"21d7c4d4"},"/contrast/pr-preview/pr-976/0.6/getting-started-0c5":{"__comp":"17896441","content":"c1fac065"},"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup-864":{"__comp":"17896441","content":"fbad2ec0"},"/contrast/pr-preview/pr-976/0.6/getting-started/install-2e9":{"__comp":"17896441","content":"1c9b88ee"},"/contrast/pr-preview/pr-976/0.6/known-limitations-454":{"__comp":"17896441","content":"6478b99f"},"/contrast/pr-preview/pr-976/0.7-599":{"__comp":"a7bd4aaa","__props":"b20d32fc"},"/contrast/pr-preview/pr-976/0.7-9f8":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/0.7-78b":{"__comp":"17896441","content":"9a99019d"},"/contrast/pr-preview/pr-976/0.7/about-054":{"__comp":"17896441","content":"39db4684"},"/contrast/pr-preview/pr-976/0.7/about/telemetry-da0":{"__comp":"17896441","content":"f31967d8"},"/contrast/pr-preview/pr-976/0.7/architecture-742":{"__comp":"17896441","content":"aa0f7abf"},"/contrast/pr-preview/pr-976/0.7/architecture/attestation-b8a":{"__comp":"17896441","content":"ab09c42c"},"/contrast/pr-preview/pr-976/0.7/architecture/certificates-2fb":{"__comp":"17896441","content":"e277c26a"},"/contrast/pr-preview/pr-976/0.7/architecture/observability-5f2":{"__comp":"17896441","content":"7edb0f0d"},"/contrast/pr-preview/pr-976/0.7/basics/confidential-containers-2ab":{"__comp":"17896441","content":"20e0cfa9"},"/contrast/pr-preview/pr-976/0.7/basics/features-a92":{"__comp":"17896441","content":"173fd1a8"},"/contrast/pr-preview/pr-976/0.7/basics/security-benefits-7bd":{"__comp":"17896441","content":"bced0f3c"},"/contrast/pr-preview/pr-976/0.7/components-afa":{"__comp":"17896441","content":"abfbdc79"},"/contrast/pr-preview/pr-976/0.7/components/policies-e21":{"__comp":"17896441","content":"06eada7a"},"/contrast/pr-preview/pr-976/0.7/components/runtime-0ae":{"__comp":"17896441","content":"8c9a8791"},"/contrast/pr-preview/pr-976/0.7/components/service-mesh-1f6":{"__comp":"17896441","content":"2dbe31cc"},"/contrast/pr-preview/pr-976/0.7/deployment-670":{"__comp":"17896441","content":"de615ffd"},"/contrast/pr-preview/pr-976/0.7/examples-03a":{"__comp":"17896441","content":"896da145"},"/contrast/pr-preview/pr-976/0.7/examples/emojivoto-d75":{"__comp":"17896441","content":"7680d80e"},"/contrast/pr-preview/pr-976/0.7/features-limitations-90a":{"__comp":"17896441","content":"e2b3b970"},"/contrast/pr-preview/pr-976/0.7/getting-started-230":{"__comp":"17896441","content":"5eab7755"},"/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setup-99c":{"__comp":"17896441","content":"8132774f"},"/contrast/pr-preview/pr-976/0.7/getting-started/install-610":{"__comp":"17896441","content":"bf823012"},"/contrast/pr-preview/pr-976/0.8-eb1":{"__comp":"a7bd4aaa","__props":"137fbf80"},"/contrast/pr-preview/pr-976/0.8-9c8":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/0.8-75f":{"__comp":"17896441","content":"098bf236"},"/contrast/pr-preview/pr-976/0.8/about/telemetry-ca9":{"__comp":"17896441","content":"ac3e6feb"},"/contrast/pr-preview/pr-976/0.8/architecture/attestation-fec":{"__comp":"17896441","content":"14a9ce33"},"/contrast/pr-preview/pr-976/0.8/architecture/certificates-765":{"__comp":"17896441","content":"aafa6b90"},"/contrast/pr-preview/pr-976/0.8/architecture/observability-220":{"__comp":"17896441","content":"6a46f748"},"/contrast/pr-preview/pr-976/0.8/architecture/secrets-754":{"__comp":"17896441","content":"a71cbd8f"},"/contrast/pr-preview/pr-976/0.8/basics/confidential-containers-4d5":{"__comp":"17896441","content":"0a7a212e"},"/contrast/pr-preview/pr-976/0.8/basics/features-793":{"__comp":"17896441","content":"7d1602ac"},"/contrast/pr-preview/pr-976/0.8/basics/security-benefits-a16":{"__comp":"17896441","content":"98367cce"},"/contrast/pr-preview/pr-976/0.8/components/overview-2d3":{"__comp":"17896441","content":"9ce1fd56"},"/contrast/pr-preview/pr-976/0.8/components/policies-652":{"__comp":"17896441","content":"ae6c0c68"},"/contrast/pr-preview/pr-976/0.8/components/runtime-006":{"__comp":"17896441","content":"9ccb1fc6"},"/contrast/pr-preview/pr-976/0.8/components/service-mesh-17b":{"__comp":"17896441","content":"790f17e8"},"/contrast/pr-preview/pr-976/0.8/deployment-370":{"__comp":"17896441","content":"a66d714b"},"/contrast/pr-preview/pr-976/0.8/examples/emojivoto-a78":{"__comp":"17896441","content":"a0a4ec6e"},"/contrast/pr-preview/pr-976/0.8/features-limitations-d8e":{"__comp":"17896441","content":"d1a11e04"},"/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setup-4ac":{"__comp":"17896441","content":"ba2406d8"},"/contrast/pr-preview/pr-976/0.8/getting-started/install-eb7":{"__comp":"17896441","content":"6fc50b39"},"/contrast/pr-preview/pr-976/0.8/troubleshooting-6ab":{"__comp":"17896441","content":"250ffcdd"},"/contrast/pr-preview/pr-976/0.9-901":{"__comp":"a7bd4aaa","__props":"9c8ec574"},"/contrast/pr-preview/pr-976/0.9-e48":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/0.9-cbe":{"__comp":"17896441","content":"44b49990"},"/contrast/pr-preview/pr-976/0.9/about/telemetry-3db":{"__comp":"17896441","content":"7f3f1ff7"},"/contrast/pr-preview/pr-976/0.9/architecture/attestation-128":{"__comp":"17896441","content":"2e82b444"},"/contrast/pr-preview/pr-976/0.9/architecture/certificates-f8d":{"__comp":"17896441","content":"fbcf0d59"},"/contrast/pr-preview/pr-976/0.9/architecture/observability-a73":{"__comp":"17896441","content":"078f57bf"},"/contrast/pr-preview/pr-976/0.9/architecture/secrets-74d":{"__comp":"17896441","content":"26742c3b"},"/contrast/pr-preview/pr-976/0.9/basics/confidential-containers-5df":{"__comp":"17896441","content":"e55aefba"},"/contrast/pr-preview/pr-976/0.9/basics/features-a33":{"__comp":"17896441","content":"6100b425"},"/contrast/pr-preview/pr-976/0.9/basics/security-benefits-23f":{"__comp":"17896441","content":"327e592d"},"/contrast/pr-preview/pr-976/0.9/components/overview-28a":{"__comp":"17896441","content":"06354bbe"},"/contrast/pr-preview/pr-976/0.9/components/policies-542":{"__comp":"17896441","content":"c7462af2"},"/contrast/pr-preview/pr-976/0.9/components/runtime-271":{"__comp":"17896441","content":"6009a9aa"},"/contrast/pr-preview/pr-976/0.9/components/service-mesh-956":{"__comp":"17896441","content":"c3a9f66a"},"/contrast/pr-preview/pr-976/0.9/deployment-bc8":{"__comp":"17896441","content":"3683601e"},"/contrast/pr-preview/pr-976/0.9/examples/emojivoto-748":{"__comp":"17896441","content":"9a28f5c4"},"/contrast/pr-preview/pr-976/0.9/features-limitations-8b0":{"__comp":"17896441","content":"0ba7602a"},"/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setup-12b":{"__comp":"17896441","content":"f36abd57"},"/contrast/pr-preview/pr-976/0.9/getting-started/install-4fc":{"__comp":"17896441","content":"dacf14a0"},"/contrast/pr-preview/pr-976/0.9/troubleshooting-714":{"__comp":"17896441","content":"41b31679"},"/contrast/pr-preview/pr-976/1.0-b7e":{"__comp":"a7bd4aaa","__props":"9152dfbd"},"/contrast/pr-preview/pr-976/1.0-9da":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/1.0-7f4":{"__comp":"17896441","content":"7bd8db71"},"/contrast/pr-preview/pr-976/1.0/about/telemetry-7ef":{"__comp":"17896441","content":"4ce6baab"},"/contrast/pr-preview/pr-976/1.0/architecture/attestation-a51":{"__comp":"17896441","content":"bd625abb"},"/contrast/pr-preview/pr-976/1.0/architecture/certificates-1e4":{"__comp":"17896441","content":"e8480491"},"/contrast/pr-preview/pr-976/1.0/architecture/observability-2ab":{"__comp":"17896441","content":"51513a8d"},"/contrast/pr-preview/pr-976/1.0/architecture/secrets-30a":{"__comp":"17896441","content":"fda633d9"},"/contrast/pr-preview/pr-976/1.0/basics/confidential-containers-ce9":{"__comp":"17896441","content":"d77304ba"},"/contrast/pr-preview/pr-976/1.0/basics/features-8a2":{"__comp":"17896441","content":"4cf3063f"},"/contrast/pr-preview/pr-976/1.0/basics/security-benefits-ac9":{"__comp":"17896441","content":"9620adf5"},"/contrast/pr-preview/pr-976/1.0/components/overview-d41":{"__comp":"17896441","content":"1ab97833"},"/contrast/pr-preview/pr-976/1.0/components/policies-72d":{"__comp":"17896441","content":"bd029836"},"/contrast/pr-preview/pr-976/1.0/components/runtime-038":{"__comp":"17896441","content":"27a940ba"},"/contrast/pr-preview/pr-976/1.0/components/service-mesh-cb6":{"__comp":"17896441","content":"270470f6"},"/contrast/pr-preview/pr-976/1.0/deployment-467":{"__comp":"17896441","content":"2df6ad32"},"/contrast/pr-preview/pr-976/1.0/examples/emojivoto-78f":{"__comp":"17896441","content":"9040bbc8"},"/contrast/pr-preview/pr-976/1.0/features-limitations-343":{"__comp":"17896441","content":"aaec90ae"},"/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setup-5a4":{"__comp":"17896441","content":"a2899f6e"},"/contrast/pr-preview/pr-976/1.0/getting-started/install-465":{"__comp":"17896441","content":"fbad79f4"},"/contrast/pr-preview/pr-976/1.0/troubleshooting-026":{"__comp":"17896441","content":"c2ce05d5"},"/contrast/pr-preview/pr-976/next-b22":{"__comp":"a7bd4aaa","__props":"bde25e2b"},"/contrast/pr-preview/pr-976/next-f3f":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/next-3d7":{"__comp":"17896441","content":"0e384e19"},"/contrast/pr-preview/pr-976/next/about/telemetry-8bd":{"__comp":"17896441","content":"2496d21b"},"/contrast/pr-preview/pr-976/next/architecture/attestation-270":{"__comp":"17896441","content":"642ed902"},"/contrast/pr-preview/pr-976/next/architecture/certificates-ab4":{"__comp":"17896441","content":"4fb24623"},"/contrast/pr-preview/pr-976/next/architecture/observability-153":{"__comp":"17896441","content":"927cf76e"},"/contrast/pr-preview/pr-976/next/architecture/secrets-6dc":{"__comp":"17896441","content":"014daffb"},"/contrast/pr-preview/pr-976/next/architecture/security-considerations-d7f":{"__comp":"17896441","content":"b0cb3eb4"},"/contrast/pr-preview/pr-976/next/basics/confidential-containers-fe2":{"__comp":"17896441","content":"b27c3275"},"/contrast/pr-preview/pr-976/next/basics/features-6df":{"__comp":"17896441","content":"89a4f0ca"},"/contrast/pr-preview/pr-976/next/basics/security-benefits-dd0":{"__comp":"17896441","content":"640cb024"},"/contrast/pr-preview/pr-976/next/components/overview-438":{"__comp":"17896441","content":"89486910"},"/contrast/pr-preview/pr-976/next/components/policies-460":{"__comp":"17896441","content":"989c6d03"},"/contrast/pr-preview/pr-976/next/components/runtime-fa0":{"__comp":"17896441","content":"c4b4ced0"},"/contrast/pr-preview/pr-976/next/components/service-mesh-702":{"__comp":"17896441","content":"ca5b6702"},"/contrast/pr-preview/pr-976/next/deployment-1dd":{"__comp":"17896441","content":"a3713279"},"/contrast/pr-preview/pr-976/next/examples/emojivoto-f41":{"__comp":"17896441","content":"f65fea7a"},"/contrast/pr-preview/pr-976/next/features-limitations-8c2":{"__comp":"17896441","content":"35dd9928"},"/contrast/pr-preview/pr-976/next/getting-started/bare-metal-409":{"__comp":"17896441","content":"cf49aa2b"},"/contrast/pr-preview/pr-976/next/getting-started/cluster-setup-1d1":{"__comp":"17896441","content":"9a06ae3d"},"/contrast/pr-preview/pr-976/next/getting-started/install-251":{"__comp":"17896441","content":"2a2a0c40"},"/contrast/pr-preview/pr-976/next/troubleshooting-193":{"__comp":"17896441","content":"9d9f8394"},"/contrast/pr-preview/pr-976/-2fb":{"__comp":"a7bd4aaa","__props":"259f95a2"},"/contrast/pr-preview/pr-976/-c3c":{"__comp":"a94703ab"},"/contrast/pr-preview/pr-976/about/telemetry-f74":{"__comp":"17896441","content":"a86a94ce"},"/contrast/pr-preview/pr-976/architecture/attestation-171":{"__comp":"17896441","content":"48f2f8ef"},"/contrast/pr-preview/pr-976/architecture/certificates-40a":{"__comp":"17896441","content":"5ecc20d3"},"/contrast/pr-preview/pr-976/architecture/observability-da1":{"__comp":"17896441","content":"68be920e"},"/contrast/pr-preview/pr-976/architecture/secrets-eae":{"__comp":"17896441","content":"f2348f57"},"/contrast/pr-preview/pr-976/architecture/security-considerations-cc5":{"__comp":"17896441","content":"6507182a"},"/contrast/pr-preview/pr-976/basics/confidential-containers-308":{"__comp":"17896441","content":"1057c3b3"},"/contrast/pr-preview/pr-976/basics/features-76b":{"__comp":"17896441","content":"1e7c9753"},"/contrast/pr-preview/pr-976/basics/security-benefits-899":{"__comp":"17896441","content":"10257d90"},"/contrast/pr-preview/pr-976/components/overview-cb2":{"__comp":"17896441","content":"edcfcef8"},"/contrast/pr-preview/pr-976/components/policies-7da":{"__comp":"17896441","content":"0b1c872d"},"/contrast/pr-preview/pr-976/components/runtime-aee":{"__comp":"17896441","content":"4eec459c"},"/contrast/pr-preview/pr-976/components/service-mesh-1d8":{"__comp":"17896441","content":"969019ea"},"/contrast/pr-preview/pr-976/deployment-9b1":{"__comp":"17896441","content":"0a09f1f2"},"/contrast/pr-preview/pr-976/examples/emojivoto-827":{"__comp":"17896441","content":"5c6fa5d3"},"/contrast/pr-preview/pr-976/features-limitations-3d3":{"__comp":"17896441","content":"27004ef7"},"/contrast/pr-preview/pr-976/getting-started/bare-metal-9e3":{"__comp":"17896441","content":"b451d7c3"},"/contrast/pr-preview/pr-976/getting-started/cluster-setup-2b0":{"__comp":"17896441","content":"3d96af17"},"/contrast/pr-preview/pr-976/getting-started/install-87c":{"__comp":"17896441","content":"a0a1fd3b"},"/contrast/pr-preview/pr-976/troubleshooting-e8d":{"__comp":"17896441","content":"e9dbdd13"},"/contrast/pr-preview/pr-976/-870":{"__comp":"17896441","content":"5f998a2f"}}')}},e=>{e.O(0,[1869],(()=>{return t=20979,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/pr-preview/pr-976/assets/js/main.bd30bfc7.js.LICENSE.txt b/pr-preview/pr-976/assets/js/main.bd30bfc7.js.LICENSE.txt new file mode 100644 index 0000000000..3a6ccc5052 --- /dev/null +++ b/pr-preview/pr-976/assets/js/main.bd30bfc7.js.LICENSE.txt @@ -0,0 +1,133 @@ +/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress + * @license MIT */ + +/*! + * lunr.Builder + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Index + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Pipeline + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Set + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.TokenSet + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.Vector + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.stemmer + * Copyright (C) 2020 Oliver Nightingale + * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt + */ + +/*! + * lunr.stopWordFilter + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.tokenizer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.trimmer + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! + * lunr.utils + * Copyright (C) 2020 Oliver Nightingale + */ + +/*! Bundled license information: + +prismjs/prism.js: + (** + * Prism: Lightweight, robust, elegant syntax highlighting + * + * @license MIT <https://opensource.org/licenses/MIT> + * @author Lea Verou <https://lea.verou.me> + * @namespace + * @public + *) +*/ + +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ + +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react-jsx-runtime.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * @license React + * scheduler.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ + +/** @license React v16.13.1 + * react-is.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ diff --git a/pr-preview/pr-976/assets/js/runtime~main.7d4c04c9.js b/pr-preview/pr-976/assets/js/runtime~main.7d4c04c9.js new file mode 100644 index 0000000000..7bfb0fa063 --- /dev/null +++ b/pr-preview/pr-976/assets/js/runtime~main.7d4c04c9.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,a,f,d,b,c={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var f=t[e]={exports:{}};return c[e].call(f.exports,f,f.exports,r),f.exports}r.m=c,e=[],r.O=(a,f,d,b)=>{if(!f){var c=1/0;for(i=0;i<e.length;i++){f=e[i][0],d=e[i][1],b=e[i][2];for(var t=!0,o=0;o<f.length;o++)(!1&b||c>=b)&&Object.keys(r.O).every((e=>r.O[e](f[o])))?f.splice(o--,1):(t=!1,b<c&&(c=b));if(t){e.splice(i--,1);var n=d();void 0!==n&&(a=n)}}return a}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[f,d,b]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var c={};a=a||[null,f({}),f([]),f(f)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=f(t))Object.getOwnPropertyNames(t).forEach((a=>c[a]=()=>e[a]));return c.default=()=>e,r.d(b,c),b},r.d=(e,a)=>{for(var f in a)r.o(a,f)&&!r.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,f)=>(r.f[f](e,a),a)),[])),r.u=e=>"assets/js/"+({89:"b3916dd3",95:"35dd9928",101:"dacf14a0",133:"98367cce",212:"a86a94ce",221:"e446d98f",234:"b451d7c3",388:"327e592d",390:"c09e49b9",426:"9ce1fd56",430:"207bb774",455:"4ce6baab",485:"969019ea",564:"f5272de0",594:"6903d0da",722:"5c6fa5d3",782:"989c6d03",801:"9a99019d",827:"fda633d9",912:"9620adf5",941:"5f998a2f",985:"1ab97833",995:"2496d21b",1047:"bd029836",1112:"966b9f47",1158:"04102e85",1226:"927cf76e",1321:"de615ffd",1362:"e8480491",1381:"5aa90309",1514:"173fd1a8",1560:"1c9b88ee",1575:"a161c24f",1597:"2df6ad32",1606:"7bd8db71",1632:"e277c26a",1647:"e9dbdd13",1658:"fbad2ec0",1690:"078f57bf",1734:"d580a1fd",1739:"896da145",1751:"327db732",1831:"9c8ec574",1841:"8132774f",1861:"a2899f6e",1889:"3a77bb3e",1954:"5ecc20d3",1955:"014daffb",1956:"f593d43a",2005:"64d58a39",2020:"48f2f8ef",2045:"abfbdc79",2132:"b0cb3eb4",2154:"27004ef7",2343:"250ffcdd",2453:"9040bbc8",2454:"dfd9c366",2472:"f65fea7a",2476:"ba2406d8",2540:"c7462af2",2550:"4fb24623",2564:"c4b4ced0",2590:"fbad79f4",2623:"e1e441c9",2639:"4eec459c",2700:"2dbe31cc",2729:"ae6c0c68",2731:"8965cb1f",2772:"5eab7755",2841:"e2b3b970",2912:"9a06ae3d",2941:"9397123b",2987:"3683601e",3074:"ac3e6feb",3108:"26742c3b",3116:"8dca39c2",3129:"6100b425",3133:"edcfcef8",3188:"0b1c872d",3357:"20382dd7",3391:"1e7c9753",3459:"39db4684",3477:"10257d90",3505:"9a28f5c4",3506:"6478b99f",3690:"b27c3275",3702:"0a7a212e",3712:"69ec948c",3859:"51513a8d",3876:"018595b3",3970:"fbcf0d59",3976:"0e384e19",4113:"e55aefba",4206:"c1fac065",4213:"6fc50b39",4233:"d77304ba",4304:"aaec90ae",4325:"b20d32fc",4415:"bd625abb",4506:"3d96af17",4555:"1ea8f7a3",4670:"9d9e06f4",4687:"89a4f0ca",4703:"cf49aa2b",4714:"41b31679",4980:"a0a4ec6e",5003:"a71cbd8f",5225:"bf823012",5231:"7edb0f0d",5242:"790f17e8",5279:"27a940ba",5310:"3d9be0cc",5316:"ee8b52db",5335:"8c9a8791",5388:"15b9bf06",5390:"21d7c4d4",5541:"642ed902",5742:"aba21aa0",5811:"1057c3b3",5878:"bde25e2b",5945:"ca5b6702",5999:"54c6367b",6069:"7d1602ac",6232:"2e82b444",6240:"6a46f748",6408:"f47dd6e5",6440:"567e04ee",6470:"06eada7a",6623:"7f3f1ff7",6645:"aafa6b90",6711:"f36abd57",6733:"f31967d8",6739:"0c24bc66",6755:"a0a1fd3b",6969:"14eb3368",7e3:"0a09f1f2",7061:"50474e10",7086:"89486910",7098:"a7bd4aaa",7292:"2a2a0c40",7294:"68be920e",7368:"0ba7602a",7664:"137fbf80",7682:"640cb024",7697:"27d05faa",7832:"c3a9f66a",7882:"75100f0d",7924:"14a9ce33",8001:"bced0f3c",8024:"c2ce05d5",8036:"9152dfbd",8117:"3e02a241",8170:"4f453872",8204:"06354bbe",8212:"6009a9aa",8259:"098bf236",8295:"aa0f7abf",8364:"4cf3063f",8401:"17896441",8403:"20e0cfa9",8597:"75d659e1",8630:"259f95a2",8671:"270470f6",8683:"ab09c42c",8772:"f2348f57",8902:"d1a11e04",8921:"90af0d0d",9013:"9d9f8394",9025:"7680d80e",9048:"a94703ab",9079:"6507182a",9103:"baef5027",9119:"cdb2b1a5",9361:"45c98560",9440:"b3a88889",9588:"a3713279",9634:"d2630e76",9647:"5e95c892",9652:"44b49990",9686:"8f09b871",9874:"9ccb1fc6",9974:"a66d714b"}[e]||e)+"."+{89:"30abb5e2",95:"876c8b6d",101:"c33c9e89",133:"28290f99",155:"48c4e908",165:"8f94caaa",212:"db57590c",221:"5906d2b8",234:"99a4d0de",388:"77873d5f",390:"9ff206ce",426:"9821471c",430:"442bb435",455:"ddbc3709",484:"808d13de",485:"32517b56",564:"78413199",594:"aed38602",722:"98b892e1",782:"4ac694c4",801:"7c69ee4c",827:"f148ee0b",890:"8531ec8c",912:"133d730b",921:"5ff0c680",941:"761e3939",985:"9e49478d",995:"1c09cf80",1047:"96853ab4",1112:"b375a919",1158:"745c04f7",1186:"8726fdba",1226:"6f4c28bf",1321:"ef11da9f",1362:"72a2b553",1381:"c36a9a65",1477:"b147cf3f",1514:"8751a104",1560:"ba0039db",1575:"491f18fc",1597:"0df42417",1606:"3f1b000d",1632:"364edfbf",1647:"305d71e2",1658:"afc757e3",1689:"251eba58",1690:"b2f92c81",1711:"0c8f9a6a",1734:"d3605f1d",1739:"a1a53ce3",1751:"9cf7a097",1831:"c337425b",1841:"2680af68",1861:"7ec951c7",1889:"ae0e3a69",1954:"560917b7",1955:"28613203",1956:"93a070a0",2005:"1a4a9610",2020:"3afa4ead",2045:"2729a342",2130:"a7c31b12",2132:"99a5cbf3",2154:"ee187533",2247:"7219b8c6",2334:"619d7d41",2343:"e9b01620",2387:"7f9ca256",2453:"06d43bf0",2454:"af676094",2472:"7a92e4f1",2476:"4e6c54c4",2540:"8edc4250",2550:"4962c99a",2564:"cc4aaa5d",2590:"6e49be6a",2623:"d7ad6ed8",2639:"883ecb5e",2700:"19015d41",2729:"92c1ee41",2731:"7fa15643",2763:"b71509e9",2772:"b121b0e1",2841:"151dea1f",2912:"046ea467",2941:"2f0b3891",2987:"e3d4185e",3074:"c8d4aa8b",3108:"ead769cd",3116:"b4b59560",3129:"8c972462",3133:"efca5aef",3188:"c7834956",3357:"20e8921f",3364:"d54f19c0",3391:"02e56af3",3459:"7504d8d4",3477:"7ee2f98c",3505:"01963c55",3506:"23cfdac2",3624:"631ec2ee",3690:"a5dbc455",3702:"4bfb0b6f",3712:"89847346",3840:"510aef0e",3859:"cdeb6e9c",3876:"560dae8b",3970:"08f1ee86",3976:"651e3adc",4113:"57f034d8",4206:"af80720c",4213:"46b4da2f",4233:"f1bec1ec",4304:"14899e6c",4325:"e428ea64",4415:"43f2f678",4445:"3811e3c0",4449:"bb76b6fa",4506:"ef1ae4be",4555:"d2d50582",4670:"34f01e43",4687:"91bcaa30",4703:"89d9d490",4714:"7dba08fd",4980:"e66a8111",5003:"fee2c6c8",5225:"0ed024b4",5231:"85693ccb",5242:"a5baddba",5279:"2b4c52be",5310:"1005a9e5",5316:"b69e4030",5335:"46416e05",5388:"b97730a3",5390:"59195010",5541:"37cf76bd",5606:"5910c299",5742:"0f4e95f1",5811:"114828df",5878:"2917f0f7",5945:"a3b16546",5999:"8cc47335",6069:"42782481",6232:"dd4ac86b",6240:"9218759d",6408:"ecf0ed95",6440:"8a836253",6452:"9f5d0a8d",6470:"0ffd2db0",6623:"009aeec6",6645:"3f7af2d6",6711:"48e08f44",6733:"71b71235",6739:"085b04d6",6755:"d49c396c",6790:"b101800c",6912:"4cd2abc1",6969:"8cb6f0b4",7e3:"af458bba",7032:"dded9666",7060:"28ce0df1",7061:"3e18d095",7086:"2245dcd7",7098:"3effeeae",7292:"fc2cf12c",7294:"9f8df8ee",7357:"6aa95f42",7368:"85a7f1d2",7664:"8c6cd314",7682:"2e039806",7697:"4fff9fb7",7723:"83dacf97",7832:"6efdd9fb",7882:"9f8f9b89",7924:"fc32993b",8001:"110450d8",8024:"83575dcd",8036:"3bdd0a61",8117:"10a2e2ba",8159:"4e759f62",8170:"072c6bcc",8174:"61ff22d1",8204:"4db69232",8212:"e37420d5",8259:"fb47b956",8295:"62cf75e4",8364:"ffa75230",8379:"c80faf06",8401:"7a01a35f",8403:"1b701e80",8496:"19c721e5",8597:"2d71da15",8630:"0c3a0ee9",8671:"2a97a5fd",8683:"54be6c5a",8731:"c272170f",8772:"3db099bc",8902:"8df8afb2",8921:"00afd3dd",8998:"5c85576b",9013:"950345c7",9025:"2894bfc5",9048:"e63edbb7",9079:"417f4320",9103:"95910e40",9119:"cee59a12",9361:"977c2d08",9368:"5da20e84",9440:"ef306daa",9588:"cb16cfe2",9634:"be1d4782",9647:"c959e509",9652:"29d0eb8e",9664:"5583cedf",9686:"5bb7d3d7",9720:"8e4604d2",9802:"bb09c288",9874:"873740e8",9875:"78d2cec3",9974:"bad912b3"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},b="contrast-docs:",r.l=(e,a,f,c)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==b+f){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+f),t.src=e),d[e]=[a];var s=(a,f)=>{t.onerror=t.onload=null,clearTimeout(l);var b=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(f))),a)return a(f)},l=setTimeout(s.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=s.bind(null,t.onerror),t.onload=s.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/contrast/pr-preview/pr-976/",r.gca=function(e){return e={17896441:"8401",89486910:"7086",b3916dd3:"89","35dd9928":"95",dacf14a0:"101","98367cce":"133",a86a94ce:"212",e446d98f:"221",b451d7c3:"234","327e592d":"388",c09e49b9:"390","9ce1fd56":"426","207bb774":"430","4ce6baab":"455","969019ea":"485",f5272de0:"564","6903d0da":"594","5c6fa5d3":"722","989c6d03":"782","9a99019d":"801",fda633d9:"827","9620adf5":"912","5f998a2f":"941","1ab97833":"985","2496d21b":"995",bd029836:"1047","966b9f47":"1112","04102e85":"1158","927cf76e":"1226",de615ffd:"1321",e8480491:"1362","5aa90309":"1381","173fd1a8":"1514","1c9b88ee":"1560",a161c24f:"1575","2df6ad32":"1597","7bd8db71":"1606",e277c26a:"1632",e9dbdd13:"1647",fbad2ec0:"1658","078f57bf":"1690",d580a1fd:"1734","896da145":"1739","327db732":"1751","9c8ec574":"1831","8132774f":"1841",a2899f6e:"1861","3a77bb3e":"1889","5ecc20d3":"1954","014daffb":"1955",f593d43a:"1956","64d58a39":"2005","48f2f8ef":"2020",abfbdc79:"2045",b0cb3eb4:"2132","27004ef7":"2154","250ffcdd":"2343","9040bbc8":"2453",dfd9c366:"2454",f65fea7a:"2472",ba2406d8:"2476",c7462af2:"2540","4fb24623":"2550",c4b4ced0:"2564",fbad79f4:"2590",e1e441c9:"2623","4eec459c":"2639","2dbe31cc":"2700",ae6c0c68:"2729","8965cb1f":"2731","5eab7755":"2772",e2b3b970:"2841","9a06ae3d":"2912","9397123b":"2941","3683601e":"2987",ac3e6feb:"3074","26742c3b":"3108","8dca39c2":"3116","6100b425":"3129",edcfcef8:"3133","0b1c872d":"3188","20382dd7":"3357","1e7c9753":"3391","39db4684":"3459","10257d90":"3477","9a28f5c4":"3505","6478b99f":"3506",b27c3275:"3690","0a7a212e":"3702","69ec948c":"3712","51513a8d":"3859","018595b3":"3876",fbcf0d59:"3970","0e384e19":"3976",e55aefba:"4113",c1fac065:"4206","6fc50b39":"4213",d77304ba:"4233",aaec90ae:"4304",b20d32fc:"4325",bd625abb:"4415","3d96af17":"4506","1ea8f7a3":"4555","9d9e06f4":"4670","89a4f0ca":"4687",cf49aa2b:"4703","41b31679":"4714",a0a4ec6e:"4980",a71cbd8f:"5003",bf823012:"5225","7edb0f0d":"5231","790f17e8":"5242","27a940ba":"5279","3d9be0cc":"5310",ee8b52db:"5316","8c9a8791":"5335","15b9bf06":"5388","21d7c4d4":"5390","642ed902":"5541",aba21aa0:"5742","1057c3b3":"5811",bde25e2b:"5878",ca5b6702:"5945","54c6367b":"5999","7d1602ac":"6069","2e82b444":"6232","6a46f748":"6240",f47dd6e5:"6408","567e04ee":"6440","06eada7a":"6470","7f3f1ff7":"6623",aafa6b90:"6645",f36abd57:"6711",f31967d8:"6733","0c24bc66":"6739",a0a1fd3b:"6755","14eb3368":"6969","0a09f1f2":"7000","50474e10":"7061",a7bd4aaa:"7098","2a2a0c40":"7292","68be920e":"7294","0ba7602a":"7368","137fbf80":"7664","640cb024":"7682","27d05faa":"7697",c3a9f66a:"7832","75100f0d":"7882","14a9ce33":"7924",bced0f3c:"8001",c2ce05d5:"8024","9152dfbd":"8036","3e02a241":"8117","4f453872":"8170","06354bbe":"8204","6009a9aa":"8212","098bf236":"8259",aa0f7abf:"8295","4cf3063f":"8364","20e0cfa9":"8403","75d659e1":"8597","259f95a2":"8630","270470f6":"8671",ab09c42c:"8683",f2348f57:"8772",d1a11e04:"8902","90af0d0d":"8921","9d9f8394":"9013","7680d80e":"9025",a94703ab:"9048","6507182a":"9079",baef5027:"9103",cdb2b1a5:"9119","45c98560":"9361",b3a88889:"9440",a3713279:"9588",d2630e76:"9634","5e95c892":"9647","44b49990":"9652","8f09b871":"9686","9ccb1fc6":"9874",a66d714b:"9974"}[e]||e,r.p+r.u(e)},(()=>{var e={5354:0,1869:0};r.f.j=(a,f)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)f.push(d[2]);else if(/^(1869|5354)$/.test(a))e[a]=0;else{var b=new Promise(((f,b)=>d=e[a]=[f,b]));f.push(d[2]=b);var c=r.p+r.u(a),t=new Error;r.l(c,(f=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var b=f&&("load"===f.type?"missing":f.type),c=f&&f.target&&f.target.src;t.message="Loading chunk "+a+" failed.\n("+b+": "+c+")",t.name="ChunkLoadError",t.type=b,t.request=c,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,f)=>{var d,b,c=f[0],t=f[1],o=f[2],n=0;if(c.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(f);n<c.length;n++)b=c[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},f=self.webpackChunkcontrast_docs=self.webpackChunkcontrast_docs||[];f.forEach(a.bind(null,0)),f.push=a.bind(null,f.push.bind(f))})()})(); \ No newline at end of file diff --git a/pr-preview/pr-976/basics/confidential-containers.html b/pr-preview/pr-976/basics/confidential-containers.html new file mode 100644 index 0000000000..f75b478e48 --- /dev/null +++ b/pr-preview/pr-976/basics/confidential-containers.html @@ -0,0 +1,45 @@ +<!doctype html> +<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-1.1 docs-doc-page docs-doc-id-basics/confidential-containers" data-has-hydrated="false"> +<head> +<meta charset="UTF-8"> +<meta name="generator" content="Docusaurus v3.6.0"> +<title data-rh="true">Confidential Containers | Contrast + + + + + + + + + + + + + +
Version: 1.1

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/basics/features.html b/pr-preview/pr-976/basics/features.html new file mode 100644 index 0000000000..5c3d441457 --- /dev/null +++ b/pr-preview/pr-976/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Version: 1.1

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/basics/security-benefits.html b/pr-preview/pr-976/basics/security-benefits.html new file mode 100644 index 0000000000..6a172ea0c0 --- /dev/null +++ b/pr-preview/pr-976/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Version: 1.1

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/components/overview.html b/pr-preview/pr-976/components/overview.html new file mode 100644 index 0000000000..b772d2f817 --- /dev/null +++ b/pr-preview/pr-976/components/overview.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Version: 1.1

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/components/policies.html b/pr-preview/pr-976/components/policies.html new file mode 100644 index 0000000000..6d53afd6aa --- /dev/null +++ b/pr-preview/pr-976/components/policies.html @@ -0,0 +1,85 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Version: 1.1

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA or TDX MRCONFIGID for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA or MRCONFIGID, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA/MRCONFIGID.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA/MRCONFIGID.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA/MRCONFIGID field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+

Platform Differences

+

Contrast uses different rules and data sections for different platforms. +This results in different policy hashes for different platforms.

+

The generate command automatically derives the correct set of rules and data sections from the reference-values flag.

+

The verify, set, and recover commands need to know the coordinator's expected policy hash to verify its identity. +By default these commands assume that the coordinator is using the policy for the AKS-CLH-SNP platform. +If the coordinator is running on a different platform, the correct policy hash can be looked up in the coordinator-policy.hash file bundled with the Contrast release. +The coordinator policy hash can be overwritten using the --coordinator-policy-hash flag.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/components/runtime.html b/pr-preview/pr-976/components/runtime.html new file mode 100644 index 0000000000..0ddb9b9922 --- /dev/null +++ b/pr-preview/pr-976/components/runtime.html @@ -0,0 +1,77 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Version: 1.1

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled/TDX-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

Virtual machine manager (VMM)

+

The containerd shim uses a virtual machine monitor to create a confidential virtual machine for every pod. +On AKS, Contrast uses cloud-hypervisor. +On bare metal, Contrast uses QEMU. +The appropriate files are installed on every node by the node-installer.

+

Snapshotters

+

Contrast uses containerd snapshotters to provide container images to the pod-VM. +Each snapshotter consists of a host component that pulls container images and a guest component used to mount/pull container images.

+

On AKS, Contrast uses the tardev snapshotter to provide container images as block devices to the pod-VM. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

On bare metal, Contrast uses the nydus snapshotter to store metadata about the images. This metadata is communicated to the guest, so that it can pull the images itself.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor or QEMU as the virtual machine manager (VMM)
  • +
  • Install an IGVM file or separate firmware and kernel files for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/components/service-mesh.html b/pr-preview/pr-976/components/service-mesh.html new file mode 100644 index 0000000000..543e8f3925 --- /dev/null +++ b/pr-preview/pr-976/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Version: 1.1

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables CONTRAST_INGRESS_PROXY_CONFIG, +CONTRAST_EGRESS_PROXY_CONFIG and CONTRAST_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: CONTRAST_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:v1.1.0@sha256:603ef5f817894b0a1406dda625eccd106bec61996a00aa13507b8058a5f76c5c"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-secrets
mountPath: /contrast
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/deployment.html b/pr-preview/pr-976/deployment.html new file mode 100644 index 0000000000..717606315c --- /dev/null +++ b/pr-preview/pr-976/deployment.html @@ -0,0 +1,140 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Version: 1.1

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set up a cluster on AKS.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-aks-clh-snp.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-aks-clh-snp.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

Security review

+

Contrast ensures integrity and confidentiality of the applications, but interactions with untrusted systems require the developers' attention. +Review the security considerations and the certificates section for writing secure Contrast application.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-secrets shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate --reference-values aks-clh-snp resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --reference-values aks-clh-snp --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-secrets volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:v1.1.0@sha256:af86d81dd673338321d655af966557faa00d354a08885b353be27462e6ffb0f1"
name: contrast-initializer
volumeMounts:
- mountPath: /contrast
name: contrast-secrets
volumes:
- emptyDir: {}
name: contrast-secrets
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

This will use the reference values from the manifest file to attest the Coordinator. +After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the +service mesh root certificate and the history of manifests into the verify/ directory. In addition, the policies +referenced in the active manifest are also written to the directory. The verification will fail if the active +manifest at the Coordinator doesn't match the manifest passed to the CLI.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Recover the Coordinator

+

If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material. +For demonstration purposes, you can simulate this scenario by deleting the Coordinator pod.

+
kubectl delete pod -l app.kubernetes.io/name=coordinator
+

Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet. +You can confirm this by running verify again, or you can restart a workload pod, which should stay in the initialization phase. +However, the secret seed in your working directory is sufficient to recover the coordinator.

+
contrast recover -c "${coordinator}:1313"
+

Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state. +You can now verify the Coordinator again, which should return the same manifest you set before.

+
warning

The recovery process invalidates the mesh CA certificate: +existing workloads won't be able to communicate with workloads newly spawned. +All workloads should be restarted after the recovery succeeded.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/examples/emojivoto.html b/pr-preview/pr-976/examples/emojivoto.html new file mode 100644 index 0000000000..3a6fbf6965 --- /dev/null +++ b/pr-preview/pr-976/examples/emojivoto.html @@ -0,0 +1,146 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Version: 1.1

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voter's perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

Emojivoto can be seen as a lighthearted example of an app dealing with sensitive data. +Contrast protects emojivoto in two ways. First, it shields emojivoto as a whole from the infrastructure, for example, Azure. +Second, it can be configured to also prevent data access even from the administrator of the app. In the case of emojivoto, this gives assurance to users that their votes remain secret.

+

emojivoto components topology

+

Prerequisites

+
    +
  • Installed Contrast CLI
  • +
  • A running Kubernetes cluster with support for confidential containers, either on AKS or on bare metal.
  • +
+

Steps to deploy emojivoto with Contrast

+

Download the deployment files

+

The emojivoto deployment files are part of the Contrast release. You can download them by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/download/v1.1.0/emojivoto-demo.yml --create-dirs --output-dir deployment
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass, +which needs to be installed to the cluster initially. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/runtime-aks-clh-snp.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/download/v1.1.0/coordinator-aks-clh-snp.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate --reference-values aks-clh-snp deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<platform>-<runtime-hash> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the reference values from the manifest to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Verifying the deployment as a user

+

In different scenarios, users of an app may want to verify its security and identity before sharing data, for example, before casting a vote. +With Contrast, a user only needs a single remote-attestation step to verify the deployment - regardless of the size or scale of the deployment. +Contrast is designed such that, by verifying the Coordinator, the user transitively verifies those systems the Coordinator has already verified or will verify in the future. +Successful verification of the Coordinator means that the user can be sure that the given manifest will be enforced.

+

Verifying the Coordinator

+

A user can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313" -m manifest.json
+

The CLI will verify the Coordinator via remote attestation using the reference values from a given manifest. This manifest needs +to be communicated out of band to everyone wanting to verify the deployment, as the verify command checks +if the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Auditing the manifest history and artifacts

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Connecting securely to the application

+

After ensuring the configuration of the Coordinator fits the expectation, the user can securely connect +to the application using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Updating the certificate SAN and the manifest (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configuring the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
"SANs": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
"WorkloadSecretID": "web"
},
+

Updating the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/features-limitations.html b/pr-preview/pr-976/features-limitations.html new file mode 100644 index 0000000000..cdfb30b71a --- /dev/null +++ b/pr-preview/pr-976/features-limitations.html @@ -0,0 +1,50 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Version: 1.1

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes is available for AMD SEV-SNP and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Contrast only supports volumes with volumeMode: Block. These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: While persistent volumes aren't supported yet, integrity checks don't currently cover other objects such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container affects the service mesh implementation of Contrast. Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+

Automatic recovery and high availability

+

The Contrast Coordinator is a singleton and can't be scaled to more than one instance. +When this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually. +In a future release, we plan to support distributed Coordinator instances that can recover automatically.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/getting-started/bare-metal.html b/pr-preview/pr-976/getting-started/bare-metal.html new file mode 100644 index 0000000000..5f2a573dc7 --- /dev/null +++ b/pr-preview/pr-976/getting-started/bare-metal.html @@ -0,0 +1,36 @@ + + + + + +Prepare a bare-metal instance | Contrast + + + + + + + + + + + + + +
Version: 1.1

Prepare a bare-metal instance

+

Hardware and firmware setup

+
    +
  1. Update your BIOS to a version that supports AMD SEV-SNP. Updating to the latest available version is recommended as newer versions will likely contain security patches for AMD SEV-SNP.
  2. +
  3. Enter BIOS setup to enable SMEE, IOMMU, RMP coverage, and SEV-SNP. Set the SEV-ES ASID Space Limit to a non-zero number (higher is better).
  4. +
  5. Download the latest firmware version for your processor from AMD, unpack it, and place it in /lib/firmware/amd.
  6. +

Consult AMD's Using SEV with AMD EPYC Processors user guide for more information.

+

Kernel Setup

+

Install a kernel with version 6.11 or greater. If you're following this guide before 6.11 has been released, use 6.11-rc3. Don't use 6.11-rc4 - 6.11-rc6 as they contain a regression. 6.11-rc7+ might work.

+

Increase the user.max_inotify_instances sysctl limit by adding user.max_inotify_instances=8192 to /etc/sysctl.d/99-sysctl.conf and running sysctl --system.

+

K3s Setup

+
    +
  1. Follow the K3s setup instructions to create a cluster.
  2. +
  3. Install a block storage provider such as Longhorn and mark it as the default storage class.
  4. +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/getting-started/cluster-setup.html b/pr-preview/pr-976/getting-started/cluster-setup.html new file mode 100644 index 0000000000..11d2377633 --- /dev/null +++ b/pr-preview/pr-976/getting-started/cluster-setup.html @@ -0,0 +1,64 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Version: 1.1

Create a cluster

+

Prerequisites

+
    +
  • Install version 2.44.1 or newer of the Azure CLI. Note that your package manager will likely install an outdated version.
  • +
  • Install a recent version of kubectl.
  • +
+

Prepare using the AKS preview

+

First, log in to your Azure subscription:

+
az login
+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, create a CoCo enabled AKS cluster with:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.30 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation \
--node-count 1 \
--generate-ssh-keys
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show a single node:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
+

🥳 Congratulations. You're now ready to set up your first application with Contrast. Follow this example to learn how.

+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/getting-started/install.html b/pr-preview/pr-976/getting-started/install.html new file mode 100644 index 0000000000..bb36c99929 --- /dev/null +++ b/pr-preview/pr-976/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Version: 1.1

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/download/v1.1.0/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/img/GitHub-Banner_Contrast_2024.gif b/pr-preview/pr-976/img/GitHub-Banner_Contrast_2024.gif new file mode 100644 index 0000000000000000000000000000000000000000..d3ad42cf5c1b637602d4108a40717d6d3604ae08 GIT binary patch literal 1683202 zcmaIdby!nr*!pB&yT&D)Rlh1$r^166k#YmS}O_ncI=AeBdcR?wQ#!`kvA zW3m3s`2L(^sKd7nPfyRP;zJFA((>HVln7`;$Jbz6;< zGtG6!zjXI~EugMi`(7r{#;k`hXJ~oWnv3SXr!lm({sf@9-PUl@0y*}#fd<$>Jq-8l zzOHmMow#Z5w>6&N;=To_?)Y0n-M;TzNKXd-gtj)EgaV-<0BBR~v5UrjL-Dq!5%kyh z{o>sHio%1|%3Ze~`|XV<U zsW_@EI&{=80jljr{@QcXfqEM5mz9;3+0{jK|Bz1X33NbwgJ@{XNPe5Be0}CSu3VkCJGiyQ0lg3s`3Nu4NN;OV- z7I|AyBU3Xe7dxYGE(*#9E*1v7hLoR#CvcqsK_W#=^$& zk%j#u3l|eBD<3Bt9}6eNzYj|I2JH-u`IN*Y{@on>nINU9gM%&K$BzI2fEmEfY-4Bg zk(HO1_ah72M>aMl_#903&ejfkKqhPZ_y4Uy%*fur&dk=q%*LAH&l>ggZ5$m0Dd9W& z&nT>H<>mip#n$%Bf5*gZU}Nm^gTN^qBNmc@3F3dGuI}j9551xsAF0ThITwJQoN1XKqn;4pBA^ zR#tI|&)gE9CD_GTIanlkKeMxP|F^8PwY`I$wSm!p+cx{N?SGbK`~O{*Pt?vx&%wq{ z*~Z55zY{^x)W*Ta-qgmHf{l}zm6d{4UeCbH`p+b~KX21NqZTu=GjlRBl(4h0qWF89 z`ON;0eK6o)Vb|y7g^%Bui1xc20Iq%72$P{9niKpHme+ z1wIbj|8|Fug-c(L#Xui^4E1<8m{>SD*qC^XjSZNL4Y}F%jp3&jr!gnxNBAy&{B!F3 zuT$y2N$~UY&%gh3ZNQ)W&(&pQ4Zo!9;MWcU?Dx~-!~Nau&Gpsg#rfIk$??(Q!9H|v zcV~NRb7OsNb!B;JabbRLc4m5Na$@$Jaxzj9Vj@BU ze7v`BUgN&P!Nz)tiGhxWih_*v;yEJx6X@OD3#8}IJf1PaKa8IJ`JQ-&0`o-i_VM-e z5Aaq94hanlHi(RhQjCp@Pl%ODN=`{lQp?E9%Fd9;%LfM#sh{Ca1>V&d$v*EH2ottgfwZY;F+j?CwE#tPYQk zPfkzpFD|dHZ*FfaA0D56!=53y5J=hTrud+~rWd=-%j^umA@)v`s>tdNA@~?Q-&c{{ z8$q@lNFrUC(;q`k3fAtg%pFW%KI=>2y$Bgj=CR*j>aQ|U;QZl<{!+#PtjH-9L;roC zx?nP2F#?I+k=thR5K*rRlCC(`~fp^nhwy( zyl>e$B@I{4C(8MI-I*G>j%FeD2P?ykbtkKBJ{aVs$s^A<`yv>=jJVZb?2M&PCMq;H zTpi3+S*(VCM_)W3)xkmGN|QFdh3-$kW5^#lh-mE6n}bGi2H| z&ll(fZC)EIjUXz`jE!K% z+CBXcp)T6ZP>vZ>gD}%AutB)XI=H9NHIKVDjX^5f-P9I99O^LD@6&q?bxqQ zdfRd8`ewcHat_e#1YQ5T56=zb&2|z^vz&X9EKBD*lWlwGc2gWi=z3Ct8ydZ7I+xJh zbPuI>dl|lX^n0%ZsSEeA0)MaVWk*WTLvx~W^`N;RV;3_rG0Symeuh6^J2)rae7^vk zC$mpdT)R(S^s0;gpt!onrK<$8Q^-)Nbh&>})^;t^UfzXgaahquU36GM!f|j|H73Du zR6QlL*i|!UTy#{sB;&Z@u=e1%@wA8Gr0H@-%jWI=28LJ5 z<4)sA>n$=SOPk6Y%hPsLn&Q(AOzy+eP8>;+pU6nxwEbY+1Zr+)J#PR*XFV#6YrTC` z36|&mwE4y71B`Wt=YuT0j2A;3vz8abJflr*FUbwZE=Gk=US5ug;LBf*OVET}j*47i&P3<-j>c;^rD6%n#QY%=Lv+98&oi|CCAdR0`;8yH zFlH7`KwuoDPIsX0T`+D;Usp-jc93Fd)|+uV{HCq#VAZA&-ReMbW-Q~7AD9MuR6d|i zs-94P-fW`Yz(lTwvoPDxO#`0yNqp`-;o1G~$dvY|X=UpR$(+G;Emob?;(zFuu-@e8Uc^B@hpr(qJ;PDlG=T%l~58f+_7atGSoKl}2084NaG5vJD%%*rr z2N`iJbx54jp_MO?Q5#Tlx;ps5a+J_!%vbIyeVE5HT%h2X#2R^ZnNM_4&?6u*72!u= zA|+p_lrS)r$9GkrXrzJa-BX3B=x8Pb8>CmQE95A4ReWdWfQk|uA8s4JV-pn z@GZAScl2>3Xt>yz+jV{!dR&$E(&|8+dto|E)jm(2$xM8(akZWcSmu{@V2mO#<9%IQ z>sMlJ@z8j9cU{-^veY&}c4>pM%(YMO#ce!;kaX-x{a(oNecnOKJ`sX@2`Js^r1$&r z@k!&uLpm_=bK7}RohPcC4HrS54zkc`^Xt$u0cNQm7}lpPH%Anoh5J@{LQh+1Fi+9c zq}C#vPTQDMGQCaIMU(bU+i_MhVc0Z}o$oYnI|vklRjNDIUw%C6l*g=ioiDY4n+#!6 z2@Sz7f^0AcpLOdlVT8^GN_6#|_3(^Tgf9bo$qu5zbLTfr{4I&6Q>Y`W=%}LO7>SoS z>Z26HD`NxLrKL6N2V%Q&;_FiSDR$$!?ObiEOpYH9R-a6a7iagzd@*IZ53E-FF0rjUuL-*0v?z7wyG zrS-eDf#kwuVR&6rXZ=W6a?{+sTV3;Z{aAp)Wfn21Ga9PS1XB5B9>aHFe^|p!{6q7O z!bbg82=jejqtHPEc4OIC>0^Ve)1%kTVK+h9!swvWMd8iSThp>7;#(b*ftzD1aM=oL z;A#toSS#7yM^qTU2n>Ok%nwOHz#AXC6Nz7l`enSdFAcUHx|R?v;Yia?e&zbed-1Le zlr!8fa`zKoqPmUDe&T)mgvUIfepMP!acJ<^&6yX~18IE<2aGl|Yn0V*Q-Q8G(yLGwS_Wrl@!MRa)K*x~uakj~j0kb{bq}*?gs=G%U1sLP@ z&~Ls*j|9MuQJPo(?!DI9=5T56Bm+8!w>HG_`Xlk>#T2DheGwUof z98;PUCz`ZtGf!OeOAhlJLvxb8F9kDSih9hm&dsTSiWM{TRXvKe*NPD8uT9t9jmVa4 zsFvNTK3ud)RE{tvUQ_0g86TlrAJ*-UpVhyK@mS3}`AUI&DJHExcl#=!T8oRLK)L*s z)%{d~e%oA#r?r0f)SO=oIBuv_za!b|psE^6sp@q5X~y}V&DiMMtC|2gk+=gKc+{{> z)U;x30e-evvjMLF0d559p0@$6qCfpjf0CH|Bn?^CZntkl6uIxXlX|?%i@c}}b zOa+-~LOuf=I(S06AOc7@0==})`XQlxbD?rK4x*z@j;h?q>IsgTyJ*_^ zLOQcTx+XAWeQqZsKzN;})BY`nd7YEhO*p~}z&^)y!?iBrat-i%4%-tS z=v{~7OCu5hh{KMScs4f$+w~1-;PBK$hXn18PRbWMHE6<<13R69tz;_{!8X zGgLCGfFX^2c9pjR?YEg^1DT!Av%1x@s9m!9!J!>7S#;*wlc<8z1dg+NsPo{kMIa1q zc`t002YnrkzNsEw?HMl85PmQhzKIke#rN_Yq;sVnaRbJ>14leUB4Fyd2)vOmG$L`l zB2fz>k!B)aqDA4*MFAC~j0axh&x?ZUqAZj2G{*I0Uq##TxqQ&bchbZ+L2v~I=QCZq z(9cJE-bdHZ;`_L`vINBhCV@deCEF8-G7(}UiQGQ(7D)R`jhGO{2ge3>#ilG2KoH_G z?qhpd<8lg()aIr02c$LVWVEEob?yqE5aKPk;;S{|?fm0S3*sp|;;o?ZU2hV8@+LT% zB>*%`T?!K1q(8XdB`m)It#N?jR6&73pkO-Ww{xIh=b%W!#1N6hShK_=T$pzvlrBZ1 zGNg0w`^)7>Ds*PLtGh+QS#$L*@<`Zcx|%8ZSo7Pa+FQ0 zE;ANX2IX!jE7MvE4siu8e}&XEq9&)!RKFiVqlz9xm29y>;dSLkK`P0C>Xvkx&Zhs9 zQ|11AC36Uu&m1ROet>7TE!Se2*RAczU7Amv+S`D1ub6bA-N4`T>9GX7q88OC4b^g5 z8EAzWxaOMZ=9witHJtdFIf22&pc=dZ&3dp_t!N1UY>04z79n3&n|duoN`T5G%le^q zzB7w~ug;cVK!GM~4C26=q|Ls7%IT8Llavju%08UT2A^gN%X|`XfrX0|hD*@vNE6kM zmgk^O!~pEG=q{b(;4uyGfDh?j&V2O&oRc;ui-xF^P?OEQWmw)AIn z7a+E@!qDB(iQb7WtBOvY@2ujG|_$!u`Rf+p?KLdnX4 z*V_FT5O3+0d1*>eDSB?{%kI+pjnX#UGG=YYOQOy(yD|-NIBtTIr(ekH;r9#OI->>NaStSlZ4%bTB%ity*Ta5c7wScCbLUTW#-T zEh%3}_eDrv@qpvQK)IauM|y!t^}*^;LDvxNU&KQ5sF0oakYr(qp9Lh(6B49_5u)W3 z7UC4~@G1IXDArXto*w|h_?$%iIi(Sh_E7JM-;l)*Yry*2kmuS!AKMUG*AOw=Q1;MJ zu_#*oFruv2NYXo9E1(NqEu@0M-SkCkBKl?W(o8f_fIByDc% z1&i%~W6%p;%NO+SHshBVt~ZXS$h44=#_bYMEY`I^*MA)@wj7_eoHDeY%eIynw(1A9 z*5!fOX-sI6~-ZtjjhF09B($V&Ptqq%m`jwo*Yq|C$TYR|?1bv>9Rl~8MvNCmBoIa^ zN1Vy-^6XtUC=*BNb@XZO@SckEEATg848x-R`C?G5TrpEO`Gg2xk&e5Hjn5Hp&4)BE zhm1=*7pxAB%d|+5FK-RLn^06Br4l6l7Cv!YG@;%$!FV)L{9!0`YfA@uW<2fPMU8=5Q`+{9NJ>J zWZYco@BQ*)<#)my6Z3O3y#DX_;qP4KqI6I4ulesWoL^pZQ4^=7KXLBzE(|Ex@+Ak@ zH!Y0(Uf|_F;$-Lr45?KME{YLX*EGX=>ji@z&4OBn13SJS?}YPyvEc1aJ$|3C6vEh# zEt5IIr1@I&Wa0br4~u0YBCSDoEz6MFe9Y5Qxq;2^r^ufKnPePxNW*{(&klzLkDpMR zNmdnERxiJ=-h{2r<*xP(t*&gZt|F~Hy#P2Q#-5=62GQA&31LYcQR`+7!`1*}(JGg@o?~)#{)69FW=9UiN3TuPT`^Ia$-SBVe0&3Z zg9AeS{lY^cf}>(0qr+l@qTyhhmi`B9b8_=i5F-lwikOQ^N(-aQDr+h#3hE(^HPv+u zt;Nli4QDlk91YxbumMBP6Vz(!raIt+ald?A!1Q%O&O_I(E14&v6(O?oZ+@Ss# z+HXls9e>1@F|02|x@t#`oyUGduA?e{G+n?Ml~kr0Jf1CCL;H`|DtwSim8mJ5F0`mL zUmmC_nl009R3-Q;w#Mt=f5g_BwJ%k+u5^hDc(K1c2srU;^?Z&&CI@6m?hJel2U}1@ zKyM^@Zz3FQjRtJkELMhi*+HWjq9J7RE*y!I;BQ4bB@1B(v*iYZX-tb=u%pF4Vp~ES zakARlib}4~1UcL6i@{gB@cS#a{A!~AiS0;pBjA7-9Dt3jGYq`g8!h@W>fY>nLA)`T z{-w3$U$IU12)u(`;jej~y@Ggo!9J+3d12D;>H6RZ(XM-;sm|&8;rV-J`ja@#z4IgU zr`-trE4H+G;EiA+p|On+X8*N~P_`CzgD{Srz|C;JYaW9LfdSBF#3yvRt>@yDygAWQ zWc^z)f5BE+)oeRXdE(47UfUXKl%VTQXACk7m+nn8%`4bRvaE&fBwM0?4uFHLnMo>O zM`Jfly^ki|s)vL~{);w#W>Y}-31 z|3_@e8GAY~*|mE+b;KCYx?X?NJL@Jeu{?WC0ysSDC4o_#{{yzvuQUIEZId0Gn&15a zTY>grp55Y$5rLb~3ld=zCXTUJZ>%oIrSN}sO~`Q{aZDFq}7M;-CC z2vMB7tw>qxyG_s!cjveNPi%7%tnZ;YCT;cmD&@y6du4Sk_lK25)~-h?)oZ=SO*h96 zCv7PIm)NelVvrju{<@km@o2tYvN`#6v*zK^e7mXjK9NC$&?X|h18vtR=z*WH ztYKq5f#n&fpCO;ojK_RG$myY~fIHs$kNJJ<^2K}?6-Z<)@;d36-%Ey{!DRQR0e{7o z7F`{+6R(6tpEmLpCKcH@zVuc%YYtDCq4F8=Bu+19ttl3>lMmtItv>$pPi*a`O_BrQ zZ2k!lmUH<}3fs_Zl3l4@z6DkigrHuLH@M-xhpgltTkl1Y39*9-&LgqM11VWIq9mfX zqA0%xQGG>>k!k3n1{DV>I3UI<+`pj9!2F<;Au^yOv`r5OTjh?90o8_R2GgKi#$Ln( z&4qI&r~VJ$?>h!{HgZ|oFsb#3M2GabsM(_GL)n-n6OFC&IL1P$&D2GQ&C~q3U~@w| zmcY(o>tke|HRW)gUg?o-vE7u3pb@}K|An=7Ui9aAngnY3`3$HNq((Azbcy8lK&_+=qn?`Q;}1z@S>n2h)V z<#!bO1^&^o%K0)Xl1BT5>PW)i+JR}s%>5!=(znGuGBaxP`^D88ahi^t#kCF7YJzUEEC-0<-ltx5f{60`ln?YMdPR8|@+^3xsSQUYiO~M#hk>2Df8Nn){`nU~q zU8HUmphlp-{wQMb#>1M)i5u(dl)6y;x$NrSZ@-}w)b%7orRe+WvA@Q?ecZ9M$ENU zJ-fv06<$ar!}y$&K~vc$!aeamQtpxp->P52+U%?5!bILsHJwVoS#i_( zWQPAXqvZE^t)%<-2DzG#YDf5b4Sb-UP{-mZv_zu?KCF?U8V&%Hyv2P3=K`h^SF^OG zjrVJwZMoXY;lvT+qKnkA@Y?Dk(X^|K-L$zLliJCPQES(S#ow5w!Z$u+K12?mpId<& zNRu-C>;kjih`$QtlR0r&d{`l&Hw!&)&W+Cp$(aOC`tv`o ze>*q(Lc@HPj&-#`KvVcNrr|7{`)bq6yRffF<~;ffeGzS$vYJ}Ud3l3?icuJ^#<J|S91A{4kgh7tynyvBCGZSnnY)d>Z zi#OOd5)#JoUO%r*NanoAfF`7SlE|#y7i%US4mdvX-a*Qy!49V6QKk{qrZH2d@h{90 zsm%C4o25FK3Gm1yUHg0;HxnT+7eh7Aaq@j@Yc3NgTM#c>eC=y>YOcg1SE=e3{@H@e z)?zT$Vx-GLhey5@&%cAqe^J@ec#gPthj_5oe_#h@X+1|Wi5FnkM>^d@Hk)S!gjgLT zSi8*yxbs+J+F5&{20r@`_|nn(AU^OA`Rl3E*Rz>GVsD#ho}gHD$_JObGi!mZ|KIYG$Jjh~X@A#R9v6f|~r_C2Pm8~|0WI#u4;P`oz#F)1~n0AyiFCQ(3`L_(NnoP$@5gYUG%mm3Eq z?(ka?M?`zaJur(#9g9}4?mNh@4jzLM{PPfQxHbS_Ufc(>r`|) zr%gH^T{%NUQ3`INSqNj;cw_Ro5o-ail>sqZ2D;6&G54D>h+Vp`cU)gN>8-rh>rIFq z$&Zztk5#yfr9uA8Eb(i0_Vc*puf>F4?0IoZ`Ee_11{?VCEDi<+((V#mqK66bhjs4! zZ#=B;;%y5IuS`6?N?_`#8o>Y_>Ul~%p2!3s9c3(IWe|ob$TUwJkH`28kJrx~ z(CITToLjG0jl_65NjE&~L^^DYbra7VNnd4bdayU+oHsKMG7EtZ8yJ^EU79OUn#UBG z58@-Jo-B&s3#or2!s9DGmt5@Yn^Oz(?Wo6--}6<3n12JMc_WbREX?q%E=MDj9IRVE(0qz9p=XYOxX({~G z18+5~L%@OiGuC+9fiMlqGu1z0OHyM))olZsv$?+x!n#+Y7pHnfpULQGixOa42+AaK z`Bt_UOlJPGk|2v9L77A{i#Q+z0uK2y9l|K1(h9QcAjnP?3GD`kauw3UC3mooVFYA9 zew*FH7B;0G=3*N*2M&`OU|O0BTiIhi#SK@G4Bs>jH;D{am0>yP3&+_EfBQUw=zT<{ zN`yWi+f85uYj(uLT!eWNj2(s=iIB+gJW&g&UkgukI0WAO9YeCMTahc<0PYL2@B}!oio(&nNd-v_1t|mkuAVU&NipQQu37uK zBD}gd)SoUUUB&uiuh`u>Z(_>Oh5G~C5S8^56N?(q<5-M^neYtS2I5rAel5@#=%B^Z zQpFDh8?4pE?*zp2cg4q_qVc{-m~knYLr1s2Gdx#I$XQFcH%V}+6$KcaljS-nQ|Yck-rmo8k8cr3@sd3@28O5~fb@rl#nn z&IF~l)}}5(Q&-T^fGlZzAtc*D3bvp$VPdNTvj9g>fJ9NiMPju~2)QS%^^Jz2PoQ-m zNb#{g{dguY!u0Fw+#2MC8XXH8)P;9?uJ6$sGBR#6@X&*^)iYn<2TO~5$cJRwG1QT2 z){!@SpiHX6H_4Lfu9Ni3lF!WwoXGMeru!Id$Cd=)xVPhW$>ud@;2+2qyjK-Q&k>Qy z5jW2fNyw3I$l067Q3zI7Y*1ICcT{%CRZGg%9}CweV%53N)xBpm;L9`GXS)l`W2?$* zaAmiW;jjsYas0gJu-D{t(ro%3liwG@^{b%?8x1^u)%5E<*pIJy%7Q209vGd_9Ny5p z)aaZQZNI`YA8Z>YePwin@rHxhTpX=Z0kX9f4LO*eZF|Gp?G(zO1G0rm61UlZk?y}Wj={7gA2+u9Lny3%a%{E zgPnqJ2rQXs(2R7kN9(Mj>P=+_Z>8hc$`*%8+T_Zi`btJELgt4`mIpt!0}GC#RIbHT zp2n(R0TRJQ%g+ye6L{p;U1^e9{YMqmpp^a>HT_%H)jN1Ks#-N!q3^UXGN{=yek2bR zT2cy&)Fu(snh+0~5ohMi)mkRkz9IT%-#FM*Oy%@2SPHJ|z@%{xq3JGG_9TXQ6RY?w z4u#r5G~ys^4G`v82-iKN2DiSEtv*((ejHdYR#=}rSii7W?}OB^j~Jevte#8km><#r z1veBgHk2i^RxmVHX+_i&X_^E#);BgQjeW+r{%KWU)3>?J0>c;R)_I28lRz!Z;1y_70iiS3@Fi-P%{x z;`y!(G@9GVm!`uMOVZZbb*(xKzt4zmm8eO0+~$`k$IdMBmF}U>Zt=}>r5FeDmhCTi z9#WJE97>ogdkG)TUf*NI6#Nxid7SiuxlCScHAYj7A*uZS?x?M98iXD_#vZoMJw_yN zOqP7iFnukGWvsOqY#C+kntUCaWSxd&fdYOmO}*-Kz3z{_Nw5061^T9y`wW4wJ`+%1 zNK;=}s6wRn(#qF>*`H)5^-B^({Uc22SJ3{O%ye||noPH4+>P{CA_FkAprXg+H6}_l z&00+JT2qF>R356Dq1xIe+vdlW)1yHE#?V{tq3dPpUOAdOL7M&{<-wt$k;9>}P?ZUi z>?sn}8Mn~66xD?khNVN*mB-=9!1|3QwLfB;!o0VH1Q*+@iIIq_kyAIv^QPRA1EecV z&6_3GyW-J@N4BTK(PyM%&9Y-iR%5b0V=Xmf7)N75BM7fZw}z0wBgD;bg2ts3z(gfc z^NZsYPg^@k1yoki)tk+bZxb6@1%!&o%*)$4zqi>mkU0b=Tk|J#?qRJ64u!A%TX~-* zkwObaj&`0|x{=Q4)woOn({^P`gfSkA-aNLkQcr*TRs32&1kY{n2PxXv{#z(R_3YF~24Mnc1>9!+=Q~5tB)pnIUQAsPll48L=>*p#=}IK0@gvuKRE)Lv56$wb;Cc(Te$Ht_Px zQ0mF$<SQG;((J81*IYJ+iQ!{BCv<#?2xebbzN zjLVvX2aA)>np2>3?9=g>NXvEq+bA)eanG17yB|@qBT@2LI*MsG;V#kN$Xe*pT=p<_ zyg%Lgw*DxV+%YJf@ zA6}dnu?Ide;NlP+Uzj#S>o~wi=dIoo5QEl67}6e!$@;>e4)cbCETwKx=$^R|3+8@S z+DmxMe_Yr}q;CAHdH;?c%j0PO%C<|~?Wrp5sWSZFHsj!Ct;@3~@vEG7v%6Gl%c~fs zLq*}kZtKIow8QAy!?fi?(Dh*=-VvDN$V&Uj6am%tpTyRm;BR7U6&V#B6B~n{07`@> zw#k~`Dz5qeNo=+I%Ks#`?`3=mMD)6S z@L}xwmf)YFk`ct5s+g>}hVaJrTb4HOIhAw-lU7HpbYal|9& z#mza)#`EPeWx`|};bN-!gr#S1<2Ago-3;USov|4%aJ{z~A%y$xPh-n# z2MCW44<@vQ@B~ z=63x@Z13m0;E63uT( z_J1|D$B@5byO-B^^qhPtvK{552jisad`9-9`Fg>%v*}@=@ucZltLsVItvgP6J0eZ! zX$Q)4xzqMLKE{eRWHrp6-EY2Gp7mhb!^M^&fbn0kr42arZf7WJ`Z>sGk9mQ@G<(Q8 z#5GA$H6pOvbUw=Zuv9f7{5P>}jN}-WWf;DkRDhAxOv!x{teIB&@se{!#$@^bNNksD zp8e<~y;*daE#X)KHb!#K+ui)CTk&|#3|aL-IlftOrqQ`w_hdK*Zbp6z2W-G%4+Nbz zE;v7L&@e7ar~U4Ob+3pf$P-Ab_eeYf=^^Y{H>U0KVk z)83D;$FpQT*wZylChYg)P1z^xXPEHB7B04UiWvWjEi#)TB2H+=3mU0*w9<8Nf}sp# z?!I;`7h9jVsF|peQXRO_IIn2s*58q|i%2MM__6qk(HKjKD#UL1^Dv6jE1doQW@3{p%%=E|cDr`J4#1urQ|^3{UFU4dsIx|r_;&d;zs z-}q9P3S<+}boBgfY_9w_ zcyg&DLbsGkMWlzI#g_pq84U?rVO?K^o`d$cI$M+8{J=;wjTY71iCq2B$vzs)O z8P1hkm1^xW$+wA?&(m$6c2T^WaxR_Ex0s#o)WH7fS@5n0y4WZJX&)9AJh4qw%yhqJ z7a<%_3`CYu#EIL>pecMFf>%gM$oocu2Nnzt^AsBo{@o`HuDQhBAkhst_!MP00WeF=tK@^9JZS|M1fdU1+Enm=7=nfpu2UgW%rNTVTrbOy`bH;XKhq+CXkVa0|tvhxGM zmd2oE!ZAkws%$eS6H(%%F>eXYWX_jnV8N2!JXopFrT+6!*3b=(_>UQ7yX-Cql`gB$)cB4lYb1A`X|ziB_yT253f#i%F2NICpXS;yio_ol#Neevl}Vyo^$EmsjN3huxw zD)(av&kSYy+DSCY62Q}QhV^y5ldSh$pfGb*WC*B>5IKBfJ~O_9#9ZG{a;U+K}2|ORf*IAIc^>>5GgAq>A`(mYo9QG5OT8H3Hz; zlEa+u6MDEC^>oUSr-GsNe`ZHwh?nD_#!rp=V*Y`_Xg(+Vt29(bYazCHsG5O$I6=eZ zezK}M7c8DSsFQTh)+Xo3sy4hoO?5F{VwP8IL^`aAlAi?0qvirM59@eb%q|h;mv?I@ zT%_0w9>`t0t@K+01}^5s!6t$y^`qvW_R{Cl6opxp$E@)$Gd{@BiW1(B*~wlm;mOyD zvkzEPT2^P1zAR|km7icry7x%f*Cd%Hv5iF+7U~)JD$Z8y~k>(q|BtkjmVl zS37`hwRWf9v#>6%_;T+f=P`W#3cu;M22x)dCP*#RyELz%iV+P{9~r7fUGS;}Hj8KY zA1cRoh7NMxTFr4=EKDVRuPOXhVo@_wGgl~RUKMw=P>)<&w~Ge>jyA4%F)Xz#9$C8E zFxzKq)$S?)>PN%{Hn3WGdWdxzBTq`VsayF50%p%sM89uyd*}=os9hW|**H(~H=er8 zUS_qH?W>L6&rFuK)NGa=Mbfx#&g-;RJ}*Dc=3ZOD2f3nR{q_zxS=*4jy_Eo+J~0lt zz2slLBMWZ{5SROfk#>7OCwUfJ_elib)x(d)cs;at6`44B)t^_PmCor9f&2ld?=wl| zBm6fp_cXA(-wKA6zl+ulEu`*Xih1IQec~Fbp2)Z2-;E`7sEsjEjSZZPaR|I{!II{9 zuPkeg2|&0+QYIwoCLDUWZ&OWCJt)!`J?&FRad}tS-f@W{j=o;{$Lit%x?P z+-WJ-xF|QctQnQ8u^p{(bFG7cUyuC1o*>&Ou-Qb@DqY2YxN%at&r^DwQF=BT1e37M zkb>EwaR=x0(SGW-1<%=HtI@&5w)8gmOE-N5k4iP@CpjPlVyg0v+pZc>m3o%3Z7;-d zn(;l3eGf3S4-`5uXZPOI9!_yW0cx%v9HvkmJRQSCBv~eT*nZ`*`fZ1a)v-oQJNR%q z?f}F0q#QrQXuQ2})Ch3=fgho&=5#^pWCDmV3ven>;V5|vknZHH_tUcK)U2xkAUj8* z1_65B0`(2FJ$54xP9uPOz`%6;;VRbgn2L~S8y0baC8wR261L8B=+>dtM%bs}%b9mSW zVZg=qRxP2Y+yi)r`LyftY%W2C!_!j(3xx;d3pF|xmcZEad8$#+2Rp;3%R;{ zPPu*&rsx23bAUY!K<~oInh#)mpN9rdY+drvHMFsLf%aA0p7}sLG;mnm_X$ogS^ak+ z!st29XmUcA;DzXoZE*H3->IJqn{xpiY%h`cIHY5W0I-<4x*t`~3kBz6KB2{a=0z5j zjuj6QlAPC-M$?luLzaieDmoV-aKtqv39FdJsoxb*)y6ID#=*HZoFd*pBi=A5eyA|s zaz5T#8sjHng1woclUaguVuEWBiu-)YDh|j~1GFInLIYz5JC}x{CGIzrV(Up-IwZzA zOaAOhyfioY!1Ef|V?qfk%QQ>+eP0$Do5T{BR63u;t6rWWCY_|5ToaUx^-yk;nT$J_ z3^+^1BQ}@gAtcn2?KU&-MI#y@tSo3xDZ5UgCQhxDNS!iE9q~$?FGyXTN?pE7U8hUi zOtjoFOWQ-E*so8!ol1MSOq<6`zm!hDrbG4t!P4m}(;w&4xe+s-(Pv1U2OBuD@Go~X`lknV%aPg?U3#-uuz zBF46kx}NhoY7|vYJ_hQsY=2isU^2wi2=R<9N5sXR3&kOzCTuY3!kR>!M5cqMH3r z5SO;bhN5Q8Uu_F*q*TR=lEvT6io-mMS#yd92Z~Lg#iI-8+%9hO?Rp^T7#= z`z7=#;wm#8oA({aAc>>M(mfZ6Lzm72`o!ZTujnA0)8IrK)iM#cvPbkJ?-%88u?=x} zE7|TX|Ja4BRj$OCd6%J$PmsK3 zi_vHEPLGeAh;;cKgHApCV=sO+nRiBZZAYRmHw_l$2T3+hHfoPMg5NN;thu%-5Q>md;F40r{78)u=@RMsMk)O)&eYPxtC~7CS^PC4N8=9Aba7oCk1S^hDsG44bom}Jw9YF{pJw^8hS9tdSItL zp?jv`;1uy)#3+n!F>0^l3VRcrsFL=2Q_1>NB>J*U`m{azn5y~;_WBkF9|MUkXJ>WQ zZMAtq{}y9y)IFbVQoeCQw{bq9k-vC!ac)#NxM`+J<0W?! zE$vvi!`N5yby=)t#=Ef;tB4avuJVeA512ncN&U<-8b|dRU(Xol92`Gf9p}B{<-?2; z;Eobv)Dq?16fe?}+;^64MEUw+Qr1*kuE>SVX_7a3vbuCqU}{q1Zc>b3>Y8;*XTL~~ z(an&1TZ0)#U7_9l4%@O3wvCh9&LbK3j4h6fYbS%J<8%klX=B>6ai=gDKabechr86D zdp97dGmOQs+Ql=hakpA*rm0vw=Ea_S*i0bbUQ$t4$_tXT{jLmW$*dsn989UaLGOY_ zGWb^8_@d0z$F0Gqsz|!#&Zo9$&ToFM$=S3;owAL4en~GSA~B`+?p6Qb{9uvUFy=yX z1J$^5YP!jShR1?I`hr>8LjLVSF~cHC3Qfg)b@g7gMZzME%&%Qc`Kqn{L+7LBS4%CR z0W#Ntv!DUTk)>C>$5cxSjxU$TO{}gFltdhsncgW)#agppd`OfST!##jpDaIXI#JjO zX4PIHCqGrXP(DV1*`Cp4Yq9h&;YCowH zaZI`;+lsqI6Lns=Eh4|mq%AElGu8!W zaN0`<+fyoq?F}sMl^*RW673H&@7F5q5C7W#{s@KOVX^h*@rN(A!9fOL;b9I@(a|XI z#WpGN%iqQ}Qz$ntzaUS&xTLhywnDNBjv~}xG&BMzLW_QTM>{thMd%;s*BTxfu^HEx z1QuI4_+mRN14j{-dEqF+&hCyNfFd0Iu@_VYP=qV|zbL|!;{<`yR6Y+}JYcbXzY_Ma z*wSRdQ3QHf=mUxXB(}FbX#k2q^F3d!S5`M7=Dl_wkl4ZpTV4JUWh?!Nq%W>$m}qH0 zV*6hdAx(jn<2nCifn1SMQlHH(Y>Mt@d%%BHgaVc)$~BrReTbYjeQGtJeFf#^oRX#g zF18Pi?SD{&L=c}32E}{hp#l4f&7oA@zy?Tcce&SxJkYKVr#kHcRIN7*6w(#y@0xT zQRwD$YM~-T=0}tB*})&rB?_1e?Dj8;Kwz-^4@F?vN_~XR&z9>YPQ>Nq7a>GwGouUQM2NtH%2;}J9bF$MZ<3EjOO=&=4dtUI4=n*o*A&}Tg!rl}ART19p zbpa{@(AYkc*=qqB+rpzRGIMZu_e;;)&i|qay+%%>$Nfy*7$^Nk6L1vaZ)3Z6GR$V4 z>NCQRZOS|<0-y+E;;e(GNMA+Zjjf{T+26!g#n+;0n$(T4dQ#gL(`LpX!L)kXq-5WA z&Z4=|7UkFY;Q4~)s_Dg|)5ZS9k{j}W5?fE+(wg6tGzV-8VBSTxwMbsGtF;*Y;H!;z z)y3M?WY+sfTd|%%Vw;gue7#dxbMSAlEf_y?+lMR_J03LrIRMsam~{95pa{L_e7+|m zyzgMnr~F@e@6JXPOYY9+?S{DtmVMvdUoPuw-d}Cyl)x9;W}Zh6i|uJYMa$jgW(ly^ zo|t#S9u`}gmNx*3@UYnCetE-o=ngElPjbGrqNyBuJmd00Vx{pD0Ude<$97OL@$t*V z9(u*S_eN7xLQ{ZPJTLQGq1V$yR)-$?NTT>)*+B!fo@Ee!!Fcs4ov*`i;xVacr4MU# z52hvCH?ln-2;ag=hrqQNOw1Me&myhx$pbeJf3m64uJ1hlQS^DMI;s;VOcj zJNld5^q8{wtO%Q4bd9<%aqz_!Xl&^ed;1jlvk~ivgBY}dzcq)lKbOp4nApZi%rpqI zbhKs}dbKBLA#}%d&r5wY#82F0JBb?sXER%Ue{rNV&RLU(Wm{)OeyU@|Ift>yT8}zp z=`haqM@-*gVw>XTG>7MACB)?rUj}r)nY15C?RmeN>T-RO@(9zwi^!T14{?j1WcI74 z%33-;`-C9QU8p~mc!od6gs=dAxUgyED22UThFJVq2uDB`?T775N}Dm!1TWb)xV@QL z0eO=8;^XmC%#z}5+rifHS)Z>?B^8an$GPofa{z;_?JO)p_UJSxn_wr;QzcRk|9M_M z&yK88)kHSS^Za5LI{BZN#`#)8Q{`=FiUv}L$s>vwP|8I>!DHR;e58iAf`Z1hykecJc+m!17MmpVr@2DPGi)nrD-L z+K7<8z*q)W?s0*}_MYO2h~#fX@xuqd_2wv~+Q&HaVwMnENcBTAG3s$^r zBPZnZ`It$G<=cQxPI5)aL*;`L!yx!dxZO`o@)ds0Z3msqQQ!B<^k{!KAx5Loz@J!F zMA-aYA5)G7M80OkFZFD&M0f>T1Y5m06W!#Piwp6X*G@+6)fc)37F!;w*T_jxq9oV! zv67YPgh{=^p5+XQ7+D%rK{14ob# zIwGdz;LUr}Rijm~Ufckco|(ZQEKyJTWV!{*)+)bua7FF}IzgOMUY|E;{BbUR)&JZc zib`Qr(>;4xrq8pPLE*AE&Nn|r&5J1hfFhuY=kimKyz->0Ohp+q5TLyN>N9(jeiX@03qdliyd-XZhMh{<}s{t&%>ERmJRlq0yjy@nYXea=T6O7uG3tUl+wj zl7$jcSoF^ra;0{Tg>Ao}X{{V`f49dVQ8X)m zGh1DM2fPAP8Pjo8orBFb9tfNiEdq`00>XvKH`0Tpthbk|eWta3GR41Frqt@bU6{=V zHLOv~T($pFv|M^#0{XREDb={6_+#n5?!LJcdC^T@=H@Z! z<#~;ag{NIJH_A;@TMPF6%}2@GOPkBfZtSvSbfw=L5k#FMKgv$kfyK7t@|rU71BnqB zmCVt#d)YiKL>*;~2raHhkf;3GK1@gZ{ng!&#qp<9GF=nNIDdJUSJ4+Tos5cQ{TkWW znk;TVnDr39>FIds>1XO0t?6Mw^(+b8E%o%DDY>(_>$^>exIYzj5*BqocYjIb;k6;^ z{Z{NPn;1CSgAM{SNSqM+#Yd=hBo=;dkY0(LZ0pGu>j~77$<@f2=bq`=r2I6- zNnx4UXz6P?nFSf3Dg0C&e7XupYlXK_PdLFVm;C}Kg? z=@*Rh3zN_v4f#7Z;V-#13pIrAgf;$&Q2*qf@A9wYOg{z~YQ0Hkdn=7#nU6yKsz#0q znda?<91W{HoxVI{jQqQ9+7Hw6%+rC|HdZY(^c<{U9z`%Wp>>baW5F6QNY~mv%6bHf zB*_}&c?Pqdx@7vc`B<(-Nnuk-`64Ky)8_Z3%^E~m%PyE)z?Q<(cF({z=PWo6(e9Wn zgjd_H!p82>&rW9C?iLzyj{<7^tk$Zl))@st$^%)gg3#F2(TLSCXw{<#!|>R{d@Af$ zY{F7w!qRfWaxOHozH=O|hZS2n6e@%>9p)Hxl|a}hya?Zm(BBxtBLVy87$qcypy1)YuzNOhj;c6L~HULtf+Kt)>>aapHE zuXJ+}sCLku!+^N z#KNpqa%}6=*E;PJYI2gg!_sQPj)WX?#>27*bE)lf{rVi}^TNS&j_MJP>#$r`Xb^VDdx{7F{337jI^{--^HR>ZKD+9q6$l+ z)RYA@`~`m6>u4!Q>)J{#%TmKOVwLCkq*%vc=^+tDA#xfjQk9oIb$ z*K4MT@>lF~A6_7Pv4fZUMx8z>N?c@Z@!ssS=(y+9L?tvmai{rljD7_1YjMf6o;Muv z4t$Rbh)WSTOP}_OGe1f|Ax)qtH7Zv&ZqrG?QBA1wO2|Y?tjIS07F*V|V%#-TMoucF z9BZ=HAvL#_*p2El5?4N0OFphFJ+bXGUoCCyCo`SrbH!J&;-6#=NdhWso|}q|Y_mh3 zEe0?BH3{8Y4hU_0I(@zs zQ#_;vA>#{c#wV4GY0C_@{0#QljOd#TKDtbS*>}Q5nWB9*5_Or)Kx67BhkI)=1jztcx9{ zVngiP_v70+FiQT=l^m;-d>M$lnk^A5EO~cnAj%+){k0U1BHVU(9z7~%??l}-s=6vw zbV?}QNWfPmEB8;RjWZ_T>}qZ8B)cgCP=r^U<()nzeKU!NW#v=_<+?PcTRKUg0cjIZ z#Y}I-f>;Gde-h%yAZ?y_G~MD^a+_9{8{ z!f5@Ya{Vc6{G((2^&R_io%#$p6KqdOPj*0-DSI1Vf_Jr-;;BU7{$vQ`yApyJ(pt zN}@ERO#9Zz$Y~~aq0EfIr@t%FilKW9X?8=Wn<=6D?APo}o@stjk~2onBGOAXPMHPT zWM8$p>IIpd?Bu}0InwYR#E-p4#3@8VDN$PV+Z$REZ6}nR^zR^wkWysS4q# z;jw+tqy@#c@AEI@ejuck7E&3M|1y_&TYmeiGLgF4sox{KU#_Y@c&xuEF|dVfplv>| zgACkNsL(sV)X$(eH~=1QP#hgl9G485G#Q-n8=NT|ylER;*c*&O99pLt+7cbwP#emx zx80pzDSEDYKsNlUDda>A_FKEJUd<}oF#mV!-0ybBhTg!2$C&nr>Z^#1>}<&+guNr^ zn7J7j8q=hsQ2Nna?NMQu(UpWz`rc8=V6KwB1qXrKP!xuX~g`-IQczD zSKf4z!UWA#bdsN7B21-yBK2P7|EMJ^Sg}D>Y=#((C8wG+U$hL!CeTFcf?&nh!k0z z^IrU*x5@2{`JVU85zKpZyK7jvTmP~=JIItfVYX;6>C$T!_1JVqx~GQw;0t|avs7in zU=PCY9*pO`l5?-~RDzdZQ2++c4qink5!fo*alIvm4Z8cf< z8?@%Pn?Z8hgK~s@i~IYFV1%XcS4$Dc{bxx}FZKhkFu^xT3U^5ZuosGto4`+`84=Bv zk%z2NU4o_umgP5>VF)YA)GPSXD?jvCHvLwJgX>7|gUK~c3v5DE(T2rKnBOj*-YR9g zPuI78{>)H3jJQ3l#LKFJy&8G}V!1#2Y0ip_sWDQpin+gv&FDa3m}?lqA>guRG2AGg zyjC{7X8VKdTQclIc9C07V_nf~OxZZRrhNGZcMtZFY5SV>5o! zCT;UzG(N@&b@olj*G&%VO%Rr#gtMU3{)DqMqN@g$yNj;p0oE{Dk*~CyfAJP>%hr$m zE!jugVNBaAD%(weVn2h6x36Q9G;Uqbx2>E#GMjFVKXfEpcL*ewL{?8nWD{mx?LbrR zW|xSH*mu8xjQDb)_;b*;rCnl)g!ZR1B#vE#5;Hyb_lLuYl=XYB6B0Kv%hhSRmjw53 zu~8_PJiI)8ya8)BAiz7&1Iz^QyWx?M(cy7XiLvqjK@kAOHou@S1);Dczbw3>s**XzS|i>2B^F=pP#B8SU?w7#>5IfI=o`7obZ^Q!C4Ja|`RsGplRc z0AsuH=YLRy1H>iR2I8~ORP|PuE39hHmcNbdM{9mKWBaVzU><@S&>iwpz(J57&e&3w zJTSK6ui=X=@i=%efhA%KU~F@w$$`WcKoJbSG5%d_X}_bw8C!9io%jN!ioYmA(epO= zV9TJ)_Ls3`RK>7Z?Mp(h30kNJP=rCpw7-Kb)<8Cp*aCyC!d@DX*#3G2D7MPS2|!|N z+=P)0B(?yGfCZDverRknY}+3iTkUq+FAt5a)oNFJz1^R8aK`olMQERN`u4!s4or%s z{2yaGwTAKM$o(80AtH_;I|sc zjfAQL79hBC3l+u_TMLt9fe*HD#TFQBvm&jzLf4~JYywoJ9^nZRPZJG;V!|Ch1t>u+g%KoM?|SN=5LpTC4Jwg8HN6qt6{hCaPgN(cgyTsK!`~~^W>Zu@% z5Ks{WDbh{>6``^6*~4P{_506%i>;bn(P!lUGPb&`X%CF;KNP`KptO2HYPkqN5jOX0 z7TjQ%t^bQ6umX*(JO(-Y(+EW-_VrkiV*8Ca#g%`I?E{LCo08nRSrD{2P1grGGWS=< z)9+kw{!FL9uCFi5VX*TIiigDZKPWZV$OUgCsR+MZRk7o@)W2@APsxspF zlI!U!VVXAK*!Q@hqARGZX>A00ZTK-i)85KKP>A!}@UvSq>1})3A5eq=Zyfc<;GaaJ z1gQqXAHbS|Z?T>biLQA+OF|LS=UNRAPedZ9>cM2N%m~~(MB*r4>9m$?C)JA-;p*}e zwk>=@jsjn7;V8mUFzS^L|7nki37JmF)5pj!5nqP!lax~uiDe40wTXtY;Zf1}XNsxu zi$#yDg@0;Am3C?qOD0;6NM#QA4kWhOa_f<~UVVxRz+h|C$p9#}O7r~vD%IXhkjQ=w z+g^!!jE$I+6M-}8*wAgf{cL1cC2S39tsXJtL`0~zuZXZ z0UF!xxWvs^e2(GmV2)`3MNpyU{v9UmxKW$zFgDJ6IgrD1ktg%0wL9gBcqs2W{)h+O zRw|A|C_jGRh_`JnKT*I|z*}*Eu{}*EYWy0+Vw6E@IFa!QEj&a}d@L+JQbdenEIgo6 zmWo?UO!4nx8ymizt<^^>ZGN4dd<_i5li!n%sV35AX}uj}hTd|oQK9HT`T_|EMyhGuBcUMrEXvhSp(R&0<`7mH(Ah<&v- zHF}YO)KvLc`JOJb#QuOo*X-1}q(N!YlQBJGfd8#Fl5)2En9r_hW}mKgcTBX-kyzMKnYM^-PqbyMsXefiw#q{<0d-3(9(N7d)JXi zn+>)-9Bg@#De|z`{zVafY;(6bK0-=ydjf7c`c>itT}|;=>R!G)GI!m2vUK+-_9rrW zXd7a~`#YxF7A(h007dwP@B!M2WA@&YCix|bV#9Cjd`Kr5_yej`1OKzB%P#+1K@1z% zEkEf&tWUz07p60p&P$RjKt-^m4TTDR!}#DI4=Vp?`5}N>WwcLe@pqJCStoRzAG35Ab4<+&oTp^P9 zFf#kh^f$d*;v6Iqp)4M6&BuDheUHatn6k1Z;`*djJEKyu&ggZ;cFLf~6V(G*`HsCt zO;1lITNr@E)>*Qf=49%ZL3VLQ@2-Ku$#g+)c4^tnpqAZ9LK9_9d5pTWH3w(X0l2y{ zhf(IJL7(e<;GDavk=(`MW^VaF-w7#z!V~RT8a9WW!1Vrz7taJAxd)Blhe}Eqw(jZT zx8nzMC}=6Q0G;&X6!OV0pfqf_Y=m&7(3NpM;Vt zUu2}-e_q|KU{D!!W4h_`bYb?c1~hy#?bm5>a>7ElNo2aOrd)efsx6;il)$K^%ZOE{ zbk)ywHIRhW1ofuf+z1VXZn<9nu5_6rN_A}UNxCU zkO?DEC{k&)R~xgjbPrM0#$!mfWZjfxqpkPYQxg?76SZ8au5*}oy}L<6tBDT8WZ2fH zpU>0?;xn&FKGkJ9N8o$@%*nm(Tqlv06kLSVUjGMvk$-K&FyBevNzKpGp+)P3zZl#emFQIEr9#{7bMi zz!A?9XlkWwEGt2lbasJ^F@dUxRt;=cO>7FEMHE$G%s|d9OBYgMVU^_}n%{$aYUuMPE_HFvs@u zxb5ksia9d#FA-I1J5}2pRfmfZ`%OE9Z95OeP$XhjhjEx1Y8=QPnJxGt6o)u$&W0WT zN}Yfm=oiCC4DAyMIbK|8Y(95Lr4H9Eb$DwZP7@bS7ZSv9e zBMw0X9sy6Mency^6PmTt0BfY6awN){6LoYX?YY()0%tk}Ehw_K>xO(z-pqbX5~}Lr`){0D(hVhCu*{LjXrs0C_-w@Z>MbzF(y%f#p4NRk7*c zYy#`p8QV)`nU%aVK%Qr8{r*s{zqEJD*cELagNym`5oO6pZ&ieoaQ$YM&7qa@ES%| zI}||jBgd$n#ZaAxkbwqU>zluGM?T-YuXayBp}MlmmWWH@R{=hxqQdvlUwong6oI!x z=ZMwScqZB;5B;jf)hbT6uT=LDsMwy}&9T?b#okTxR1fXaO}{$U2i4t7(B06hsk9#H{xDpiz0M}agD?3rc!gs4#i$899});iQ>#K1sTzAkEIIjx%msNDkaWTmHMiS4Zp{PvbTDvtmUaX z{i&kAQ)v*>u{U?8zKWKn1p;>QGLdpND^Wb>`$POegKi)Hm<<~fSxtlN}XguV+4fo9rv&@f$4+co7% z3~k+Yne`2H+RfzLeZ+*%-C`dDiY-@%tF69^LaCQ+DPdSCdVeV=e7%n|NzC>BF zPFcBsSydjaENQAtBk?%}y#(b=!fQ^#H**ryf#tLbiS+&D5i8~I&?}T^Dw>5WrVT4* z{VO=@yIV&qh6pO%7)%f4OjlZyg$hi?5_$p}e6LO`rAVtBVpGBkQx5egZ%|WxdaB|Z zdf$4aG97=5=rPyh?9)wb(NDGe6HP&vU^t0wCuPwKzFZny@2?wlLe_H1~>4I1cd zaNdD61W-4kyl9+|2%B;Yo4pyq*$<1T)4<1c*w5nJOc*6;93_+DVoYt?yK&eyc0|@| zK5`tZ+;PM?k7#FYMxAJ`LTmZRJ&wuzWs0>$x;7HEp+z>XrM<6(#w&{dMJs(|Aqhh( zAz9I6zRu1?t8`HGo4umt{Ae@Ow$m64YLhk^lVZExHpR$dCKIzL_0?g7H!qVlrxY-xxZ-W8ll1 zbn?1)vgCHM_jKl+c1FMGDr4>vRO+g;?y8UMl7w`bka?Tkc3FUlExEd_B_Bdt4499@ zK)2Ig_vW*n>Otuh_hg@jISWWn(_ON}jf}IOZ#!l$GD1~E;=J!=N{m`>;_dthX5ScQ zACky|wnU$vM0K8;g-QRy_wv3XvPEXZ{Q zCh-9c-GOGm0llmNNZWw%`oM4lIFf!4Bs2&twp$*9>ZyZslJ6Dq%Pt)s1W3tjeDZbdgEA&y;4)2=vVSTA2ZKgwnUOGSIH9B;%Yx;=Bdpg2CA$Zj+Kb?=r?Y4vD#u zUvoQ)K3?GD{h_(T`?+HmUwa6J4Cz;lvC2Ni-oxnL^YcHk7^$P&u)`;G)#*+PX=;7Y zJ0RWaTi9QiFS7W}eUzfKNbu*)R??Av`l4Rj(LquFVG!amRHz9j#B z!0?I6CHvUvw@}1ynTp@?A}K{)Ey(6~IRw#{M-4mfIAUptG}MWkqROR;s_2)0!WyPlbip1Uqmz$})? zbd{`}TqlW9Ro~u=-_~>9J`B)1if>P0icMdfx~RL&*4W9rza25xFLl8lUz&DI!m2bA zt#;X^j@_+m+HE}8ZC->1OYMC&*y|47lTX{z7}(QW*~>-Rx1rp3;M<=x+pqB1&uZMC z$3pq}7e(;W`J339!BK>$=qRj*#5Oqzl$M_UBMW|a3|MUQjDD1ql>#@{jQ*ks@Wi$i zLTc2}-r3X92On$)M}|npCxFBjes>H&5#}jpS4daaXExTxH&*s`wzv0>4o{BH*7hzh zt|^c1E^Z$^K_e3_O@+1oRS`m$pSWWq3uEAxz3L1kWYlu%`H;~a{E}C1ji{WeGn|T- zM=9@kt?z#tTdN%>u}!|=6dq567j%_0qZz{6{}@|fvGu0&lAbJ3sL*;|E?+QRpaxHD zZ5g8BhsU@RvfziufW=lqk;x6d*e)cny8TUTxu5|Li>-7+=HI(x!G)P{6oFo5W&l7D z1_}59#SPNxUhtzt1AKGwXSe49P!XJOJJ{|Nly<@Ij`fiU!;mPJ^Noue4t9)7S`J7UO4@&`>>+oc8Sj<%d`vI_8e4S6 ziZ0$P3ckI(3!aSMP5Yr*X$Kfxq`I8ZLLT>9mJ_^&yF;eP%>+!FoFDfSlKS`ZU%4-+d zOmR!7S5B*;AATOya^MfybK zi{)_W`SNs`R2V=J;w`-VMAOi)kNgPgzT(FCrC~50`IF3!;Aiyw9c+`+2`W*v7`^y9 zUXdL6!RnQeKBc#I=(Cmi4_^8_%MtAaR0NV$kT2^l}Du8y>FStE14=)>{+_EVgTXD#CHmb+JHV3r7E;&@283XCtbVYCua*Orl+KBN`GZ zsb^~+H+)(CDH}EWy})X`7D>hD@~|M&=$QmP4t&;5|7>ReibNwiWDclxu=QRjfFeYo zE(3#YtpNFP>1N`V8n)9EZ3@TyX42Vq2-n4@R0kvjK47r*c-0|;B84LGs1XKN5k_$0 zwo$1K9?+Yq?hyeT9vh3U zn~=2Yi;(=&krRJzC=>XAB8(?v8Oa8FJj-UT%9B#ge_SR0-@{`;`Ld)IMcVRb`3iR} zm~L+v_3hk_p{GG zT@aOi!UD=#nZQ~^0)<_81<(Nh0Uatw6CFMz&EAbFT(4QKI-wMv z#x?6a2el(X#qh5bRQC@@m zL@~-keG>zz$yfbFeYC<$de+`@#sw%_`$pFLVbYao_e~IGMEBANfBL=JuVJ=I)-4G~ z5nke>`n`But`}nB6=HFpk+{kQ6Xk2l9CCOnCV4pUpdx$@)1g9U+!E6`9`UQrd`sB4 zCGB%OszsTV`5izJ=CYzIJ=vOsGildLhI0jV*q&o9d1NZ5@@!_<2!AEz zF{S}u&7i4Qyg}NsZ7w7PXVg;lbbgC`On7?GEZFCC;SkF(Hl6v;yQpVb+75Y57lVJI zx=xos<#{c4YvUfIx649r=rRbHCcH>(a$}4lQ8UHiiS2KqVMv#}u1BHP*=jq7LU9w_ zaY^{?nz=K9s!*|lC9KFvT~|u6YRG6he(rXIErhV{X~9YI&E%%ry8Q?y614UHw$x|6 zKnoxJLjb#a#hW<>9cqP{-0$Z*3fM(cHA82`j_Ue6--`@o`YUr66!v5!RAw~kRp-ZS ztIa|<=Xy3&YaU-5G~Agku2-x5#$v6t+2vdgF=p9Z96X$aGq%8D%Ntz3e5blb9i!g& zz1TGDb;$;&-QrLVq0JuVoukORrLpOYQ(?%T!_$5TSl!|oLU5xSrljK$L{ZnW*4derm`@W5kgwky$N~eJ+s)SoAGMf_{?4K1ijuq!ra( z)l*&*k;api#?T4l=5ymVTkknOll5OFYEbgt4f6gjlZzFTlc%QV%%%nqnW-)rXtXJD zo2iAt*G1u1%hg|3H@>bDeA}+}-I_9Uftno=_<69sQRA2WDr>} zeGjLBS)eEakK8TLHZ3p-<*@W=v1%TX5(cER1!O7(WJ4a2#{?)<$@irPXm-leTm;Y% zS``^EHIG>uL}qU2H+F{D5Q3bh)!M35AB(a2BD4AFt9e9(1_O-kRjB_a+qAAaCb7MDg*}n7Mv}fp zN(@I@jRsKbWKsXfRs4~!$W<8gqogJr_QsK^mb;2DqLwuR((TBi{J1$L;u(R{b77bh z&kRyGVI)Pilb}D}z~PK&!5iIG0w8YsPl?Z@eie~O0B@!bX2LE%TMCy zZVU9jRKWwg=szN^Mzzu3pXpxOxthi4TA&KwbnDvAxT@$0KcxX0+Zf;o6&eaIUYZ^@ zL=PVni%X<$tKjathWA=i)MvsSNNhPMJt#qOJ_;W3aR$_v&y%*r7>LA~EzqQ^^`D6#pm_ct2v(GM@=w~UoQ zfM1KGewnxla0qM^T7DEdPzpUI8AC`CQn`(eL@6Yn{Z5rrE)@JO{AI7~WrLw9_r0=@2>qY1rrKEgBRQl7;L#@J`r~Z+3ue(0 zk37w0OM9l01}wG(mQP;Rq!mL0RM!LbgcP)&2bR&K*AZDVURW-CWcm~nxQ77lAj4H6~{;-L%rvh#k5Efbs-G!ttx&!!AWroh5apOLxd7c9$>wH~XI zqno8O9lYoF(TLhkjV{DoQN;vV)r?wI-#6rj&Ca&Q?w*L%p*!2YJ=7;A^bxVzul&%S zvuqqdv7OBU>xX$gvA2Jc>lUF-92Z8~8}@=7i2^m8QjGI8G3>`1u^-fiNVIw33~_mb zC*g@I+#hHon2GaIY~dSTwhAv7KqIg_@z3O=$wiiO@WHEFVt$FZhw2tp`#XD-0^lO} zBdf9(<}XL7(?<6=xCrZE82U#abVmcR<>pt+U$j_OS6IpuSWvnckbR8qQ*0Qan-&s| z;}y26eeo8Fh|QYbi^uK+VS0Y{u}3QIbfdB0Ja=!wxa+zSF88>5qd4BOI0Q$rlv*)F zbb>V6_>4S)?3q$)_xRZAc)Ypz6r_Yw+Jrd1get>?_DDEq+qj+3Ol#amo7hoH)@7eK zADOsRnb0^r2E11eeES&9;;Fblib^$deyVS{|CcQPXoNK2 zEj$r`B5>ANJN{y9Nds{*6mA7*+60!f0gG+ml5F7m?;57MbYD(Lz+7Np0_4**uzeG=K)Y);P^*yI4X6Q84CLCaW*3k%xSKP^+33s>=FX8D z8qw%pp&m1>K3m1=8xZC%&JoxL%MF_42tmsWi|33$~>&wVHp36(R&a0x%zf9oC ztaHq9$j?Lj0-Pl)p3N^)X{k^t0OtC)kp)t<1@EQ`WUmV3i3>YaT6s^ki4qG*OkBF$ zFotFeUosTE0%kvlqBkbG8gem-x!QHAi!q_aK5?-}`Rz`b?u4SE zVfH0v35U@^L_I4O*HR8<0Cy2VoMG=E%HL{(NGR+g++R^ne4n^uIdEWrc1uf2n1vbeq{;xHaYW+Zyng0>tMP0u`KfR*_qsL86n`AnKhT)abKtMry z-yS3gT`}xtU_?@}8w8GWv_8|y=rtJRiXY?y%*4$>L6SN#aT{?G8^A?aR2mX-P%fDp zI=CJBSdpdYTYt2brIlZQl31^)lKtIt*x-7&xjx%8U-hX}!|)uddHhJXP=jAij#qo= z1nDRqH}FBw=<3i2eZ#U+Z@7)wf^y4;*3g2%<&1U9kCW((H{krtr1iN;A#Zi7tf^rC zPV39t*3tKEDwstxbV4*>UG3!Ztu=tSe}G|}t?2Xz)^cINkXR;_h%qI5MYWP5zT zJ^m(@;Q5~5y;q?O-y*nrqZ8-JLVE|C-zYhnkEr{pCYYzIEd-19g&6dGj_R9VSP<&$ zE138HeFu94QCr+_UbMP-RG(O*)M?465_tFmQg4uM^4yAcM*+}lA(!dbF9v~~kG0N< zwGTW$4^A*%#`+YrK$eMdP>Y3CH_fIjrC%q*T9?o{v}&*t(^+>ozfxkH^|C4W{p;Z> z|t@Wxc@}Zv(?4E9`SsSt8FoFg+N57D-1?i8v2;_PN z*o!i;FU_%#7TLcD(g;Kw+kZ1wCNTEKbgaR1jJA=BelVQzF8rP8&yU<2%=WxKbB1J$Bqxg2}HYdhtLfB|Me*hL0*Ll}ZiXb3}0K5PV9wZDk^$eGih%E91ejkfXnu#|hNtE(3Nc2kG zmrP&q%2WrCi`hI(lLAa~Ku73#o8+jLR9Qq(?K}tJHmz%%^D&`p;!X}Ao2UIa|4DY9 z-Euy>a6Wo|{#x4HH@52Tpm*GK0b$q=D)l`A)VG*)$nITTTxd}=UtNNc_Rekb*^eWF zl3(vi7fF6t(oNT#GA_MrhV)5NnmW_|<8<@5m>~R}+6&ogt8{HQhLZ}m#SkBhL{I)|{fIjTNr0ry; z4WI}r#9QkkTe-vNJ0j5vL0f)9Tcv+=-ppglok!2*7e(<*MUxBvIB$Dgww+9VtG6-b z>5pr+QEVSFSbw-IAgmcySBcux%O;l_b+36Kz4ctM-i@XuB7f^{}$U;&nJ{Pa!{|db|0MQ z;wC6*a1`N_(fnT&fmb1q4UZp4Y^CzadM(%c=>Cf$SnbT`eG-sNk#}o*DsG+oEk(#V z{0P=wnKz#E(AWZp$NsOeEdfx3=bTjS$Q1^|`BMG1MRV1LOMUVZ(j7cpjpbcUn&TyX|tm<>jAMUZ*a>;4~A zci|Rg+s11fkOl#fE-7hH=@Jo;4(Ud^OQgGF=kj8DKGsC6YB-)O7h4^Tjk+~h{>pWLV6gCC+u{$nL3FHFxX<<`a>Zy_9(gVg z7iuhiJukKZV;jWc{cwIZJ4vPbP3O_+;&i@Q_nnvLAEi(<&CZ%BF(~j0FsVcb|8*^BSj#&-GW{)u_w^kQshGb#+IpmAIjL$ zZH2MVE$G8BY$E4Iz@08^MGzc1cL0nnbg{)a=m8kpgY6gt5&EBTUzLEvV`?fPJx~;3 zCqdPpemBW5(5wgA*wUmJ*B%(BO7zh0rP=olc0Z#C8SZCA|66P^7&`wkwxIG2=-n}f z10b+taqt{+5d=$bIj> z#`fXr=uexu`>WFqIDF~T4s+_#(=K$b}@^b+g3|Lr4k8u{B#7KDD*OPFYR zHb_?hZET^7ElZGX^#~zguZ%MM3Oh&SI$B{H7aV4?pAf;cvY!;99sMyS{qDpbSz7r2 zhazY>om|dfT9P^<8zjnb&gd0{b1qnvoLnv1^uN4bv71l7S~YAAzkcDim(KP7pa{=* z$L#qhZnh%CFmAVFRAp~>5~j0ncmH>HjCWsXLjLX`zaRpPRZ{Z%?x6Hpu^o@-eO7Ew z)GwazjzOS@$Ivi4fW@}r;cO6T{o#Blbg>P3=XoO;X9J)J ziJy7_6yeX)9bON>*j~)bwPXH65w6ES5y7C7!(0jij4c-Ie~c{x+y)dycxG(z{xP;6 z76PD)?HimPa_rAt*g~8BbcXP6={iI3z_zcmg0txkZ9zl{Ik?Qw8YId8 zP?z_Xg{OO1=k6@AV|&Dsj7@sJV>hXr`lY3D_sDW(esb+bIJ?tysyWy7)`UgqO5rq2~h zme1jN7W~ITf0CYTl+VbY=~5Q~iCqn6$5 z3GYL#91SVam`y*U)l8*a)fUQ}j7W>tB;J-9R)kwk8oSjlP2rizDW+IEY1XamUReNl z$AH9Et2q3nMgPZCyLgNG-Kmo%2fuRr++nVE<{l~A{fE!Vs1Y@=j5B(b$*K*!)>{-FY0Aov4=}Ra30fB2k|E2F~FBy&= zib+^7&Js5^V`&eX({UGpuYMqBtsX|uNH^t+zXO6KIWZw$d#K31hkT8weqHvemqGFG zkXU0*Leszw%Q#h-E=CQ(IKbG(MpIZR8Kh8jiE`C90VqOE+KzKSZ-IZLv*#fB^~jz8 zl3g@#_><~oNSxrkA!Z5`MHt-|<-42ISbRbMQNpY)ta>WZ^DV=k{*a1mN_>j7G##x0 zL0?C8Le0w0V*1!2h%WeUwladl7$iY3J##lVY%gP;vnZ`uAv(X5md{xwVQI?{#J$6A zQr+q@X5(11_y@hdGJW1M8f2^nu1hw$zIk8{Fwrvb4Xa zK}eUIBBPD3!VdHETw8#|)S1MP5UuX{h0FHo-!&^gX_Xx=F@d%6M@Zw~2+8 zQ`>nH-f+2Kq_9rV+I-G6N2NHvs$Qb(LJ#l9s?aig!va|cZ~3dk_}NnEU^^D$Sex^b zZ-FO&sX7(%c${y=JfwqG8&~CFYUOorWhHgp^vBUmw3%<_RA;5_{t-AlW^Fgyr&W|} zWj!s!?|}PB`$QwLdEw;uFJ!LUztF~(OUrd~_;$2pzBLQe!);3n=;HC)3lmp8RWaA+ zn%A7+BR-yCNxLnv-CV8sRsMd%zp6<(0#;Pm)XamyooBQO`?{uQCwiVHNg1+oh#LU0xd5cyxC@U)(w>REHub4X| z-@}Sq=l_X0S3@4X=JLnnV; zA4JD0kB4jHw?O$AXcIwa3#g@7U56U%2d*#!jvt0bkRJmJ zh&&Bp*1bQ*xS0g@U_YCv3MZz8DpF z9c88HjOpU+hYw|JZT+GnXkC2Hx$JYbS8-#Kxnii3T{7lf=v-oQ8e*6Zc=G3YFK}av zxMFYXT<h%X94mt^raK(?S z#xv4*Fo}A+Gxk{EGFUF~Sam{N=SoN<_soDX+zCS6n@2rp5I(+6s9%S8{t-j}OY3#v zlsKa6bsgljlI5k? z2S5?r>V3j+d@0mSBMjjf)KdPT2#R`e@96x}=J0b2{VGw+s~7!hdCc<>38Li93$Ogj zjHR0G&D+)efuOR_Ou8k(zbQX$peb$QLb~>E+9XdpF!;}@TMktPjMD@Ta0X7O1g^>l zeoKNTwx$Gf=RI=YgGrADhZ2NdmwCEt9lAhqDM}gQ zY(sS!glKLP+XzJwsN+M};IdPksVG>1yHlWiXOKY@1XSDz`Zfg;yaWm3h8n*Qtu+m$ z1JO1$=6F|!w(N(#cUA7(x9d^M&C(C+PYUDc2O3+(@tfQ>?C>e>@DYV@=YVi=4d$iB z@YRL9Ex3rULoA!z5j$!C1sI{m@cy{*r&jTMO2rT71o>ydk%k)iW(^vA-HsM}k!HM_ zk91M6gat2dHJuZqFkA|p!BK+_9ByFFVAW`^A!nl7Xy3zVk|Hj`CT$9Jm$!?B5xhD; zeI0Y>!mM7Da~)IRS9JL$_QnVZEn~9|zwyz#38)uOyZ{v2xZP5l#7&r_{r5?`sF;Dt<@ZrZ#~Q|=O-Yss-k4S1vFa69#joPc zOkCNUX$MV1Sy$jyWr#%rJz2apGq=>D<`ZfBQ$T|Nv(77Yl`#B>PzKa zs4CyCBDYBGf1dG1c?jDA)8vDR#}535;)ter0%pwuR0`8I7Xn73Wd{)hSDP$X2+7vX zGKBbQMHuDQ=Q8fq;%> z5Wb&f>{f4zMw#eL!B3f;MgXDAxT&{vqrhVT5!_J|fwM_KZ^`bm$t7th!8Fw7ISw&7 zfx|gWhdH$PxnWZDY)f{)`z3BL1K=5d9Lg0;Y5I45Y%&IVeoSI7PnPJXJnv6u-Jiw7 z@6zn5{rZ)5VX+Un+K21m35w+MSI@y~?xjAv53_7`hTSla` z{PzmR0-OVQ3un-@iEo`jDcXUD+L24GYnt5AL~XH$+zA?Ozke2;1+-Om7o{H-fnOJ& zN&%-D+<-x%5ad<@E-p(Es6Z{LD%Pu&EU5>TG!>T&&zH2`l@Q~UcJT`JNDB3t8w{kB zt~Zp99+plFK~Sf7%Vvf==Ojh!lgpNd%A60%R%GupT zBZ`bIIV;X2UtKSCU!_!F2Pfn1SBOaWWYFWlhW7Z^_aG4CpsiPaCFxb*?=9h}!d}Mv zz+L5(orJCtS{jjK)LcjG2zDE9Dsi+zYPoC4zhBX)Mks(|F6g%? z5YKfQO`Sk}bn?IE#71caz6Q^fM6V&Z#3n{BYjQ_jw~}bbY~D}Oo3&9s>aZpky=^Tz z*5vzr-}ZNTs-3MJUZp+XwY?#+y%^lSKi&TOyd8$5Lx!iL(YymGtV5-!gQc&7v?m@@ z%ivX*&}->Ve&f#Vy;7a1PTtzi%85>ZM(D!oqLl6e(p$Q;E{5ZmOkrQ%J#?|Q%#nPB zbX$91o!()7Pxt0K?soi`EJ)&W&)f55W!@97GDM^jRNI5dXG(b5qm;G)YF#L3f>E{X z#o_DIY^lOo?yZwpCDVRs#1!GNg_ImpSXMM68pv26v5vMw#obiv|^s24_g? z)zReDhvknPgSFg(QBmvHS}BnahqkrXc1fw~(x}q88;-TJ8~GK%?utZ9!~B=STG%69 z{39j`BYl>%1D2sfX`v%p%Hvw=lPk*8(qXffD)a6tiz8vnBcqf1qd;XlP6-*?k{TQ3|tZW${Jb@;2bnY8mk2PyKRWs|~hoW(ld9C*@Hn%_Pg3CrB_T_Z~F$3%Zg z)JN+AG}3L<)q-J!=t<3J?2oOI<%J%vT~-_>DHkUd)>_H6clJ4^)Sh?_OL#OhrcRot zTDGS2F{WS8O#hUeMmL@o4w=TupFZxMCfo%`+c1mqGeVqmLLS=@@1wU6#z=PvL&m%pdKI*G=B@%c$6*WgaqPDy`#W&L$g_V(%}&5acezz|n0{IWay1w*z@&9$zi zygu%}t`)!D-MC)(d~}Qle`9=M6o?s_GYfJbx_e?jx{)*7y zWo6R2Bt73$`xeQ%mVe*U{4jFKB`~4?tpH(l%LuY%{BGMk6EYz(#`&sM3+MI7BK^iw*FZAzH1)-WV6ODon}Q)$u{C?KWfZSC%r6A)+@pD z;8oOtaqEG?#6iZ>!6Cz8-#08SbgcZ0?x>=}v2S9fo+d&MhgCX{A3I< zwLU$rzj@N$Sm=22O}I+w{oUJWcFZ2U7&lrqv6f0Yyx2tunev2~ANS3*K^V}G-vBCt zUjVS#fPuV+(W3i%W|`(;I8+tJ|ARvwO@#~ti7l8!xW-t9jvH8PLtckK?~dKI2-O0Ntw=aDu{}^=`-0L^X;bpTWpj@Y(?od{BZ)KvI1V|7gG2V+wErukXvJI22z1c^+V_~ z3MqrBs-1H}DJluJ!rsq`Z-sO37XEj4Oc3#Q>%|9bLbzyA8VRZxHr9jf=&u6wMsf18 zW^ZHE$U=5rDA+aqOw=+j+DX(+FxyRr{HG#>(2!zw(3_;$kC~aIJFgX)WY}Lo50Cw8 zY#9o%?8%EwbHZ4b_H#o;8J-#2gP#fd*-#Xr*bMLAVw+%oSo9Mv>lsC0D1m)O5$4QG z%2c+W504EUVRs-h9#;a3Z7KHiVml!FZ?P>!_zy)m>i!>!5DF}|5heXi`#GWiEw;bm zDE_oOGqzWF&x~!e4L-owR(3ezjP!IqE4C(7I2Rga01<@er?hET=U>G*rUzCTm- zfJ5AIFEH4qvEn`twoIQW&PO2Z^GxTM|1q{BY_9~7m@g(i?|tsU6Q?b^n0n2Aaxwjk zBFK&dBBq)qX(w>!{N!>@%%Ayc!7!A$chR(<>}nCG_T)bl!M=aAbJZDWY@v)T*Do3P z|1q}E#daMFe$9C!l8?n@D~?N^X9vr${QoYtcl&vfI$w4Rgrn{b3!#f`W&4vW?*Dst z3|MTH4ZWLBYhT;6ob(`ldpH|neAn{VQv?`n|4VG272AJyUw&}G4+Du|ll6eLyCD@3EJsF>kaHlD@nehy_a zaY<-cI7=`egoLs<4N8Gw02N^c4XPq^bMFH2Nf>J)O7a-M*rw5kvlpnR%;fEIEZECf z)$^pTIiIJtP(*O|-xBX8ou>_F11JIy>2aeX|7lnOe}8O-YccJ|>p=iT7?iu+4*K|T zAm@W`|F2YfKs~!TV%Ji~MMEM!U2L-Z+X7MW`GdV=S-7${ojD(be zd{&2|Kv1z#0mH2LXH*51QNTw423yolMco~o;y%f_>X<`iQyE4WYe2DG8&b6mw} zG1stvh|5(CX7fU?faubctEFKfvpT6#pGI8gaUDxdvZdK>&C*i6iOBHD1n??%wde|u`$?lVW2)U?ef@5JnKd-A-MDHv)VKz_X{I?g46pu{{M{T~lji(JZ0&DE zgZ;ith3owA+Gy37!>N(>@h&6Z0_>kQD2m{g$iGU8=>lWDb`C$%viI{(2Q;z8A6ZA_ zyXoA{&GbJJ+dyHP=z?d@dSYklz!0ABC6pBjzHI1#Pf_c^VJ8PM(m^_rfW`KGL{*px zNhiMbX#h9P2Bl?M2zHlkfS@r&l*xht$=vCHsPUIqUfgJa_A&T*q!%lhAC3M9F1TJd zC!t|vhsDW{KxKv!x6V}5QhIX4cvlpEaN`SW4i%{dOHJxLcOP3@^qAAGLB6w%84b>3&3V-UJ2nMvY>|UvBH~08lLaI;c*D8n-u_nnfKs=q zTO89n7&jB)_ONB?S`45Fc7+O;+jJF&%5~r~D2kAXS~4;!d7e@rS;qY>Uel@VN7LPd zs^d#n?Q=={HX_nW@p(MGL;6F#lLegY&&1H=Rut&XZd)bOj$uju0Pea>fneFx1^``O5Chu?M>yhg#U2@l_!41TY zKw^9Bdi^)*m$h@ZMdO*ySWA*c#V*(Q?M2%)G2Z}DyLL~Zd*;0KI>yJNPTCa6g!fL?2AFM3gFg3T>iDbvusdEzPc#@f-k~xl&d7QZU^^!$bepNl@ zLP>ZPD*iQ&{?*17l4`I`bN+p`7X8~03xx&5PL+U35lb~wqP|_&!33G%KAADRzzrNL zLvbtPB-#0dz}aZ4xk)SQ0jqVqpdEQAig5K;4tU!R_tV+WP_=1 za}gMPR}WaF3h(r(C^>-pVj*#AAp)BUsMiX79EzCzww%3+S>oUE@Il0?AVCf#5+@o1 zIJ?pXkeIR^HGXJil3lG@XwaseT0m$F+>iIPKlF@#beR6&;R@qd4YRrYF+gWOI{=C;hOi^S565F zyM(dv>;|~(&AJdZMU$Yo{>62@#ErQMaHUp{x$bpsIsY~??OJjDtv?pF2|t#VCzf43 zmTl3kB{8;(*1aFeqyIXVVNQ=6(fyk3^Ot1zVOo#DhByp+{rPL?EJq0Mi9aJGJm;ZA z=qa3Fu*T(?0wlJJp8EyDLKmn?h+bdu(98}zyWfl4T_@O@dCAp!8LE7FGD%d&@t*fi z)DQIjUhj=UkfdAdeIjV$zbJ+|Ao?0v4243>H$lwnA_@M3DWP~WkY|$v2Zx)IUr_kI zdSymOXZBjp_w6Lam+8j$J%OJA;325_34Qm=jq}T|^)sIE6F~NFY{C_8Of``A7Y+9B zD3X#gwUAXy^8-p-?toU~fRPYF^_#TpssOEpfQr8X%hZ7jA;gAifhG&-ec6HQwspV4fq|o2W33R_E83LIM{TlH@|rk`5V)YwmR+4PjA? zYYc3?E3Bw)(qT-MNo?9uQN~?SRPm{I};dyvL?Q1y5)_ZZOR#j6#?e-TCbjF&J}>}jT+Q1sR4crQT_5navLXq>_8 zJ22t7iahS2smyrI*(P>id9P#{Bi$r=@+4W|iTcx<*wrRE8;cPPBssxjqWv{-*oKG& zA||8yR3r^1!w^@(5x>enF{3T?MPy95&k~1@`Gl{Fn^H=fUYFmdRJ!0)AK=uQrK&}z zk`1S}9Hds@rBS=#cdJ|UnWYUJ5DYb?jSi+w5Y|jdq|chA*G8u=Hlt+a{k?otw{TRp)w+M13__|Az`M1dWim*<>Em$ekMmaV3Furv8HgTxix#bu#75Zoi8R9KoO3EtA5;?|d*$*yT?dDWzZo#p z*ti2(Z$71mnt0UeXdY@F!W4cX!eL6`%tP?Vtr1LI)-3H_Vm1M#CWM`hKW{H z%u|J^)j(i7&Qrs_ zOvLF{!_64Ti)O{YoGyTtA;?!7*h2c{-b$i*U`vJkW}`L=y-tyDFfL5~!KLmpVNj!a z5VAPLtXE0F7{h++5AqTzAjf5Zc_78rj?o(X>2lZYOTBR@@aCil1E$V{%?M@KTm>@-hOhs5k^@+G+PrJ%aKsD}Yi z1iJJohVYMQg6-$`?JVK#_a(*b%+tbzfND}wx1>MD)$wXOPCBGRhnqHXdlF`%?_@!-OT~3@r$|8s3++uP5|%%+fy0>ZYUpXiD4~N;Gx+!k%V~K+w(M zUaqTT%=J)?O5k(0)NL^{C%I)`h=Y!eT{j2d82(D+kLXg{e#r~Ln44R)$i02 z;8NP}#zgFK-0#IN>*F5iR~i`LJ`j{PaMd%=(<&#$NPco#8_k~?zp`>65sYC}hx2n# zt)wo)eU%g;gcZBK5O{?BlDhmj%ZzU=6M5L?z8)V8I!yn5Y(+zoGJN{@y_x@4_090r zN4oA(y4!TR-WBEku#utCk&!f&G0WTuCe^8yu$fZTxd*0&2i2vP(fR$RwGp*-lCjN) zciSrnyY6FXv13_vW5@1}zX8tj2;nb@<~cvxrRDgw7W-}K_`}M0H`)X&^Ms!8#JIx* zQrU#S80<^ZZIE!Qzobi|Q(=PQq+}bU6`%RrhUPaC(w+OA$);F-iqV(@DP2O{DaKW3 ztC_Jh_3mWq*r44gqP=9P-ArIwictTlWLh#L?&bD$IqD36A~=_SUR0fF8R~Fb>v#|E zspL{RKs1X(B0QYZ$!jO|OW+b&vy4@1dSLrY$chl-%Ax$qooCR1$Je39KQDGx;64ST)@25Wud0Nu&TCWs zC#dRNDx3*jP>4Ad(#;{k@@!wE3E9lPbbd z=Wa|dWs|vPlWA@9$Mxp>@^J~aEt|t}&M^*dYfj!VPJZi&PvsLrYgfUqfxppszC>)l zZrygQh?c>KA^iAFVeR_v%Z^G!n@{FW%FvFk=S^_t4HnI=p};OrlUr2#ZcN24@O}YS zD-Jj!Cv!VZV7TY<1i8)nwbwQj-_2Xvb!g!C6z`i+x=TA-{%JOX#Y;VK_Al@a%ITmn z^S%?N+&KM!Iqe{0%-Ex84xS+C$h`Zz%>2v3q@i~ePOXPw5@O->N99lRV-;f2MMq2R zj~Jatf$+W2GvX-23vhzRz1GLF-p7L&2*YE?qff_@uzgdqP!XXl@Wdwj#BAim8y4C2 zABqr207Vf%R#8wCAr}8Ru}w?0{Kwelkrfmcd@m_2D=)RFs;;T6(*1`bG#dgaLRWW} zHIUc>cgKb>fW&rkYI@2UxI6ak8ASjR+cooV+q*mad%NcU5?jbKWBZ5L{PyJj?&%f= zf`Tq?o7MRe`Tt#P=|1!bg(8124{QA1EgDMt+4w?SA#X5-POkU@x%%yJB866;KjHJ? zF<`L;7+dIKd+2T(Ybui~E=+l6kEvU0bVt< zvE_4m12nd89hN1}M-r7(U0ck0l{53k~ zGm0?K;g6#Npa}RG*&BgGSL^>Vwv-^f%@EqT>>PX`vCRop>VYP7QZ?9c+C#_4fZIw$F-fuuw-~UWlY*(a%7Ab9(qRN9f(L=fpO_ z9CBEcuhLmmj8%DfSX|audZ|`0w!8|4@XZl+(|MfBMk=w4BXJ{ehwg@7n%eN!heN9irKEz++lg zb|4?6p0=a?Nv-UH!F;If!Ine++l%|{-(vf>pFHT9u|=;!L(MI%7$UBD@EK;PA^9=H z*e-oO!nwzEKFD#T#Wuu-biy{l`5H)U#fi%p^b> zaGp_wZK`bO-LZ-%+~>Pvr^I?t6v3;V@Zoyg3;X%*7_uPQ|L%@83Nrt@I|ffn_Zda) z-(btu82F4Lpl2hCiFaYCtozeRXQQeX3W+qH1_asqqZ7&lC;}FCI%FUlgGV0tK~;%U zB;LyyxDV1G_>R{KG`23E!)SQ_;*S7_#}Yq>GiZD#S{TUTt{>=Su@fdeK+fg;{TXO% z|Aw6+BY%4M9>s~b9d7-A^kw%SV~a13EJ}_Y6CJf3`R1>IBw|yH5OxfWe_RNqjqgA* z@=kPA7?9Ya;AV60(5rTCzisN0D0Qxm&FUFa1G6S5Wb`tbQtW6!8C$Rdi+9M+Z^rb) zYAgVXFtWqU*gZU;wVN1w5cWPuB6*U4jlE1FpEWU=XbBi>Vb+1cb})5A?L4JTJ%Y2L zC~e>QoM#@z#Gyra%+9!jJFekVNcdS)VcgM;OJWk!y$NFfCC zlJ50;kqKXgU||x?7 z7kTPuF_L?N`3WEinfEfU(~J*kJ}zG5bC~aYU-EDwL|7*#vG;Pu9qdcxGL4o9COv!QtFeSxtb^=I7fi7wGICd zMc^o>=}6Qet)KV0#npS@UFbYit_;Mzs`OG;)Bn`>&ijj{0bzHNJ_X-mQ1UU5*p>o= z?T5q=OB4PhbyJW04`~}=wIaeN06jg5CrRPCe7ti>2 z47+Vy?S1n--i2%@hw{)0H!-enD|Lx3{}|g}Pj?MJ`j1F2GMt)WF&7*WuSlzuQXZlZy>76(I={nBM4BRPb$JiV9dZNk-Mi}V8PEGQ`k*)&KHg@7QFZjL<0|r}k zA-tuVK3f0m2tDp@vR|kD2@Ba#4maJD_&mXdzA<;NK{U>}IhtD%CMkw|RNO5(jemXK}^oq4XSOc*<>O(^(iCOlA^? z8UT&~maZ#ySR7VqAWG^9t22&}urOY_n=ALpFV_}C?!S+QW~Z-g6UrAYZDPid{Bon`>A*vj3i#v(A+<~Wp1fSPKST>qg6<4t2uEG$l! z@fCs)o)&AYcR5ISm4T$CQ?X+gL##}?ZVsh=45AK2is**XJI{@6dC*8LzTcwhk9v*C zsj%bXw|ono0_=HB+V!>ZWh;82bwxYCwNz5;)n2^%l?bZ_HL3D-B)OX|{57y)jph&h zcdPp#eA{p_en;90?Y|0ZXX~Txt{iW4M#`@3&k$Po_xN;{1IU2M_m78q&>aN)bXghs zcnZe^votK=j6`GW^L>7O?HguSM`Gm-gS0z3u~+xNb>&$&%;r=0%`I(&=Y^{DBX0Z6 z9fTyW>Z;+J0g2nE06q*abT=kp^3?X1!m^(*!$&+7$roQp(dfrUBJbR>eIL4MsD3I+ z+Idnn7@j*df?F`sRr1!iH%3nKzM8;%tQ57p^0wl{vg7mt4v(Q!iP`UBxzLCc7n*op z`FPQoQi_{0`Mjn|G6fP_24oz?SGZAqreP{(tOR&QAI#W;&3-E3nM9ivP@4mf+y&|I z@;UtrIQ>f;{l(P?DpUx8i(}PS{=Fg=ef}0o!4}Pq0c{BZvpAMo;+8rKGJU%;12nS3 zDuH9I%5%vomGH@LY_SE$o z97}N{EfXEhoY=oRMK%~Yft59#3Y-9&)OFset=H*EElStG896x$RYGfAnQH{sC0vyo zlaOaJUVGtEJ1!`CvnMo^oZ&81?dem=ne1bjb48m zr`4ZIjHgra&{F@ra2>ybpRj!GVW6G9n=(*$M`6=JiIt1keKQa5%^Az8!;=Pxs zp_gk2+D)R@{dHpBx|i=QIt+pL3+E(FLvN5e2I@jmM3bl)qE8H=kD0L#;2h#a`w#>J ze@rF&0SD~xd;wX*PbI~--WSkH>76B#;Qh*)OrsI~*tk!k z{5#bBYvcTTLj0wi3Hu49zluu(immcZ+K_!fbAG@~2r)3*eoKO+_r3}Q7~6Thz~O|z zO+qq@fk3N5Bpc))yT**`&p{5RK`7PaF37;nALQwb=#!NBhBer~kungODp-vQ6f7UE zmL+f&95p~4!yOX8kfmf7l9Uu;SRL|yHiQiUMBu8J+nD{)0YqjFicTM*?EsLDBq zjzPJG&hG7ePV-I9`z2+A9XsOyMpoJ|E-=zaV=n(vuE1UHN;T5NO_-aJ{TC$ruk-I` zox`Ph)g-~;;@9?@rs~Qj4m;cq@$nHF;GbINj&ELQm=-wl*F@+OMVj_Ip3dPLTOO?Cn!IKxY5c{W73f&mmE$~4y*(~KLt2;ySW&Fu}22By2!pM@k6g>MF3 z$klZ+=Uuiqib@(>*_vY7U-P#56>%2DW)T6fDL+37A1r4aT%fKHJ>SIZxcVP)V##rm zO>qVjak95@zhB1_amJIX#2ec}x7sdOL2dO?%!_zk`h+1O1EX6H(~t!717x7GwK+(z zb1AboOLPiJtgTFRTTE0$O!DSQ@>5T8_DJrFt&bY+4g)&RJ=K%`bv^@4fIP5o>B~qsEiHV zjg17kf%iFV=1lGTc4n8MtcfbU*ocC>P0+(s7OHyh^HQYpmKK^q92{go;d5#ZvKkR$ zi9Z#@B8t$!q-@Z{wo;1qTrFP*98vT((nK{9EERdRpKrC-Y-7%Ghg|Sf80o-J&~?e- zz+2$cUodvxGC>?2bXS0Ts};-ziJs`y_DzXiY1SsXb)LB_+>|OJCoI|-E}|dQd3&pq zq7kzr70c|xm%&?nq1k?g=2k8l_Ym(^X&zU7_^}phAqYTMdfrbh#h=@tA}M*NaYGN~$XZHpPx^{|=>2fx z%SlkB%5T;*2>fl6N;F)hOVam-ukQW{jk9=I&_9pi#b~Q8Al;N7B;IR{*y-KDx~A z#Wi6ZTi{64ikvSiVBK4Jjo+BxI6ZeIR*>)mcgk7WAF|(hhtwLVCoQD&NavOIcP*KJ);MUg@H# z{6k74O)5)pZ%kP)frTW_a4#WoU&@J};mTsSOJ9~1fyD}eS!tTp3ZYGyv|Y=R{e!fl zbh>kxjO#;yJG!i=G^w|iEZ`zo5Yz@T$pxnkfTYR8RuCc{2C%RP5jh6q(ySAXGgXcd zlHKJ~!yr`Y$Ag)r)Y(i!d0Iop0O3|TWZX5xaXD1MG`v3wTi3D{>Dz#Ny+#3UAle(g zNYC++3T1W;?QQwhykHl)+!%h}$aTm>{C*VCa~=72?mOF2^oaK&wBajE;j3xkII{0^ z`B+!P#}>sS)aN&j9yZ7Y9CZ#qoTfEf0Y~IqH7*~Tiyg-ArJY)FonTI!`hXi2Zc%QD zTbu$>u)t#bw1s=XIn2@ei=)t!K^rHzFobtfTE``(yAZc5Ce2CbpdUyG6A?Q!JmQ3=jiXjwZd8(hFZTa^89 ztWHv;ExnjH*NfZSYZJYg`gr_fV{xh+KU@36|HD#*&q={aUy%$^33GqhiF8F-K$V9~ z%}GGr2}wiva?=TEb9kWtN?<#wTqkKzx6DeI`^o^b^-ws)$m+^rUuNP%<}@?atQD}< z+ANl><{VS6u4d(ZU~>@UgXMcAc{(`LtV{;l&Cn}C)b(G|op%8czwFyqSnP2uwJ)hohn z%ygGm;e|3!t@75_1RvW7Wp+D_QtrNCwMT7aPiVs_m}ra9+Q<8!7P(EUa8i%WHjXFAAoj4;7oYm(tWOqn zmMmLNGGLL_po^`VdT@ABw=i7z9NT zppC71wairUb7Ko-Y#q=xtX659fW=m`;hhe$_Y1UtjV-X)>XbI3>h@!iOL>wsRc{R^ zFsnW@w*L}aaIM({A%DSci|Y@IxpD(l^>o)u73NyQw}Pki2mAAt@e;XlvX6I{D^;ZI?t5NMh}*7fc1H2q852!J8lk z>wW#ecVOF`u=jnYxnb?9lHm>DOVdmb34=(a%f(YDU`GTP+d1>2 zvTEM!BVe#CJ|X~61SXv4yJJ0+*~ir*oF&J&6QYbKwG%{o(81QN3_uZvt+1a5+jYp9 z?thH!k@*IoBJ?o=i>;*YA1I1o(`IpT^rszYY=OgLNLro$8e7!vjsH*tYy(~3@R*6^ zcVg(_v3_zd_s#+8XA~iGr0*Y!@V@)FbA)}Iq<<7hY}v+aE{@N~1+UTjCPbij$Hd>r z^Z|FrfW%g|nc{LrN!99dR)sI?@;R}c*V&@DS}^d^`#+0qSv}FW4rZqn`*G$5qW>kf z*Uu=z8u7OF&4x2oc_UFM*BF2zFt&AW$EjN1?)<0N{^r@EP$RqB&P~MNJt(x%1s|4H zklh`XLHaT7kE@5D?oNug$b5gd?6uwh0Tx>TMZmX#GPVGU(Dli?<-A!KXpbqre)G6k zkn?K2TCw@#0Wh}jo?dLr*?3;=z={?ek*$A7fhqd0~J0#|r}UkO}ibyaSe~ z(%b%jjO{6aB9Oxe2qK|sRQeLMWMQ!wqET6qVV$@uNErl6t+^Kd@=GOkTz!9v8Th9TRUCfWPJCr@n7d@E|H?#tO z3~BihaO4md&oiKR$KLo;+^Y=;k=}j%gn;@L^VLNb@+DS)NL)@}^?o)3$TUnEUY>Z? z^ozjZWH<|mDuQw_mt>YMP82{9QZDl3HWi{FO6JroMMcuKDT-3_)cGm(Au{hr71JFh z71Qt7WxemrG6PYSJ|p1Di*cCeV$2riQ{u`;3Ki$%far?_E)`V1#H%z6&6c|=E9L1c zsUdNwNH?LXl(Ej{Po&JLZ5)=_j>cE)f*JJ|an+qU5^Ao7n9OgLHI`5<>sxl1?Fd!0 zjwMU=7ry`~f}_qosMPR8xpGM3sv5=sNNfQg0Z43LPbZmvz^k50Nid+7Dl?bItC<6H z8grB^jv1HKWG!BqNDP-*M}lP@w80aeQ&vWb?0~6)&ED; zSwBS4!2K2wX%vxeK{^DbOHiasq+6s*1car#ySrnTE~%xvyHmPBx@GSyKJR<){R`&T zna`Z>IYWPrj|T*{08kv^S-EEts?dScA7`{0-D?8DW|Z1LZO?QwZmDFyURI2_Z7pQ@ z^9-&&+kftbip3Eq0l-Yj*PRU99H?rcqR*k~KCgkrmIu^MQgz(T8;*?SD2PsSJKMvH zb;<~m+#r8A?)@NJ`67V@iE*WzMTECXEIXk=$t~B+ zF-l9>cce>oIK0C@!W}~GD7F`S_^)0>g6O=d(4{2BZf{0Hu!3n&$@@M~dPN5g=VlWg z;w$jqj%ASL<^9T*d!(47B%8TE3>m+s7JRNv<2NE_EE**S(wPUDep;@oSQYFSZMe^!#xpme=JybEqT{9*Z}Wca1Ug z2!-3iwL^#2E-9iY_zZ!_V$?qb>=$vR8KA`dM?Tq-*~i@wF%G8JVKtB(;-T7R#^CQE zNI}0Du4meCT zUmkvsU>!1*x#C^CJZc!av-TLcf?!|$X%_+*+Z63eK7g_HNUH- zd+dI78gH`b1TeP45svn;PlQ~!fUaG^&9R0daboN*@&0jF8JiD!Q3L85Mq0?m26VA z7R4$dqWG!fJ;OWOZN#4vT8@rd&T5g3Q;ulpAYifenTh=R1!NEd!gT_Tszi*5zzf^JvYxmbB(H^m!QB@H)ajX11WH?ngB%|176sc*|B zXsd+r%$zWHL1TC0di0$H_x;*<$f*0#l{=KmLsr$pUJ47)A>4pb?|M8QW)kKRJP{c@ z4_2N%B{D_>d18Q2uTtyN zfR74+>y@iIoUA;gv&Q7g0IuMHRoH(vBcLwuvL^7|htJecZBV3xA|zkG+N4RHg=Idw z&1C2LBJUmiVlPPTl+N&NZ~^ZRo60Pr`QY+8dXH0Jv8AVw2%&ORb}_J(-wa_QVQk}7 zVFoj{sfThq=K$fUvTVCS5MwbCvk+m}7;l)JN?5CH*lc3haAlbLRG8OAm@!WHnq;`L zGut*O?@x62UT?Uzrp6xzhf|{b=O2OSScDlk!c_Y0-@1I(vj_y@NP%~eHAa#4(wxAs zkC_BkT90&vashd|m&A|(qbOez9ug-=pfqm`n1^yVD%_cu20(0?bm@Y0|NP`n&=g2A z=VzOXX6n+g#~FeltNKbV2?C7g3GaQl{A7F<;wEV*gadDmcN4>gK;H5yv$$ zxvAb1DF?+-ye?*+j(d0cxY+KY8PrCx0b@RAx^M06Z@%=;Fy%)T%Vw_ zmEew^xJ8xdbMwiMQ9MAyIH)f%bT`oe$1CavCq^nMZtg{5P*QRqF8OQ{J7O||*2`>0 zyj(N9{5d=bAAV7Nxz=j(GYf(W;))6l>6!vFf+FdLqzaM{q9!TgkJlAqys6a8m0dUH zJsakIxv5N~7TD}*Yv1g<^J3^8? zOPV?0&u)OLX@k6A89cT!K@??HDCrGc{{-oMv;8UG$DiL3z&j{=zsA6g;(P z0lH&P8~`_QY*FyU!+r~*Ypk$P(eatfsn1t5?a5kbtK?GA^TtUg?lxkvVg;Qx4u>{| z+&0yrwl^DX#^~+5uiN(}VC^D??X{lmpK{xoT|Jif+Le$yI9NKiMLKl!J9q@2^I3`u z40f1rbwu)&>Ed)ca(0q_?i6?JWR2>S9_*A8e6(Gp;wfuOskwG(3eJ&@cEw{$<1u$9 z#`_Suq?p{#H6+0i+xp4w{510t)zt4~JJ()K=ds0rfFBEDx>i)*kd@wjB=*`4yP` zSv%gDOq$hPT7Oxy^2^GM3n$m#V+F8*j9*XXVKD9YamV1&mwe229(`s`2(rzsNm zFcQyd4BxFOw02CW{ zb(>OmL)Wx&*LM4;TjH)yj%gq?ZAgw~Ea$S0d)$#TiV`tLL+%Z#0n@z18`j$tzv zTZ!+1kE!cnu8=Rd>F_mX54}t3z{b3SBx<$J(U$vBqc|!wZNba6YJo3(Y0k2{rs{C4 z_Y^N+3dO%m=Z~bz;=s}(0_E|B_!4qNz_x#Yy36rY+R|+|28e>cT>l+#k{Ntk{kxmY_Jc|`%q^SVxeiHQg?4)o zqg0vq4I|fl_6v&h4{ufttL@TU&KE4tdBOA~6ly?yZ0dTo3wMoLcx_5)ZTfVWAsv}X z9v04G9nQw4!Ja)5=9B1&{CTZ+>IjI%AG8v)(cv-b!w{fg}s@3vD+z zZaWOSRNhX2gk8mi-WR~Oi(y}}Saychb}Cy$0(3>ITXw!I?F1a}5R>gj3-7*H-Q~95 z{S?1jUB3I}QIH@{u=j;~Pf>YK!(nd?VdjTiViDW(5_$2mXZz;4Ge0_K+;sMpZT2an z_J7vwGmHU|&;3_K2kjJyokz3XY)^aB5BeX!AZ+VP0vor&B;;ux7e1#HMUj6Rgmg}y4r^7y5)*uMace0c*^cRI;%({;YP;czR0Wix;KBY)gm@gs)}xi zfZJ|7w+%O6AxcOG!4F+|M?C&x3^l8CEJQJ1Aw-;uU&Z|Yv)E$bv&S8%RP8^_%_9L_fUoLie>uKf;MZg79nLC#XgzFHUfoLQd5^T+S*@Ckl@Sz~4iAqlh6MtM?LFunfY>Uu!=(rZPQ4kxV*B^*s(R=5NJ|S0_8>*| zxY+7@S-k#VDFU~8+dssXpdCPL$sBf811Jor)`0F9g8}JdcZ{VJ)b^jncDT3uKPkfL zPFsY?15pp$V*5Jk`)i;(CQFCj9iu4D2q3odQr)mPb>o7~cunXkAVh#Owg&wATX2o- zRQ>5k_gDYR*lK`D^p1B;GCUu4!6g3^9^1(V7+cdUQpgL&tQcu?v)n}8LbLo- z>pey=sqg=$Q^L%mAM)-?A^8n@>6%bHOzS;}g+NQx`E=t#XQ2Dn2G zD*O3?#r8jqEgZ2GUMa2}@+S4JTW7;Os{fr_R9brwzi`xW)Q$P3;jG`{&y#a#%A4l( zwSlshzktfN6`9cT_}^fQ^-i|u$#cN+)`_bod(uT<63RjTZ?FXrTUhVw02X9&dLTU3 z&r}6GmmL$ZB5=+C8e8>^;}lyv@+B7Aw2BGg*7E!xjmT`f7>Wj;y~u711cyt-cT-UsSz0W_J{ zYoR$LglQHo%(+_jwMAmCE|J*;0xxBKNi6nDhGX5?L- z|A*KPHxRX=Qo53Ny1=_*Gzwj(@b1{D!lM*H0@eYy*aC>{cZE*4#a8&*38$j#2HqV* zhFff5KzQtp$DQ3I5FWdb$b>!I1D*00kBlvm2;)D-7Ll>F6@?$Z*a8|`G|^}OF}6It zZO^Q2a2^+1czEpCmzG5gO(hZS6NC4Q5GpY`W62JZ`D6bG1V07`v|y#{QM}x8Kb!!` zPU`*-g!PI~aT5|d^$|W2wb&To*8z*ICIBc70vg-iE~aG!a{YS=qMoP-*Yb6Wzi8hC zaof8+S2`$7wIx5$DMfPUpHThG%@M^gh!Va%i2$SsAH;2=Vq#y@qBsR9AfHByXZzA{ zW=dh`iu4i2W+5h8dZI&nv0fVD#>BY-I)V@Qkb7h%CBA;x=k&^c70s@=FJ4BBMbt7C zfEA%`FpsT1JH9kCFF|E2M91HWpk1ts)k7+u{iZU(_;&NnAZPy9e8!MrTIP*D7%*UNl9H3`ua47;~73qAPG0(;1kkP3W@!IuSM$6}L zk*M`lZ>8QQs2{F}Ndij)gyLivSv1Piiq>v5gfa zk}i;@N6wCio&y2}#vo0xiR5gEIPVZ+m~-bu`Xz&;D1WqK*ko=tTY0dQJzm)tJ9t&nt z%^z1OJTGK!ekP;t`L{?vNd@>K;MQCO7F)uB*>3(C&5aL)(Ed+z4k`{hSN)bv%hhu( zhzELi7({J?7VKVJ2Y|-5#9X1MV%p%Ky41?5&sb&w(AXNkaUr&L9H>mWxvc%LlVs!Q z@C%OEezZ%rO~6Db;=8I>-A}d$hg4T;TtN-BQXD1-YLA++zpr5bSwxUnK79zY@%@{2R)rQ+CyJ^)NCpuhDePU>pNwX{*pU8N*x&GaDqdo$kiC{kb#-zod10~W>rlP=NdH;-U8<7B zQ)up@^m#1-xw3;CbUZ;`t#J)s#hsR*;+B855cP6zOi8uu878Z_QPX||cEfB>^K7rV zMP-c2j1kwsXH>ykA=n4>El4u(lsmY z#crCb6Ii4Ki5-0z=Z@y`>Eux3O!>ggzV+4FGIkS4B7+BD=o@#)Q=MOIFHe7zZ!VAc z?q;Hge7~mF@-QT{k38ry`=ZVP?U}GQK8qmA`|CDbd3V2rjMXiZ#EwyV?*LIO16(cG zEq!-JaP9B4BTB^Xm9mQK9z9X=6xhAML&fdPh&y4hqTez7Tde058@GTIK@jWHgIBKy zaCHp>(8%IeF|BDM`PW#eJ7PweW^j$|wI|N(CnFq_@2Xx$Hsbe@UJf;0q`W2$uT33M zUifxPTzTTqC7RIh;P}Ryvdnt3shdW0O9pcKyoKOWvcHVuev(MwCAfo%=_&Pg#f(-F zW}e9{Q;KI^mTRtoC{vAWA%E?wcx~Q`Cky)Q_cIH>Ue#~l+(H{oZnzWfNbveh^exeH zxLdCKlE`${GC%J3ibDV>F~GTwWItb_w!*sp#M+xk@q|wC?2_!l zLGh|a@n%c$p5XIC4F!VQ=O=1Gq((N0L{#XtLD(}vSg1cT)e&Fv1hcFB;PCqanMEP3 z4Hnq^QMyAzwT(!_qfBd}%-|RzQ*8^~v2Em4;kXL1dTVEGYX=Or{Ene+r*;5h8?Iz; z@zWk?N+q@fQiQPSYkMWInqn>Umn-HaNoIAzaMi1ydObh=KRN6qhVKQ2n+3oe6004e zpE`c$iAYv)`~iORgHY2^jXl5G5x90QdJ6L3iA0hDp*Tg-#ekrBksMW^kQq=1z7sC7 zQ>K?GOJ|}huAfbL#{P@Bmf4@>56-!E4W>!gAp^p9DzRSf&QStZ;^q)b%FC^f!G&;IQT)v>_M@n zL1_GxNp+cb6+x*xK{(P%S!h3U)w4(qg29QwggwDz7&K+qS$w!5mAoMmN+F;8LKrY; zp>-imv)Q^xq3q6dz_j0`p5yEt+S3~f$V*3v>|>F_M3`V<2?k+enz;^sVMVw<-9Pbk8?PNIGhvZr_)B9W=Gfp;j!5Wg!+8Ten;e+ z{HN$zXnbIlKCJ)~u>W@CGxVr-t|)hBZG0&wB0h*xP88`}RNyTaygEkA^IFQ8p18mz zCYq@}+IcjZ4Lv5Agb!}b;N#D;i>U|4@b$%*9LGSC1w#9#-fH)6OMP zR0;B`2@eSg%S@h7Pb0N_BMlT|UE@;XV}$a0Sn0uh>Crsa^VY;ujAulWWhb6qoe~8$RBPp5N^ql%qft~GmoP(^#?Ms z_A=24vyAVkUf$Xem}e20Qv=#s^8PF;{#t73Y+Cbd+30LWXg2e9HXBI}2Y(JoKgTzO zo)<&4uQw-nAk=y)NA$KX!yq?Wpnd@j#_ZS?CMnG%J)fIc^i$!szSTBd#W`GE6PhpJ zpb2$2vDG*Nl4B(KWde>@433#`5&3ZuR>=)e0rnsB4K^4Y_9Tto0pNyDjnF)BYZqAP z3_NJT>BaBlOVZ?D=oFL;34wBl?Li`#bfcLHV$BN@f(uG&3sU9_(#{Gpp?cYSdb#s1 z`N@R^&_VFdU@B*PS%mU zg&nTZadunAd;k1zq1T;eQnCij%bHWdI@ctfvD`hsTr#y2Pc)gW!j$pV%Qu-mNpu~` zi&*c8d}(YdNE^)cvr=B&b?G1ASNW%^Lj1ZlEa(LY)pjf_iz_>(Q(5j(C!8$pLM{1H z{H;JeA}&>Hb5(2SRc^BK>t?@vwR+)GYB-5ZF(=f!wM5`Y&x`w&B27kVW_Oyl@AD)$?)U0*TdJReecG?ivB3t(b zAS;*StyR}9NFR`57veG~G{a~^n;Yq39}6J1gJI*^^`B?LelrYZrVMFq*XL-d55I+i zNr%^p)r|?+^qq$dfzz2?!Tf3g_H0`As)mMB!4Z`8hD+JV_LLFYZ;h-SBTatriMDg9 z5t*EGWI%gN1~QT2G!+7wDdL{P2d^a*J%XNXBYh) z!iy$RLEhho%A8(zzKBW!#d?F>W~3WuT!mhQ(!HQ%mnxN-_9e$oM@GuQd-D0SIdsnV z>-}t`Tz4ZUY)%@8nMI67D z&3b{w)@e52pr*I6trxmP8iA!4C98NV)rW4>H{;cpRNS}L)|W;`nPC}}l^T@8qLeSV z1SwW3lnpKx{8B3WrF<|LSluhs;q5r-=mBWsfZWtT)Ac|r(O`$*U>BBZui$SZ6~;IN zMv z_^>hScVnw6V+3i@D=A|~)njB!W9esOIymFhCH${h_37Nk+Y`o1G+T6A$6s!Zk3X5< zV4c|bIKkyM!K>2>9MTJ6i@YcQ23RdV{oNw-oU|=S;xXX|_ZQ#X`Nm+zw~MNu&f6f{U$d$w^O>tRu%300Hs93)o`2 z4tZx2c{e#lZ`xv1-QwZc;_%-^6vCxfTub@dON>94auSzlDwlv}9O>0kndHElobATp z>#Z=`owVh>L)(MDAxD3geMx_NfA~%EJ2ZLxthRvL>d$!Qg&Qp0h@lbIwLF${zmo zE!#S0sWx|b6tA!j|8SIGI5$8*=p8%*icL?CnoN+u`5i2}5CR(F!GJ z;O+PfL)QmG_vI3=<(nG)c9(*w)!>~S&8OO}dytIV!~Ul{WV?pk4ptdU4m?6ZX)_mjsy?;??Cab$E?XKN|`DqQbZh^IEV&jJ4} zQ=0y2nI1H6{p}H+&tskcmRL3BFhAn(0I8VwZhR=QI$YSQnu|X?*Mqst9xk&TRf-0g4VEV z*4XgW#Q_@Igz4Z0jqHdY_Y-=%zZIZQ*2y zKDiWx+MA4lzvSqa+=^OELv$R|vH7{I7D_E<;)nhRv4zPu)}5f*M=~o6yVjp=jb_M1 z$b+Hq#rB^R;gx-B$a4kvMx3+FiIDdr@WuA1;&HLPXL*z&z!%%Ui2oK_Dlf$U7TZi8 zRWZ26R#kEpm&h0bUu=7`aH;%(<`|VcAVpxvH_d+fuRGSf(*bnHOaYDUa$tA3;1Q%J zLIf%3zwVegQWmh-!Vz0}f>&@U0-q5fFxckBJJ|Pi{u^w+zWq1Y<|muLyJJF+-LYxF zVr#Hb08amTz6yEMausja7XK=(87;LZLi0!^?4>qNt z;`x|3ec1W9G*1)fgyQ>>^RdsQa@AAn9wOD#8hS(3)A}YbtBV;$0rJaf(~J`CIm;>` zpgz{Ydi8Iy{g1JgtHtDr&Gf>eL$Hbzy!kD7 z{7az4`FuiQRkrx z8hu3%2HW4)yG8~HAyTY({?{FQLbB%NtLTgTN>o%rea$;|#TSL^Rq!+acD#IjKQtB5 z5ZvTQf<{SL7KS57C;@boa40Yf%OnuX9AIomR{Wni)?xp+#v$89%f{(@5kXDzg5m~{ zBAksyxMOVuAxQ<|J;#k=(tJTp)R#>_j}*=3d_u#3oUk=mk$dIxI>;tyR>kt~C{ucf5A$?~HU z`f}-b0L0c`oHO(W%S^tCL@^qLyG)9fNv%M7VTX>V(TSEt$0=2F{&BFifV@l7Jv~jB zI0*-&2(n+Zw-Yx$N4y<+l3~n$CU_Y{=Y}8#Aht2@QTy|`5sx#iozFxGFu=SpnvE>m zRD1pa4HfBL_0Kfl za+PuRdQPBd)wJVIn~J?mnZaAA?v5U+&^eno0Ad5ROGA~3pB5Ha8ep{*KjN$0F-uG( zWah`0S#92ww;?_B&rd@ytJ$Jb?B-qVP zEFH%;X#d8318Q-xK8clB+EA@^UOc04sPEC)w{mP4`j&C^3s`KE)m(S)be$(cbP=Fe zO~7L7x_u{%1RZG}?0Dlo0M>gr{nN5)k?DyVDuPC$?i~!t^ycVY!RDX!!Qn(#N0b*$?a=l53{N$DM-rS-}Cl20zJ8y2Q1!LyZ>2+(k~heq?-a|==V}@>afS+wV_k4b$n7CmolQQu%`a3D z8dlZYNiF9F^P4OUYxbN?zbyop?m8(@Y`&BHi{%iFByH)5dp`S#cSrQ){HSpPWA>>0 zgxHe(n7JNjj>|kmLWpGCI_7+V0h>o!P1>6J*LmKXv;ydi)r9)y`I2DR)eCp&@7eQr z%fr%z%~vJLV0d?oex@d0a|%LmucHk}5eU;&%J>^$`rpE?+b5+@g0)iDD10n>WVzL# z{ne$!>a3O$@~6=$_Zz`lo?q46XWQur%-^UL8xC#FCM{@Jny1Wv(`dF!wQ#WJ;wc#o zkU!5(sX;El=j%@xKF?o}t%;0DwE@dt6lyKmRTnMU*HQ?qIW&Q0_fu`tWG;8(o9gPS z*yhWan~tF54Zq!V9Xj@xPQ4QvyGbcs_9=v$7jzokJSbguWv<&vAC3dx|8~dMYrT7j zXpJ<<^m-Mz@(HjAV0CBu@DP1{E`N=OPw>iLBBC8TrJ0aIz9~?Rat*hk8Hpj>?YYW9 z2f;!!Hv6y;uF0T_+vMyMUjOWH@a+29w->#=Fv`l)Hq(tQFmfN$*UIy_!S20=sQ%fJ zW~F4?o+G>W11mG9%FVJ5rz!8*b_hd~*1db{i*No~I^-Ihf9T^C=zj32uX+HyG=i{t z&U|Fg98Od3c~b*b^*JPuLZX$Vne*o<)nq_vBd{!OA&R;4-AUE z+=~6iii2C0!vt2crgRf1^wR`>Aa5(DY^w!2h9v@}-{Jt@;K!(9&GgfHN1SP2)t__9 zy6n`NkM_IZr|<9mzT1Gl-*X4t6WBO_U;!&gDu8S%$5HG@h*SoDmDOSPj5OTG(3-?OIL=!;{QRzlY&9Ii@+uAF^1y$P-Z z2{9zAu7Z5Hql9h~gs~=uZemF<=N)4uiSb-tyUP;0uRFQ}8e5YW#(G(jdp+*z^^#7A zgeNm`7SqPQULN14Jq$JCjh&>EUwL}uo0t=OqF%?BiFsCjHN{jF8%RIs1Nno-$4F-_7hU@<5_@srJ>fy$AsjgNZz zR*=ebwZNdd^x)aRqnmUh`XKu$)mPtw&e3gOQH8>{y1pP1s$hhEyPP_^Tu3mFnnp2i zh~9ee6DU^{ZHNdV55_!qgL)PLlRb|o(wk9)zjIj>^P1S~PiPdM460|-ng1Ln3Ipe4 zPpF6W#)ZwRJB)MXm`UW!qJ{Hn>ev!GZh;)PcXB`p;rlz`UJ}Bhd%`~3j@Na$vi-St z6S+6E?=P!C_q~EhjBq_IN>F5EW+Y}`WXeipHbN9`9|pcte!V_2OC*Bjd_K_FvmpW7 z@`LR)VPFSmFen-PXhi_K-+}>+trN);CPj$9GbAt>5)6fe&O^d)A(12n(fkFmng#LB z1&PT8$xH>aCK8{sVpXPNv!N178io1Jal3>B`)Y)S1jbssapf2u*5V!pb41nV@xXz6 z(z%oiigZ?|39!kwOM9Y8CfF62qFj5r))x=XlX~0~dj^sD@RfAgC-xbZ>_;UA*C$@A zCNAGnMmm|t@Ri2xn!`C-DeBa@q;z71EaK!G4R~v=4OkBQl2zA|%L)`L<`k=lt*V1k z>IzZ}^!=J{=v&ZJ+vXTLrBb{57!49rGuu<~w3vn&nMci-$LE+Q`B-LdU=;(|Y19_1 zOB$7qkbteq0A%{~W7~A#TlFG3{W<*)PRtDM{qzXl4C_sHlAfw7vy24wr;Zm{z+x+& z!po}2i3t7mBsh~ZArlp&8n7UkoMk59XJKOSU^$0W2l8mUWa*RE*nWJ{tj;R|gvUa7 z!*dWhZL+QJYTDznr+I7j)M{-p9XdO--$H9AyTX27*Lu*0Z`9>{C#2jvPe1ZoYhJ`kUK~RHSEl?- zk$fZR4<^!4P=qILHVr^`4BF7pxX{pi*U(DZ*e=l6snyu+(%72jBIg4K^u0RF;Kq{fj7viEXqz%mE%q&z3 zT|I9r^;uZy1iBTtY?w&XpI!y*AXQmnRlT(cJV*-U5rFmBvv9nA7ZfKML`nEdI-$n> zzQ?Qq!TSO+zxS7aYNm2g@E7K4MXeC623r+@tREjk)MT;@T>27NP)W*B-LQJo@B4V3 z{G>&w1}vJs!&v%%vPp-r_t(yY!YmSMxikknnd|tZ>weIOAF7ADB-Dj33~c1& zMi)88SPb@9*7r9K9#_2|K6sBXsh5hWKZyl}(L$pnpf7&qK^D*oQ$&kX&`a;28H8|k zZH`*QP{Z)S;_%V^@G;p4FxWQSHEy|#T&IrQHo~2!5BDPz3kB*?68l=C3cJl{*m1{N z1V!d?W&Fn1E-k;9OyUeZYUW#R2wO?y;w{l(#VwkxjU>e=g5&56#k6uVB^)x($=X;B zP4Vu>;~d)FHhEDdQgFG+k{!rW2+F-$oS-R|qh(2=7nEnj@?mb2XLY51gQWl?fhtI^=U8#b^oa(i;{FBgY06b{30XJi2EYjMd$)( zX#t;bm&j(9E?Kwp5TfDYj7%IG!vGsfPo>IKx4%{TckMt<=ANI6v*AQ)R|QoV0Fmj!0OY5J1pjbXzxp<;b`EV|^wWU*LRh`)K)^swqhOujZO%%Jke5X6 zac|vO-I6p(#30%7TFKzO`tp>l-Yk~WydYZs!qD>lPy)_y8vAfMLc>-n@{X+Yp6tl| z((i}A@NU(KfXWX0mrp>oXN?!s!!#Dkdlw zCtlr8%;8Nk^G>cQPrd<7zKWidZkps6pXB515GIBy(?W4E13n- zSzTs>hi!t~0z+6;!^wAlE><~ftHn|Lx~X4CZr&}$N0P>z&yeH9-uqRmGq2sy8@@P? z$g~i3QEfdjk1M@UDQ}-V*q7?QU$?x_+O$v4zc||avqiYJY2Nl%V? zRw>CJjNtG(vFn6C z`i3amhPuecC+iIq?+qr%#%kwA#nuKb(&iVcO<;9}8gI7vZ{Fo@c6Dzm*-oirr|7fM z89XQ&>TcoVPm^&?8B` zbB+ANoA(LxP7`|-hdh}-Z>!R89Y5C8%H5QX>~=ArHVWT0`So``J78xz=plC~wmaas z?VrKd85%wqZ-x!56CI8n4$QFTO7!c9-`;=1&~?8W7|l3ba{oJ9_I|lE!cRhEQ&@ld z2>I}ES+V>`lIr)F-0w@P;WPO^_4*BW6tL6xu=9*Re}#{)GhnwZu!m=8=8qa%KT`9c zkl@hp;K+#RsMu)Ie;V5~_+p!#`6@k+6b#N!C@3y1fs|F`{i>>|uB(N<`c>BmX=-h6 ze3T;m4`SQ@ym#W&)J)^-^xWdY^2Ex*>LX&iwYBnme|r7k=*tFsRha|pjRC9(vO#%yz+$Uq zoCGYkfEB@RuM<7#AVqkFl?#N&04ajJb}oFeC3j4ct+zE2NK7(a z9;~l28OHhmbjP6fyYC=ha*o=dkBDst!N&%NL;kv^o#mkvo;bM17WVg1V;cff2c!sq z#x~<6Tx0ul&neJyZWusp(f?U&8*h&7#*6eaguU;sj@KLBe}E&l7kQ6}tvd!_vHeeq z07JITT=D*=u@%48fBC4f{h!756*9i}EOH=qJTJB1>vXiX;D3v4H(X;oZJHCNQk+PG zEN}^-i4fUhFpLyc{R(Jo>EMhle6dv&?=wUZS8~dYQ=vAajng*P=!(~H=*vTQj|IYG z|8>Uzjjc^L5Q0lWjUsi4mAgGku?#n`Q-406qjiCMHOZmoUk0E~T^^K;T~cMA#%_kh8+n+YyO(A>wS=`Bad_+N`{c?TQSM+~mI zOt=(b|KQ(X3j-Ki)@mfNl*3;OObu4GY@R8Hb*u5rhqcRWA*J>EH7RWM2l-lT_2N!6d?f9rUmVanY|r_aL}e5L*kyj6Hjf?rVIDm|EIB~B*d{r zLd#h!>&LH3WglSsNLDq#fhqE?8}$*fy*jWPmPZDzwTJ=qUNL(50=};zwX#SDZ+{`q4j@*Er8h8 zts))2dPHphuN2{C8}_)^<|bI*?q*PCL-#__q61&Wbn5mUR7My)YHS7Q3n7)#EUg{5 zf^_u=EdwX@uRUbgTR2DV&w8+)xB-sc?|%Wu?vpU?MaKyt{uS`c2f?+3_ag%Py)+R5 z*T@@>i*3ut^LK_Gf6q;F0mOFy{Wy%0F$m#fWi%3r;%g466&Z(iIATlpAt)0WF*6oJ zQ<3p=UnWXYblfv%9A-WAuWJ1t+AGR8eHjEXbyR!X>sOw>aSdA4H?-zyl_YSQDZCBM{t8CnRpIZVWnQblG=@dOA&H>^JwEvW7SS^6QSpMs=);q z+Eno@z_tG4V(U7Ah1SKOcyXH0%sH8XyUFmyY%dXVi}&^oSD|>dx#|$hRADyXkjmIz zQVp=!*7gml^{qZN?9b!vks7v5j!~yWXhSRQ8h%7d3W80MWClocL-a5Oq zvekk)wnuH_)gPyE%;GaoucmgA%kn@s|I6U9rthFX72)I=H-q#V=LOFx*K$zrE-N%{ z04YKyHrm6H#QfM+nFmCU6^78OIsNR|v;0#KlF41`{Cqt9%fS)_wqC7e>*HFbn@k%a zhW54i<2puJYc0)QZGz@wHjWJ$Y_Losj7*a-Kyc9dh5K~}6~ReErc^das;YBR@T5^8 zG}|iQ^b@o3Nt1Ty8=`H@ZjSi`G$X-v;+fvx56~!~A6V?Sw<-Q8PBr)Dax6|1g(!!+(3a8Oj4=?B?v~xehr3mp#j9R;S1XZB8H>!EeI_REu zfW{U;Y{Ta`k@RnQ6PpaTQ2iMV4cX3m)0Fa~^Q0KfAL>4j%jOrA-xMl;u1`@Pu8i0D zlfGbZ^30$y*T~C^#pr}o=38UeQkhJU1EJ^zmm>e2Q`U<+ zJ2BKH#SaSSIRRTlA4Q>K;dC&|9It1L*&NB^(ptCUiCc+%x7B8d_Rw4|i=;vEzZ`KD zSox64IaxKGiQLumDS@zR1rzc~P13Ir!*_+Has3v$@2agq4Ta?aat8*aceBbvd+G^8 z2gU+-bE6N18sNYDl6BT4v&I%R>-_*?yMS-|lt(wf1QU8&UACi}u8%07ZdjaB9u!vF zxXl`7$a%ROQF35-G4yAkP@!sf-}3H*%&|9V<1aKGtM(V!^Zo*^)TQKo2=o*S!8A5C z=#3@aK>jQI>T;b3xwJPx#ukTw$G3+y%T~?WYYV#QH}dJD{oRM9WWB2`{>h_f_4^_GnH;|l@xN*bw@~~YN7E-Q^IhwU|%O*QOdK_D7Ex&imrsuBpE|39NMShOg zAIM52{VXt59sAA5!h_g zJo_`Mv1=!cn&2yaEsQbai#dbyoY3zX;SX9-KV-unsJ=glYkz3Zijae~s0jVVU)j>A z*&6fW(+Aixsu8e&wclL%e}7^3mdDOn(T+R74x~=RUu!4mNSt(H_nX#URKniG#@>IH zL<($Q-)7&uYTtqQQ;YLwbT1j;2%Y!(sZskgnSnxQ`==f~Iy(8lX$B0-*AUqa{XW%Mf0PUsmnF(p;rB(0-`4Q4_sD_qx(h@78)YOI! z&W5&Eq7t{tBmf?92It{lhMBd1FeI!P)hGq*G_A}uB4(sU5MJgOzN5}qm(4sp8-8>h z-eT~iciaV7Y#Y^F+fYr~0$k^*O$HK725U{6>D-XfO+8di(URO|15Cp%-3WX>Z}fZ) zzI2PM;n=Ko2c!rjLGBsi=Hwkpj5!?nH5?2dJz|KaK_7@`c@wQHnP1(gOtX^@f*r5i*&UJKrv}6D&?_9?Bck)${`Szb$ayTa#gH_hse53yGf4)u-MfH0$^gGzJ zx?#4K1|>@E`nlf#udDuE^PiRQ1$<3#fVPDi>MPB95YL%ElrkVnGN8>Nzz7teT@e5b zfzcucTGIpq!*PyWnl7L~H+%w*-9RD4AW@2-P0^r0=b&I3Wa-|ZhV`IG)Zjjr;8>O5 zSsMpXJxMZt%G!AF(OK{rcE~kL$fIt^kO^7Abqe-G$ONsfwX!a5o&=$oQ*C|f659KE ze7(kNr&i#A5vs?UAhl}}))nO3tAg|bE)wXMo`d11RnptzT%z>CQxn6}X47XSV01}Y zvPv`I1xBvLMiHn<5$LA$Y#Gl6XwqL2X5ti5QDr={)rrJU%KVM!4!Fv80g*>v?v6VC^|Z3hL9)>S{5v*2O4EGnP@c1N0T^Q&*$K;VYR?)hq$xSrH ztDmnoS*f^x(x|cl<}1S<8{O-J3q{=m{*w3C&RnK0J_lJIsYD75*SA+Z$h7 zG;5erqIghZL}6lFVWNji0U91CY5((UW&c!H|3D~CZ~-VxwUB)s^a>FM)}sNpih>P| z!CKy6gG_L8KbUC;Y>%Im#ht{ZoWyUR6uWL$$SqP#s|8GeiQ^?#Nha6Q64!&18@L^s zB*hZ1liO%hk|k2C3{q_UQZ6%79>!BP=*Y%YOR-o}cX=erj8n9p%l$U+?fdOF8bMW-1+dIrpmXJrB#cBm$xp&GevxVg zS&fOF!3B9W1rT*?e>ChOqQW5VLRQ_v%FsfboI>5cLZYogN|d7a6h(T1MKlIQb%b{5 z1x4&#Ma}y~G0%!M$%;Go3A&R+dP9nLbBjYIlC{Q))h>#AuuCR*O6Is= zrD>jLP%gGT=ac@y9FAk24i-1K=}%w9uUN#-$PD};mq$k|<61CV@m9Sf{~gLlf$|qk z9Sj%|_+`<`B^ zI!E4KdyQUw|2mh!I@g0bcj9`_Aqz?gKH6(u|00ae?E2tAORomYm_?v50_}=|T5$K9 zL!k*Ns%K=@(YH_$u7)(3f;{yGa8g4KF?NX?Y@oCVr~Cj1K&#dCuWK=E>x%>%q-~o9 z-#nr6LEMf5+j<_m9%lox9vBL5^0T_5l%`s@5KiV4g@V=5I9y_YXs?ly#@~Bu;qV-SLh(&9)|OIbG4U-4^TJ^M&o+ zlsyubYv90t&=^DZpnkzD1MV%yB%zZKlUd-Zcu=j_m@CIIr+dx&<8`wu)zWxb3_YFu z*gO7-ZHh=1vQC<2H{$(F7Pl`*(~)fIS-cudG^R}V7oA)WOdr)e=8d|zUAyocvUzw| zA_B5y%&VpDCciaJ$t{|QqMN=)fW=5Ic%o)^Gk13jZPsXGvg?|&>kqO2FzAw%7GR$x*7$$+d5d3PXo`&YdzLoR_~F z4jS1s=bHqHbMJpZP85+yj1BjT2uX~&?FRyHS;PbR-v(W?wZ|8_(O|LKS4vO6+_}vLnBKfGt#2K zBgLc)(sVKLET8r~A4$ti@^X{ID&`0_*~q^1h=R_@PT0s8bY$0}6?djID6X|iV)Rr~ z@{&RCnj!7ZeKm_B>_H0V49p&~IEKA^IYGg{hAiuXMjwv#pubu_wn|fRk2X%Y)DG(h zx~$`9=pE%k9i*ud?=ukK<<`hZH>wOKXf-#k;yQb-Du=H!Z2~$!dThY@I@v6uxR0uq z#k+*vHw6wR*Aly4qGi9hnG_wI64BZsMEgjO#HvujqV%AkV!@`>G%Y_it@SXi`(dVD zY{tZVrX^s;{NWeiZT{SxvDMr*^xU>j?R72cbq||$d)Tgj)%Wvg)}=vNE4a^-Cm{mB zt%Gx(a#nF>&}a>41c_>lrfT>tG)irL$2u|jVfXjsd`!gW49$UjzJ&nQ1!|iGNa{iu zbU|=@q4Z%v9vimU!M-RZzgX+BI2gY;BH9F9SoAqtoO!df*xl4;z9i9@sTJ?tGl;Z0NFLXL zRzB(|J%!~4UE{=@UMIuw1{2l?C#p&IqfSmN4*`u$bZ!rpkWGP4UvZ#STnpLU4aVDv zQ>2~MVk_qaHzo|5Q{?O)RYJSpsn!TBY%%`XlFOJ@m;EJiI;}%8V-(h-v0`Sg@5S0%1q(i;pq^y1%()kA5Fj(2l#>T!<{D5p2hl$%;#5 zHwJS)P);=oDEVq$MR@{bZ9ew#Wqd?KR`>wG!t;;z(x2}Olkek+?B`nUcd;)Pj_j8l z@7q@_vQivOiym+q9CW50^b8*~YiYGU4oTt-%it|f@GtjjY4EDRss|2o{kINIP} znY0X^A%r`tJDk26xGCD3c0St|Tt+}PJwXCDE3*}!Fp;zw7u^rW)o|%yc9NVRN2|%&kSXF*fY=4P8 zDYl1(XXj^0ibcP;8$vw*8e) z!1k|VYbebQ0NbVhk2}ce0^X0rg#nQ9EQv@uSv7lK0N7?rrTzo9Ra#hI;}4L_v>JJk zcrS}oD>d5l_+f*NC5yGzlMPtpS7w?Gj=v|C2kXlI65Ib|Y~LP!C-$)ch%JG19`8-X z#$dun{gqvo{Caux4BZ%$a%8b;){?k3@Elh z6amQCYCvD|jAjd`GipjW?9XMZ1G{65SH~(H!0y;5_k`cOlSSHqV(WGZw=oDr5gza1 z{wcOUf71UWw$JOkyiuv1q6mzTF5j18H0!?K6oK6_d?n-d|3ndP|3(pvfr@QbCQz~6 zU*8C2dPnvb*y@K1Y(X|7_%3(#BSjHux1vPQ=V9Fdu?6Rl$gr+I5nEcyI7~$oV0g?B z{EI-tvH!=5zflB(1j#&n<2IW?EX7Emhxo_Ahzz?H=TfE3k;9>J(ucw z8Xlv`db+aDesXLPEmUrRun!oy|*#0B77#|S(6&4X|W(?gvRL)sqwEy4TvC@X`?u(3wCp`y@ zO&7HQu>GTy2`IKe58*!*TRaVGmWgTdoVdWh!IW=J2ov)N-Y~Em8XP))^PZi-m z8Qc8g|2npIO>I~N?(%lXoO8v$hk37tevf`SU|<^)oL%~jBKQJ`B8YK@S5HcR{!lZn zfR}1NEny`4XI#bTiP-*ZcKFZmSRJ!)56jc=n04=e6D!HudVWh0s$v_opKr_>LZ1a{k))|M z@{t0-w~yO#pOJshRIpRB{)!`%z_^4#VNI1jz|BJAq@#A+<$6(%2m z>_YyM;5>>*DEb|q%RAf(RI#Y0XbNiD?6<&L*C)CdDp+t%j@-LoNk>o&jd(xe2k?2E z(s@kcP}hJ`f~0J@!8ei(kwMPoy#$B-SjHT@cVr3Sp3);gMOdMd8V^ys$inw0z$-?s zjIrWfX=VSOIYp8{D;VnqaM*!Kd%18?@Z{E3OOQ+iMBDxFLrk2}3WnM_d=ceRg?eCaea;($zz}U?_ zawmi{q2`xVgUth;CzWET>3n^?suwOZRr^Fig8SkN6G@j(QH1+rytXIBwmiJV{7$@W z;d0AM1{)p0X;ENB;S^A884;O4g3oai>4;>GQTT%rUh>rW89_reU?NJQ@y$Ef)EC}9$N8YfqLKQ2*p$%;Xhvg)z!rCU-iic#;? zd_X=^b@um?E^0YIvAy>wPA%!-907*MG=A1%-6*(EEXMp!@a~X>4k$miqtMOPGbuCL z8$D{^?B_O6r!Z<;r*$0N-tP$PSUNrU2%j%pwX4`2*6HO-Fcn<^El?EUNFx%@(3O}c zJ{CDF0y`Mx=SGK-LU)pZ4YekwKK|(S+4sV;L~EIwk9+vCe8)B^o?(MzCqNz%Wjopz zY(V*?upgqm9n1gbhp~c7l2UD6f>HVprp1*({gLM5@q%J|9{S-G^iQ=*GWQ!qZ_|GZ zefpgE*@&MPc7yVpS}_0f*e8_RQJ(;sq94N#$8PBms+W7C_z%11POdphn`)BU3kuS8 zt2xPHCSRDA*}*X-Q(3jNg;zgoiE=V9SMj{yxx5ga6#+2C9%Y7J@1;0x7UlcB_0lVL z(krHutGnkrHoj6~tap2lImxxRxr0(}w$elo4>^}bew#9NJ#SH`&uRiMov|e=moM8c zO!-L3_l(La2M$7N~P!rU^t=3R~7RXE;$fg`PDym5xC&ZU; zCpa7Ec^&Apj-R4yFIHzC0J2Y8x0jsKI-ItbQFMsH50=ewP*o1Tnsxv|w6zmSlDWhT zjKmC`98EYw%&Q&Iw;dsnx7K)0cC#TU3QmqrP6Sy_gfmXHT`TKB#fG7fPg})96_GDUy?cwODsEbDn z7;}MJx&wgWv2QklUGZT1Ik4TXAiGf@C4~?}mmOW4oeOGEAvDQjT~kQezPvy<$T?^~ zUMuMtVF-bCCnBg6bfNI_FSmeQ48M=zHX_HkvR|p|Eazsa^@GelGpN-LMhVaJ?v($z7^x zIF#nQaw%XRe0pP2xKYREquCd6}sI%x_uh@BmB$;_{i643>VIsdfRS43=Q{k z3_E5c$q2Ky&LeH8qK1v4Xr!VL-!M-lMq%z5F(-MvK!81CF^L5-wgDU;382~UY1wxJ zJ<0nO62(k}Z#@~2e)9c@`QsGx!}sThn;b)71mSWIF11`BicnFj$Op~kqxJszEl!Zu z{Ef4@xQjRL9BNlj9N}Et7lQavN1w0rN(!p+HQCBGxAD$}yc$r8H8Bh=$pk>LZPrhy zm$z!o=DXTPvw*5t(PG(fC)%qfF4!e5$0iQ29@?TNM9wOUKHGv^cr+iln4cXIkUxoZI?!ylxboI zA<&$x2`s)T9&^Qyx3On?o$SX&Pz|=PF(Fjwh1rW#2SuQ!Z19v8u%vX*ru2YIH7OiZ z`byLKQdZYfMhQ|cl1L|M#izj`vo|{P^FS_=d^wmL*a%ynciM!80ws%G6X*SY$wL>4 zu&cDJ*XgVr=@+Ulm%-^b&~(R%bRb}miI>s26^^KufkGF7wl9N0D2r7{_kxffhp?(v zA(M@W0pGQ1!yuAK?ZXWyvXeSXfGCS1$(?Gzoz}HlqDY>x!HCJ#!)rUrhw7^ePmQ7( zr>=k}e^Sk_L{AB|oI|Iax6mAoY_@P*Qz;(PY{%LR$8Ykkrktm6Sn@T%)x5p>*Xjf> zjikEg^>uAxd7Zdh;lKK4u~HvS|5s3p|u_KBb)&%1~w1`FuuWsEQ=i zrvaLBhwev*ksg{*9R?}SPd&zpVGU2B1NXJ9u`jvlQojhGS0lXY^=bkVnd*ir%}waVb7o*G{6M?8=ANYD zKB=U<;6VO5yb;2Z-Q<>^x+S7ln)9YXiwi-E=ngVh_FJy4ttO?n$qxGqt^JuPUC-K1 z7gEkmN&mRET@i}kgoNA`ia+o;!RREOnUN#7Ng$b({}fL{la|C7EXOjVc(I6tO<$oP zQ~@!lzzfwUpbx*FF7ucQvGL~E#ISgeGcSI$yYv8q>z3_as= z>zc^Qw4g-?o+P5^{ZAYHlkl(`Y>RGzQ>G3o9#UV@4(w*;LaMl{ZVBw zI|4ZezrQA(D(9U^j&_mBjnhxVyB@Q~7#HGi7K7hDWFWAs^#Bu9elo0F1+lJ;UIP7I zjoZ0ic08It;(jFM^(B}a59EQuEUb9qDN*CC9pX)D@~eLLyA9;CpeCdy4-}eX7@9!Z ztW~&GAi?ns!&MDqr;ySEta9n+l||31)f>^A8ZV<78!&A8%;4S$1aqj|n9iwGuuo%)Ww7)oVtWh$XB<#jSOmicOOGIBtc>zMG0#|Gk=S5=!lgf{(`{? z8Vn}8!-;o@)jb@61$3HXtShQ~>Ub>EWck$;eU@1aLYLIF&*^?)Y6 zR!-ziO)w6_r0DsiKOA;^ltp4cqUPi`;P#+Fkjmgsb^VMrg-tf~S!PN>XG%PL>P^Fx zOiPzxPu0#=*R8~~qTCmy4@N2;S?bNdoDJnQimPQ8<#i6D?8)W~Epy+G&6pndg!lB= z$ky8OebXY!ITQaT8B%+hpQGPdds8>-!3WP{z3ua9SKr+$C~U57yYBn+T-fuxi2K}x zFmHd}y@U@u2_EwxOrNl#ehQFJ8i{h4TfX`px}&Iao(2@sv`|QzP=YlWSeOv><{;=6 zy~bj(E_@I=v?wt)*m6Hu>(o}j*5f#>P9M`3y)(KnIiDuSG6WURU zHaJ)}sFXJ7aXV;AHgdZ*)Ze)oaB#$nL7aJg5Xda>UM< zF3s@xdP)lK9PZTEta#dJ%&ODZI?9>e@9f+;A&^J?QU7`6{5h6a$1I4^Tw^~rab%SgLt2Y`rMw zbx>M#(Bz5KnyT8)u+*-#wEqgE%ms%SrAShKIGlC|`Exk2a@TU=KUMllq++@2OTe7x z{X)~xz-oXz_R6sKNIII(rsvA8Ma#hw-cHf+0!*lsc6H_C_=@B)+&TG6ua@9cNkhTO z{s|%c%1P(h2@>P!GX@x9*&0UpDO%a-Rr{$UBC66q#a8;??pU}~G!R9I{`REUCgT28 zY%@OP!`%8-UiP)mW`utUFm-?&n<(~gf6hSnZMswh=Vha%4 zh1Wg`MY82Q-KI5WGi6%jK~KA5^M4iF!CH$&I=ywFC~3~)rAF)D8{O);{|DIK8NxNq zS?PEGe9If4@uT9$K;lQ`l@xNn^#AUT{qKq`OdlY&ypBOH2&@lAhLf+3pNQ>SPyPDS zrA`N!Qp7!i-A2i|a%K233S4J+;VAX#_~A1`$o*gG?UMUF59nJDB(|*A z4WNlJeiuSt3(5>;?7+_qV5?LCq6p|-n_(YoA^Ktb6M$#?8C{hk`ZMx;c8n;;UQYCv zzZqMlzrYr#*lIk21QOxhRdYZ(Jd%cSC^p>rQjO+}lZ$ zKzstWFl5*6Ct|ysDaN+Hn;pet+LIF}m(=xlcr2IiiP!>BghGf~oGBfqM-C80D6V~S zY+HEXo;?)Q3ZQ)L0*LMZb8Oqt+j{>KMfe}b_J3t;6^eTP5!(&Ri~#6%S`lNz0T4xa z%GjPD|F0;*6R~{^C@*UxdMR_-c0rhO+JVG*Sl;%MllWi8wu@W?^Q;HSXz8q%)QI8y z{{maqffp&ncBmhX_#{Ch2uOBMQ~g&FO%*4U&Ph{Lojf~{p84LRS53!YRw(xuVWj* zg$p>g*PCHR|Ie}YBN|6#1To*PxxR;e3x z;l;5VU1|Nh!BgmKE4~ly6lHwOy=+#PAIIo7!$_tTt@vLp8IU(D1y6geIm#Oi`dnbwsn4Lf{oa{yne61f9YFzLa+`cyC zZA99qifyn^Ji6Mc5B|~sOaWNydhUwEpkot?D*lwQjbdvEPPw0A~ir)g>gXF(D&Svc|aUPPyPTm)PZHhDDNbXvV36KG!? zswGHH?E&^nJo=_!mxRSIpKnQWlc2jwjH7fXeAmSbEkUA}XW=Zuc_^Foq#l7=V>i;v z;AIexNFPQpBuW5hD+pOKON{h9I#eb)2nQ`ks&ZE}F)TXFv8!L!kyVm81SeKtkAea# zI8Kp}GHw6>whh4USeL@H0edQ?nR7`4oNtW1etDcX=ZV&ZvCO~X^7S6~Kpu2)tSB`Q zLn=CjF+aszI#^ACsiCRj+|V{e#(_@H<@fimFWX5!+Z9*6iDYk_E%h>Kn zj=C;MHM`5jA&wc%Lk!j@ta!5D))vJ0leNrV-4|EA;TPKomz1|UIm}2!Uyr(#=c^+0` z{*$#GaBO`DhDt1%`UJ5oPwB`orBS~~ENu`v`O(UhYHIXpv`n2s$HI?wExEw^3fqC8 zb<7tv^df_px+!Z|WzM~gNqFvU!9DHo2&U;%et$v<8I0brtHkeNb*%_pC)jjZb0+<` zKihh*`GOE3g@n*LGiXb;+y`%H4VhPkjY>k$3tn;^U3pH3)byn{g*};6L|=3?q74-j zt>l|{KkaI0=hNNI=AY@1r&cLo1Z$k#A14x*%q%4?@ zLGQH#M3mEGT-NHfe)^-aq`2(9LUO~@2Tj^hr4rMm5&OJS#syh3o`d{7`}~^cg-^R< zB_z|3wnugau+*U*)1QJqv0BBFfy2%pf9AEqYpXe_XH1<&isyP9)#@yeYF*VGEmKJ} ztT<J4~b34{C6YcTy)b#Mfs z>R__?j%V=n#yi0?i^M`yM%o6JiAzyPqGN`2y?{7!xmnp<(r4AU7?aFLr?&UO`g5P) zI_cFf=18cf5|0;Dy|d_S}8G zaivflyG46TZ)O(aP%>K=u86|yg|yUjGMCt9P25hJG;&$n_;6$`J`C?DkASh5+8M&I z70Bzi{;G`TB=9v0g&^PcD=4IkMy@H66|DD;yQQ1wax2WjJX-;NK8{;0H`1**cNp*H zcgBlmhR>r08kPkYUy>^KrxkzcYN>uv{j{BsIRC@QhdW8H7WNukNs&rK%Li z+6QTsT)E>5FgzAH!iR8sGZxu$k^f>;P<=K1K&txk4S$)q8|-e)2w(66$+)Dl%w($E z=X@5beR;cTeG0SB_g`dTw~MO=)E`s}uga>Fdlz7EDrU02-=G{`)iY+OATM+XTL-TB z^Es~`TyGpM&H*Ye1qbip1aIX(<|^zKq+Av=xIXh7K1SUZ#(ykmAgJq9mYcO`+Z@V! zxW2jNmWMNzuBVo#R8~Co7#B)bmou27QC30SR(IQ0MlY=;xSk`3Tc7AyUwByq*89<< zwIa>S7brF_$!%UK+h_z~;|1Cf1mX}W3y=f~kU0flvcYUkX#}Zf1E})fkoeis<7u>0 z+BrH0_IUu^6-wzp^?kMCbQ;&OPcf}j zq$HInR{NxNd|dPL-`C_wZ$RD`)wz~X%al1$S5UiEDbv)<%G9CALXD6cd)-=QBhz9G z)n2*})zLAm>0po_Z#mL$87c#0;3~ zd0A07#`9=Cv#6W(M^?rKt)^eyXLzl-xj;*~K7%vTYR;_}+^8k~+6_yI-8e(sI4a}vY_cRo zt*otR#L*j4l#01a_fBR%1!DTEg=RRS&d2>u48C3D6|_y=8YHTgC`kf z;C#xR-m8+{U$4jH_&%01JUuQwzSkw;$~n;}{6kMVoLcxYC;oWZ$bynN!|98LsvKh(!-pwifXx#9#hVO zSpNQ4g&sX)Ac6AtgHXxC z1Qgr8x$@E7^nqQN9yUfrmY@FAt_zY{IDTUW@nQujuYnPKrUFi-oKl3SQ05!cOgo=U z!hLFDDH_t-OtM>=cRX3MidhfNSr}lrrFk8SC^#0vYN17UF12bgw`#7!Y+f~EnPkRK zx7DE>ISNEM(S}T0y-dn(F|j>48jCqcS2;{3xq7^{`3boyuC?k5u~pl-+NR$SjoFO| z>uf{WP1WjN?B+QyD&nKYyV1wn7jglS3KyRGxT<`;>3q$b{Nh)TRSt-s8YIOU0*!_2 z)k2PDAickzA{Bki1)A~&2~t>~2L7amg6Qc2S$vQdT;bvS!h3Rany)$O zYQIDz+8A86c98nTiFie=rK^A_u|DN+A^5S|@pmbmKz6kFH4>Mi&hrTc6W?iw}BnD@ao;&djGQY<<{F$Tpj z7P9v&ItO1Bq-xF0b8o0wt;}n==1nyUYaNC<%=UeIb z{Z!BQCgS#6>pqQY@z$_YivATz!sBCC`|Xe@d|W|2zv zAXctfLrjfd+P+`0*$bd&P`;=NNVf%a*tLWHB}t8x6^%^ejqGQQHFQl-wWa}vH!Zj7 zq-=p5`%M$Xc4N|Z6N4Jl$-@Ebb{rSQLPkN04nfOq_5`PzFt-t#EBHh9l5wyq(msNaA@0;!$=3Os(uK?r{?HLPk}-Jxx7ZxI@a7VDwN62PW3AV^o%pbJPjNjo zqVd-n<9I3UG(D2nH#zRJDp49X(P9Y_T0y)>JQ z42OFs@ZcIy*%>y`8Lm(zkb)?5=q57czJcgOGtdQ`;(M%hDcn!VlT6PFbxVgv2L^Pj zJTR&^O|RgYya(rqNO^+tYBben_7i)w7kdE3);jDbw@a;kO09!?uYx|i&TVad!t9Uz zUiW2o@B3LJ;XWS{&LEAs;1sUVC9d$pzDQ!8Xc?bachvYHr9^WyFdtGf1A6LV|3Obe zrUqX&rb;d!X4)N85Hv7ZJ}^HyPdRD=1lZb%iH0(%+S4{Fx10f;R& z*-(@8kb=%oZ`e>ObZFpcsI|~`?0zYadw4=tW7^zq_E2LXWtojFSx`JEsiJwaILPB{ z6hU)kZCd2;UZf+s7T{P*q;bEBS?XQZYUJzvv-;a}ISP zq-}hU>7bXDW;&YC)r(M6kp3tO7@>#^p_B3%lR$>{)5GLv;wd5iDI=w+0de~9xo0xX zTT(|;3J+WIq`%w+rj;#>Nx;)8rPCVCzrvMj9%5>=`DR2-VKW91GiK(j=e;wgazCvO zXMi_wYRXw##yrNFUdQKgF2%hb%{%-^bDp2(d@cGsFyaHl=YqqLLS^g2kLDs%Eut+@ zW1E%YOAr&o=fSed$sWq7!;tiFjLZk+Y+04G&;dv|f8jFLllyTeN) zC9AR}%Z<;FTaH`|w05VpzS?UYEv@txq=0uFjvF0zLrAO^fp(IgZ6Ce#B|7ie!utteuf6gXeNRX=|JhIUK|}p;}o% zTCzc`-SNRwnsG_$9nq$u!e)#8CYR?V*YKu9+a&+dqySbIU^2J$x=S1fA+~MtFjdPj z{`v&_EiV1bZzh|-rCV(DmxPtPmSzqGm`NwXb4R&HVKv6^ILFNM56k?vMTvq2Q?DA& zY(+pXAM~4J>W=l`j`0gc&z3xCv|V2fAn26uZ^;!Hu^XJ0ANrgp{CGD~4mFyTH&$ye zF=7u~ik>dRmwK$6p2nA{wU86BkRP!hk-J~UXI)`#T_w9%^Wh*(^q_ihu}(`3n%3AT zx72-fV2pa0LVGx{Jk-Y~XHakBe$d<;}Zcpo450N=o%K>y&-fUpq%sIaKu zxQK8dW1I4q*k)w|#5Nl(xFER*zN7>aUV`#Zv8|SSBDPKX9i5%>J%D1{Bk{C5Hl+Nt zJ2oNql(C&R1c0sN6R_Rj+uhp-6x$=U(=%p|zZKh?+dqh&KokK1omis$sbc#KXRi0Z zyJIkkigzN<+*tu)Tan!h5ZjP{8QcFjw$ibtdQTZ!!yznF>y0MbZ$=~OpM2p-=&EVP zuz-y1|0A|M?0yPGUn@*S8{&&*vD8ZfkffE&=c^1SvykX(KP=XfFZKK&s$p#O|$0}Ws0?4!!QJSw!wxY!sGAUmDiz4v!w*eVj zfY>UhWdgfnmuvss9ShOj1{=*}=HUUvHZNK6AF;jZN_E~Y*h&3-vA6T2*cxYuyf)p< z3?fWI!B+nZY~{%Ia{ei{ay-3xDUJ;$h<_`#8Kk;T6#ps6v6bMq<-6! z9_4?4Ev&qqL-)TK+b3e%FQfy!Wyu#Y)JzzvAJr}htsVUz$2QsW%}OPPcjIa8-Eq_5 zj5Jg8_pPUl?f-LZjo`}Lzmuf^j_p`>N7WNDM9o#>pFeBXOezaM z*pI$v^E&^}?pUJ5<=@@0g}2F3J{bQL+ev=ZC8tdirxn}P;j2}LD_PWcey_FaS6$zx zac%f=j&Q*?qIem(*WbAGE<-Lq| zht;!|jWp%fF>W+v&XtXfZ7A9p%w2avLuUgNk(g{ly!ykxr>x&U0Gw8T z?wLRIoCzoT%Gn?USf-zRg^5PC0|hX%Uj9T)d3U=VB*w5|o6y%q#X8P2UGV%hET1Oz zSmi842tN|Hb21Ic*oN+9M&kFP!aah{!tM#82xoWGk)UVc=pj+WZ|yUAl=_67hx7wv z0LL~#LX^%nn#@e3PpAVT9wb8%8PFv`PQDi{rVvAtCDJd&`b-)$L;kVgD8p)DYox} zN+;r36Z?nMun)jvVN~TAqCm#>chW2mZf$M1tc6Xe`aY1ceTpLZ&};pcGHN>P9&wuv z)p^<-1AwhRTA1#2HFY;(&zE4;!}M2;AhaIwf57&a3IeM&%r}8M&hW)FSi~i-DtXz< z81F~YV3Zhpfk}0?_@LTEDThLcoP{Yx{DNdrk3xyAg&DtFo4_ln$)tsgJg(saIVT?0 zSH@(>-mf$^FqJu5=4ByXi^;!y3b{J@Ep6m2Otn*IY`>uW?(3F0 z$BydXGUU1GZ;Z){%jc6dSGyUQSu*6P;V!Xq#7No31fmEGKzB-2>qzEf%YOehN26-m z&6IM=oyq7=_=^!d49E+vK>*l7VHqEoO-87sj0Ks7$B1MvGKCvG=s|wD%R_ z3#)ULlIWhvJ@$}l7(aPUb;LF!Y z({zHx=k)M7T!Jjp^fG7X_V_u7qnk;8>@4#Sx;j>q(6IL%^DlVb-L3AJt(v090a1ke zwKKaCGX#9~1)io_gdsq&Wwcq5dRdR>6k<&tbhb`-wb}K(6eU*rd@t#Kiv~7`_C*D+ z$GWG1*@@iIXhf4RK$-0mEM~*|n>fH)wtNLNt z)E&lJ;fw2i6Snf1S3`fe7*!&$YTx_yT6&`;KSaI}>-5*oS+8}vJ_^0 zKB_*S9euoPggu~W!og5YGxk+l7pA?F*}ql{D5}r$6xQ~bRXTo0>@!pQW!5HUu1#sK z&(5RAZh=|PWBAJ)YuDWLJK9TU3&MJD;%l_|1k|^4Xym&VNpKjh-Mq_&s72*IfiErB zIV`u7EcLA|cM~kf$}LAHEhm0k8osnT7qb!oJx|C*x<^)HhWm+J0fz=>Ei>mQ*Y^@W z&{~1ZUs1&$G2i;G>ec7=SKQBRw63i+C2aJ#0#FTX6e?^;5(C=a*pkf#yi>-d*wJ_w zh)1g&=x7``9UnOR-OgRYj-yU^xkh-U#*U9VNWdv5XpT@++&*khOX4c%L{#)QW$^hg zdpQ&bH8zK&Ytip0Fddbv;Ok5W^;w4;6*6rUM_ng!0~B4O*%0y=N7Fh-*D*&+6sKC} z_qLo)_K6hIwoa6JPA-DYid2+%ApXuASW)0L6CB z4dJ(26N)=t_Lt5?BeYlYvTG(1^--9r92f!!qv9U^9MM$%9sxaHBYKQiu8h|b6~5|w zMk|>l1(<-vOx|XAVu7D#r5J8JdEpd=eklreo3cQEvIqb4iREU!`N>D%B_D70?Ymba zM;ywW8TvKMOw`0YvF&?*t@$en@6j1lf;n%1|0%gxP)o!!qFOSeVm^7&AWRNtUoI6a zo<1zTUEl4Oe&*bMq99eYjHnM#IFnO9N0&r6Jb$J7ME7~%u=}Zn06%4|tpdUp4+sK- zWOQvBf2pgkgUnFDq`d)gXtp+7fws4v3O6Q-;z~Xi4gO}3tY8qV;upMG5!}*GntH9B!IhF_tdpw}l8;Yb00}9Ah(9^C zG@(@zp#+Yhb)Zn;%Fre*$rfYDHjrM2N?5mZm>#q9Kpz#*uNZ+)kK>0=f@mU*VBz60 z;TN>Di`TTvTy(1tx^-0gt?Tr9+X#3bhJBR`q=AT{E7?=fhl{z4=RAx?RBnKx`Jj^d zfFJb;A9c6!rDHY|$%LglkcDY1hC(e11sfhq^y_PA)|8RQTb*c*&S=&KVEpSV?R3^= zK06Egx3{V$G$vUBggHVyIp$Re7s@{+k`y@#6s2-wKXNO6nvWGKh!r&P5`lXC=>CoY z$(5kxkuot)(cvlkh^9Mjp7}fOD}lu~mv|s!TldkYBFcxN&w`F7-#I?svnKxMbbRY+ z{1dI+bH z6pCbma?}dZ<7^12!RS+Oh?T*mrr=?J@cUkk$^md~1DF8?KMp&oY2P;YrpS{kXi+q1 zty{RnrMMU^c|gj(dcJtjJ9+Y1$@iS(#{OiDi{v?1(soI)PPCA2Rh?eRkbX4sK@;-f zy_8WG$8p-wDb>^&G^e>ei3L>($Jx}li&Priw2d35Et9kzaGHH(+Tna!=v7*cV)!|C z`X6xk6`ITqx6EBI-NOwXoLWUSYX<%uJ#s_ETvvqVWyMjS>)CY%#X$zPtD$K^C2m9I zn~+S~+DvA3BhrR12&z?ZZ?XtZAtDV`62|Z>ucC+Xsy_^5jXS}NS#G~dU??o*SIZn^ z@tB&tr;SmqVkc0Ik@^j9+h3*DSfjC6gQS~NAQmeVk|TXHqCZuVeqCbz8dj>wS!%CX`r5YCC9ZTo$#G)7 zG~lB2l(0;MwM=K>wx=<28D2y{@{myAxaOFi5<<3IofM6TqQ;ybHj_H>E0;2-k zjP6yk46a!PfqDmVTLsNM11fr@#^nzTwGWg;oxhzcFF}>Hy_H-|l`U75d<<2Hdzo)d ztMKij&=3%{{y(nHf}yIlUAqXCz$T(Hn|ECrA8opJSAwsORb_<=<1)Qwt5OjsECmBNb;CnyYb_>&)nFzlcn56Q_^T zXN(dbq|q0kiDHeC?{1K9v(J;Cq2khA-?332$>Tt6#x?~rzY$XQFi@U?U8;fei}-aVaU)cr5yBJ@ew$=^qtQHA^ox7Q8VSE! z6M)cddK!o55{p?>2%8~+^e;;mrknWKnmdwhH{ylo7Ki!jnpaDRS9nG`DO#ix!JCVu z+o)u_p)LE2qKBctdL?=~Xn%e{eyP!VbwF`r=5PRUc+e1kx_1D2VHc8Z@NRmDVbsVa zZSNhzo{GY-m}s$i+h3Rbz;kOyKA+BkbJeO;<;H8G^Jx0@qQ;;Xm)#vBl7nC|@ZQv83nI9pOUn%DkOy1uv+~2O# zpNIwzRKvha{d3j@8B7D&hkRDS{NJK#1SDaLn-+?f2Pz&G%1Ia9SO%-nG-|^K>&yoM zk29p^b@NbB;oYFw2f;4QCF5_!9fLyy%}c!i?z+@8Wj@?7F#IuxaK&v|0DojbW@L%E zW$x$58hGTUW<+&tWbc0D;?<}M$Ec|ybQIZP6gy^Aq5N4MjD0nVk2mJWHb$yE_L&k0 zwS^)-QlW-RpdXE;b+zSgwqf#)E6R<#*^F}~jQeA!pU;oSUXPQLzMw?!pkjsxVqtWA z8H`%%?;a}(5GNT%GCnS^>ncxHJ5HMAO|q4_@+@`QiB|EGOnnNiQp%_@Al)?n0V{nt z#W~5!a@QrN6^$>^t;L)j>CnB#;m&pEPQztFh&3bBvIWGf5bS4ct9m#Ix2=YIWRpF= zQRh~(=UQ9LIz7(*1R#Ic-XH39T?xo~M02w9v%b7@?qxtNb~offIjq#eS#sXnU_Q#V z9~}M?Jk+0vx{%Dc5VzHkZVyG|WrUP8?`0n>R6g!yq!m{4;nXzwH-s++_AeI63e=(E z8s9875`%hVK)80GH*rIK-AfQ{f{`Ztw7sPv;^hwhAWoH%Vv3;O{>uYoA`7J8h`!|! z(~%YCm3`@z?eNm)Oqh($Av5`LxXx+m%X7Zpm!!H^GP-wzWp^@fABJ_GNcCXD#^5|8 z;M1tx0#}*yo`G5%^tG?#YdErNc$VP=@0^J+CP-WK-;k}taIXVu1T0UN`5c1}=!Wk+ z&i>G4((z;-DsGUaXF>_8?Agx+c%yhRvV_7}-mY#jVX`w^uwut&NjyzSMno&3n<#{J zs~lCUqQ@wWOz-4FyCt(<2&|lodR~fKvFfDd7&C7JVg$?LZFAJPmvpmM8nZu9ckDc7 zhXTyqA9|hN<#}uFfZMn|7cs7N9Ps5 z2z~@}eq{anctiVm+vAwV=eKY5G4afC(B(1AyAwF=ldBfJo2M~v{BggXRZNUEnARV# zk?r`}r$P?UQ__^vHyG<^Un4NyXJCC_XCCf2Daa@ZJbS=I!U7muKPBL6J~%WeBqA^> zGEylnKH+~fw&{d%S@Aj9`AS(u1v$lKh2>>MRfSo)9?#*izl?2r$1`L5uM|O(@C_ly z_!!~z)cE}D;==OM@0GRHvH9ig&DpKpH*5Qc2girUnn(hUEL*#4Ik z!SPc8MVo(j=sO1WsrpxMd&9_hv`fUXH-SUdFFu-u6}jSxOgsr}5|ak~;7_*eRL-_W zJ!zkPQC3Z2cI7g~oQagw?FuIIB+|K+2H5sTa}}Uf+Rf^pOlN-m8y@?Iv1QDFQLEEg z^N?AMD^qXOIjiJr`$vj!VJ}n9m^&LY~88JfcDkm0N>xzy4}$4c}%6hmw&l zgzZh{#TGnE5lqR-pAp+e2MgwU+s@t2f5KxI2m}?Jl{_8KQiQ)6+ia=8cV3bI>5esC zKQFd#zP9|k*nZXyf7aLzI<^YRxZj-}9Mp|^0-|A`I}mOs>L>h{#x^g(ju&eu z#b!ogC)Hs)cqh$eV(sr@3oy2Lrn?zJW6`@=A?yPM*-@+vg;@VAw%Q@xz+$_ayS<(UzQcpfL`$bz+Gzops@)>z;MvU1$6&MIZ~MIPZHqt6ParmtRsjpjdr)KFCt{ z&^5$1Yko2G`9B)lQIWqIThvrwou&e$2-06yFDK>1o;9|g`Fa7w*4_T4rXwIl(0oI2 z1xOM2YF``YmtHLxE3E#H6oHuo@!#$kAVqNJpt$)jjjg{hdHsfrfF)l&74!e;beLDtbHH3{+OTe@vip%_Lb&}n3d+){~ z1UK+EJT_|ueZ1Lu6NdJoz;6Nyz3-EFKom%CqoP3)A(zG@z(JT0@#YTBcwwg3hJ4&b z_u3Cd-me1}MKae{;RS_SeO5eHfWM!PAcY2?vHdGW2wRi8l*c2Qkb~hUk<#wa!*9Pi z4RjX_!$R*&qLkbYifRwTX5IkN*aWc2k)WH(Z6q^P_OPoCWm(u{gZJnV5$-;w!8VEa zuqK~{8MFPcpX=;lhn$7~(;e$Q9NLL+B9Zfk?God=I*WV?jv`0=Yq1p|l9UU?h8B`z zF;56bHH`&Ji}XvVpU1EyN7HifSbz504La z-@ADm>2I);V2A!e?YqiEH7K~0+&nhjNG3v|b{4>J&6NC%sKqZEM3V0jhsWxyHT#~^Hr_|(;qTQWPfXPL9mxBg+4 zE723e67pxDeEIHYt`P2aauhQ|T&7*V)bc(M>7HrU#n`D7K3->G6hO1m2@qeQWJL(x z)yi^7?OUOP%pxi9hU4xOci+tA)9|W$&79F4Kdu_Q@G+(^iY=` z9PZ4+UKt+G)I!0?f1G;q`=*WQZe0+LFy(#~=_?Q(D?25$CL!EBrx3|d75 zKOP!?ZCqHUTdOrw?IetVy1w}=eGOSmji%uL;42zN*;0IS!l*qSrp>g`{`=-M=qoRs z?cv7T!t>r@s>;n!US~BjP=dz519RlV=7{Ulg>`b}ZXvG=m+tLl0sdewT^TCd9c2??aM~+LXc+aHWP!Df!?hii_JvF@(X_VdDNXa`y#{%e%Rs28!Aj{e+ z6q_2JRT`gl8s4sPs6Eh8>(qgrIklX|v0^b++nBTr>Q=q(vAPTJJrcHx{p33(%nwUz z&Cv$Wp!!^w5>N6QDu*E&`&`_uE|;WEzlMXG2tc(z$$Ebh)oEzbeLbixOaOyNlB zY7$Io_WNs&*5K0i22j7YWk|HO;S99n#N|oEo%>_!NGH4iZ?{4XBO+!e>S!m<(!+!5K&-26YZOsv&t!A%;5+ zuWH}m8S2_xhgcgq0yp)6UE-96dQ{uu^_&t7NKP$I5|lztDQsaMM8g8|o%)i(GUI;a zzIHCSbmCKnI>+r$Pt@yAane**J7?4Z*Y#34*WtN!w1pfI`LixVQwC+%F5mH7XGC0& z>t$*K4I4Njt1Dfbc3f`=n1E7P2M2R^piv)w)N+>FV6U6Ys@o{OI||qPNip|n6&6Ha z_wZWxg;{qa7(j~fVV%Q+R>6bG*5gC02VJ)ZRpH0uYY%Z8&vP+PCge|7j-EG&?01NY z4;+e6$5=6HFYb9ogt=IFIxbavFBD^Q0GS3fw!<{uBZl6%1>UlIadQF4q^c0LjD4+5oMeg>%tyb}4Ts;Z$;pF~#o6YaGP;grSzb$~8sfOthf zm%k8WegNAwh*lqO95>J&U~ECj9zl45*IL|NwhFrVi}u3aoOZrJ1pdZBfdquX1wo;6 zgyG^ukp#hIg26o|!AZuVI3;~r^ItlDW)Gj3OE0$zUr3@(QK6B{ z(_ePVSVoFKA&SToi@+$7-rkko<)q&impQzlKS|0gz>YK$jU+RTv`mP+t&bd@fJQ#u zL|#!v!Ae9SI7cB78lyHuq2Ip8M2^O!j>i5H9c>s*2#O}AN7&qnrh|*2ppRi!h@p0l z`2y$30Ad5A2(lM38aT1vKgJp=#G3oYs!MY4%;$P;#Ok2r0ax7`U*h6@;{c5dG~V{kn=&b1joy-?EyZI%1#{KX7gzN{RMm*y*R&t~YCFODHX&lb zDn1?~O5GPOQSI~;#_cvAKsr+v3K4W+>E!?-I*I&R0GC!HVm>LX!JjnWKkl|jOBM9P z7-X~?05$>j#s?VQ1Y{xGTJILO6(x6YmvGeuR@^2R_a}R(g4gZAfzidu}ugj3os|E4> zhP3@#@uT@)$Mj)m$UoSz%dgbR;RnNbCYWBukPsH5X%5$Eq;g$kxONEN9O8g<|R^=1x?nCc-D|!)`U+MeNk3lZx#Z8JriY* zb7Z3^Wxud>=S2C&jbg&PkiB}HEy$1~g7Q(+B}aU~Ly|~=em+MQC6}2#m-kEVXM^>aOX4_m)i_h`I+KCC(VnIt3bkNReiuheb8O~Y_@86k#AfhA8$SXsX(HWNg;R;18QBLK@7>_fi&pA z(qUm&_(Q%q6-9v{DoI7T450GGqH5w|Dq6vs5KzM)$mk}3I;WU55SNY?&(aAmSE2-v zBCzV0IR3<|l)zi;E?L_u5m5{pPZpU}C!97dokbyV0S{o#Oy+97YwYLLlP!uOd*7O&yVF-g(%efK)2*@7tyGDk!C)(xe(4e%O_vJ{=*fm6M8L-LjJewPH9Cy!dK!ub8nwoYJtXC|)=iv0?rOUn z%ngaS?7+QZCUpfDdCrY>UMb!rNfs)EDk}l;R7kub(kQEvkO(HMAqDh{ZOcO%jCV-| zpTvEm%^H?sts?jNQp_-7T`)6;8rb9zB2xy6ng+mgFgE3ouXI0ubwltG8-EQJF$wzD zpcXfkfDD{KElrKBe+0Yz16UISns{vAir5Y;LWf2k@MPPY23$%;4s6FzwI}X{r!)x0 zT$*E}n?V)L>Eq2SjP|RIL_h*gEm8EPPCaRP3lJV_9d9|)7`<{E-Tu&ezE)Ne^yYVP z>tjVL>~QN-Xd0aPuf1TsmxsU59@E5-O!H*=(`V`8%-1-6rgsdGi7v%#oy$FH+FzjL6Y6Ud4! zz;^ZKR}G1Ey)ft+3+$3$ss@^3kyl->ak}N*Oo->J$%4DzWp`@~b!TmNe-EpXeA~m+ zUt_TJ$;ge}WQpBOy4EtR_9yRb$YgC-0#r$uu+F7v7OSs!ETC=@ug}NbqCvRNT`J$n zrO%tE-mwM+xR8$0LeuN7_c7p0a+?S7Vm{^Z#V#h;-p(hZ`lU)?aInBdyFYtXpC>0UC|l<@qa@L~$V%)zi6%*Yzk$foAVnf>!_dtEbP^cp_U4EB6!vw`e_&{= zO$LQ0a#ZM0X1sKnAbXNxAcd|o^Q|*T)3c;@u%a8Xg~PLx0_I=_?r>LL3t4_rBY`6( zAwGB!ttrt`Bk@NgNpv}BEo0f{_W)r2ihdeZc>1-$v`XnWMG|>sw{A@tcjQr`dJ6KzC*4$&(671znx??mjYnNv3anvirHRrOz{jHE^ zAz{v%S|w;`&cR;=Gh-nr4b_{7Z%iTKRJ1?I9W$^y0i5ES?zRU}PdYQJu6#SFVuf9u0wE9ugZn_zeIL90vCz|m40*`Xc< zzO^^L3&pS=#qzW?bXYA~cs6`_etCH1a9NyuWJ7x7H)_ka#rMtPlngM;G3oIp%I{09 z!bFA*)sLe{t>GP~ zDnWSzMz^F7AKhY`b%$Bdsaj5x~v zx)9Qg_(qI`nyLgb-V4hbe@QczB$<}v|0b>dVflJ99`89frs=-*HEK(}WlO6p<~zTq zZrY4KznNjgwnovm*~+$Rq?Z!4xl6dY{nH-_32zIOIpdlg!>@CTGj*PfyP?eW{+25K zX)i>?_oMira6v9WCG&?pwn9St;N~WS; z-LI!(aW;r zN3&8#Gam43=-;=cR~9{1G~-gV?GQ5oP+H_&kW z(Fr0dS0*vi2|FaZfdS=>qeqr8ad1VD@?U}LN6!?d+J^TVl5iZWO z0FCX9!@cx#cnt38hrnOP_Enl%pS5me;NS4r&#a_Sf)6wEySV^j`=&7H8L{o7eMW49 z&jbI_*wV)aJxdW*hJ^J)N7Ds-WeFtz>5gHic2*ZETB%;)adTd6eZ=fO7Vy^2W_ zp%8RuG=(p8McUy@^)opYNWa@HgI`a46zB zp71m`-+k`3dRKkljL8K!{dae4cP;QA#8$6f0Qp@`QWgvYq%A9yxsvW}*!x=JjnGf) z_3IHVR|P*J+0Hq$BR(QX zy99B{>h!OZ42$;ik|@`nr3m|bxPKSh9HPu;DFUR3u)GJw4Erx*TYaAKuN0xxl;W_Q z&|w&Gjd?qL886XQ|!e@PK28DZY61~4AiZzh->H|*vWA4C3GYyPjOb?j z8L?e&6l{Us75B8h#5A{VM|x9Y-GTO|sr{e9_O*)nSvP@ENktEZ$kK=IH-Qi3eQ&G; zD*N9GyV>+IWiOo%zUxK17@}z%Iv@TtOVTmIv$J$D3gtz74v*nmT#k#=J}T-x}MxWjo%e>lK%4fU)&J z#JE}YnbiH?@Yv0IpolgSMXZ!%!`mdIG$iU2srCMyjKDGp`kX`z0mg#-6%^)@x+j$P z<-IMTEY)znLq|Ql+4si-nj7~gGv-yp99`fa4`*xj*$?MOV;c{=w<4aS{0>O^kAI}8 zavrbXKTXMfSq=R9O?1;r5m9{CRe$1+s$#Q6lCAqaRGND_9p|gy7G|9M!}YHz1(+0J zB?Qj+QUWdes2#?VcB(|vnR)irP9IR}D4m;})#Ap;hScL&8!l@sf z9h$L7r_fm3wtpUljD?|iC(**`rv~H*OY6?g>4zRp?w46u{;?^PL}#2bEbUd#j4k&o z_2cNTuV-V^Fr|O;UlvB<5m$Ggv-RShMRs3rSYBd{)uM^mDN!1cE zh7+;!`S&!tSxbLf=_2NV-bWSm2C|I;0_!hQ|5lb{tmi%C@1i(?6NhSEt8 z;>agR(&Q%;(tqQ^Q7j0_E7bfltlTfDTtARk>eW4L32Ua>wXa->1|!Z-Bk)&>FxxL{ z={~6aFJtSnaFKRHqSAWRKN@gUtP7)+Bmf7g_$x(_Dd=UQsSJxRF`$c88z7gg3IRN{ zocEwnuY~ak_M>ca^yluFe45r#j)D~ZOu2GRwf}IgiSOS0Q~-N%DY^xl1+nag@?^@& zQN93rk=%)BeHO}bfhhC-#`9pyI&Bj#ETWiM)KJ8lWvhw{bjR+HC!IgNEjE3C{9)X*{i(LfJ@XCdT`>GkG}2>=j_CXcyR@3+JWBIAWg)Q{V5ll^R_-IM?51F z?&?)Ni+=xhTk8AWoY?%enuAADYWgF))XRsxubxk+rN(eKuVIs~ybAbyU{&q`jco$+ zYe0&?SO7>7u4*X`Gmz}TNy`x|{%z=G))Ms{>j4M>eSE{{iGxeqJv4!B#idIan5Z`-tFm`|`jI>Q&h=vOJ3@YWNUkg_@0=Qw@pE`=oBjJi z>TOt6%3mo$L)yboRSOCYOCb8?=u7zO&exK=Lc~OwnDA-?lB~8E< zuZ_7E3r76%Od=940mRmRB8#0(9;}#4cSKb5eZUlyJUq=uN-XOtd5|(c}x0bnMKMqVKOZTS?0XRLX2N zYESDwgf*b0N?jx`@oCbTAXGmSu~y zJHzW(vEOvG#5e9zn50D~k74B@q9gg~7RA1sd?Cxto@4_PruDI|%igR4v$74Wqm`lG&UzAL8;MCj! zjBRAH%k*ihx}?U!{$1zYli5Y#oc1tO>mE3@;pAw$GJDDC)#c!Ygv8aS%%%8AX;4{d zxQAy@tA!e zUl(zwt``4n;L4xC&xk<-XE4nwK}Odwve()NH9^-EcHgdpZeD%A%(ah8vQH4#Q9{%? z?B?!sl3_&)8web=Utah|kakMmYEK!wsn@^DfxL!>2F?K(^;0a>e6TH~C%+cw%P@T9i3%Fj1Bfq|hP1W(%j`tR6@HW`; zCPVV+AoqDI?$c!JL!0Eo*yqC>q{4#a%PNiuB;%%Sedl6*gKB*FcYOuu5MVg`NWVP~ z?Tndzl6`*M?bcs+apYAKg$4cPbo~{*{WUWEb;td^KzKTwNp>Fs0ziUBP62N1g5*<4 z7B@*zYJ^qHk1BylAW(^SAkU`oY)zocZlIu;NH%g%%Qvxuq-3v4*xpQSnK~$0 z*xVNts^F-kH^(*h3W4C8?(a=%!3dRLi%WZ}YI20UUs>P{gv3>>!8~4l5FyJF|@=^2R9> z=#CNXzq_lC9PN#Sxs4nbivkc^H0lq*hH_Z`QBgD|n73J2dmlkG(TNGsfE0l!n2n5( ztQPP3%&*v*>+Gv5ZI6KWK9ox>`D+3-g-0l1j>r*rk#VTuHo;dB6FU zk|+ztB#V`&DpL6au$?bBRv~kJV?oI#RRVO-YyzR#A{y1w7t!avpDyroq#1K+40CAJ zau`9L(&{x*cR8vWUJ8(!NQK-$>)hzrTu@bR+D5J+YF_T!JOc5&vLAU10eQ9AdEIS! zjT?DZrj`oy`F+Cq_NMuNyz;d&@?D9r+z0qPQ3}GT3xt9awB-tpYzye43ql|TJmUos zD234>iE-+M2`;!v5CJfxFpV2Rf>o4{-KhUB#KR=6Bgu75Bac~U$xBP!AG3UM%0C4QZ1s{ z#juqvH7Nf%`IGcvwXAebDSOS=&=@Kc1)FSWj54^p2_aVv)m-zwJ8Yvyp1Mb`I9Fc- z+3+COSc=G z`}uPFMetxp5jVtu)#5Z7BJOaKi2Y+A4f5j+nr97quOP{ikTe%ao~DgcyC5~9P##KS z*^o^ou$SKp)oBc}z0~6KvxN*b^2|2Q8;GUkDn1h%0~CVtu4EeDo4_Y?xZSIgSliA_(m#KzqJg?N37;kS8C=mLBkP z9ssZz*UW*i`GH?43+=ejK^Bg|0fWJEKH&y%W1|$wOm1-t>QI|ma_7?cI$9--0NkMF zmnsn1z@lAuY0w~KsjeZo;TAmG^!?!vcpTjPsuHm^b$OwAc@d>-EVyjGL3|fHvRBmN zhSR;K+4ndH3iWg%_!gWgWF#9X-rif*?40`uBzG=x8Go|HC zkJxFsmg(TJ>F>)>B;9cMAIrH0GAKsO$|f?XX70)sr7x|}XMdur*z&135$8K%xCn)gOt$mCnd z<1I4bv}vA(6s7K2ii2YJ7OF`WGg?3mOQ0%Jk_@%Q`p3cChT`AdT5PL}OOF{et7HSx zUk2O{zTyuLYkc1wUm8Iv9oK4Z2L&&Lkx^LdRHPjav>XN)hwNF5;P>cm@*Q~~h8FFP z%#BE#n1!CB{AQbR(zKy|bouoNNxMAy^_Y76WFdt-=nO-)niaSjnzbrBHiq%IDo#F* zBQs7|(vFV-H6%-kSUp&K`Mr`{b{#4Gl-_LJ6~P@ddmZa!9s8>>LU7inWjQqGGalCs zlHVrpVmI*iCb?ENs3N2J7&eR8H-Seu1=r0x+HU67P1di9%14{Na9gU)(~8H_N>50- zsayKZTX|z!MHgFDSlg8!w+%eDjnlSgLpIy0r8?&Gfyf zn+sb8ROD)YmJM<4yP5I3;KtpQ<@tye|0w>Xn0E^$8Vm6edz3kQZs~+2M@2RS`#w-j zu0)`hH`s#KR6^F|bF)8GmeQ_u&k~r}ml&U% zkOE3gPs_xN$w<%6O3W!N&M(dW1wgh{|8~b3>+CRF+FCo>yE=Qi`+Du32ixcF*yOm7 z-OSwV!o1MZ;_tcTzk{vn^I*HHc6{+^WVj`KZalapYT|MvED#fVSb(r7|8|*k5$orCI3fbOE*sW zEJaAJ4h6zvnZP)nQ#1`Mw%P`5HP4G}dm5pXgL&jX8e50bq&n-h8PGv)*>a;};qJ2( zVTINU4wVe;CUC7Y2!~O-Bq`{5vHd&(jKaWT`|<1CP(#%Yps}@06NXfqOuUi@x?|jb zqGtibHh?*|_Gq!*Okr;LAH)_FI-L1G-7)9b{~Bzwg$r7=?yio1rw2lz7@7aEBD6FE zjO}j~`p<8K9`7%Y4$?0(0`-|GyjX&&TYW5>7NP)3uCBdMTt;4!^Mc>&2Pra zvhQui$tg>0#Vex(Zy|n>bv8&;59rTL`jLPPM8_mS+i@IdYa3we9{QcX-Lbz?gufbF zK#Fj;4oifz>XR8nw%?Hz#%fxS70SV26GER0vM~j^V*!vtn5>wP!or{g z7vrM*vVDfaf}T4lLrMNXvPntddUA1Dm0ohWlPZQs&;*K1~I?QhSjRE|{-OtSj5AgidG^$?DTo7E^rvIg=P6_22;*pL5VYy$-*`ranT zMfC51Gvq_|i+)*#(54h%4<1%t=-nUH@09T{^l;y4d{;HnB?$_lGmJ!OPuz;pOCr)U@z&9 z%Q>xIAFk75zrmpCd`l8)%N5!3`U(mmtp)~LRthGpFddZv`Gi_vur&`3Mc9!?Y;qcV z=YdS|9Z6WIon_mPPBTnjnSgLWf7?IlRXCavUGn6dHAZRwnyF!@@cia>U>#uuRv=Vd zZrqe^BI z%>v;uY-1s7yD?&F5ityd0%4~IxnKb{O8(=sNUxXU(drpl2|#!(NP08GOFxIse@{Y9 zPd=`!I!DydL@M$11bRzc|0m}?=?tn^IzDD3&s)R&{Luva=sH-yQ&W zLkxcfP|N<5J^0UHt1l6%wsxn?)BfeFS+t}UfY>&yc7KIBjvu7oq0qI!h{|~q9%j7! zkp%pGeF#!J%zS;3BtpAi5fyB1M19c4Y<9~U=5qOWv9+4{SOmJvp_3_;R2i5^fUp^B zgceFS_S95sp<8e&fn{x7>i%kM(Ti3#YdM4OfbpzAVQ6t4kFvWX4``k0}e@aSyNsm;&@u(gCl_DJbAT~iJl$?47i?u@&n_8~o zoySlQIrGF+4+*czuUFIbE?%_suqU`hSs>lfxVHRJn{iKyPdEIg*E%wT>B&0&TjoJ* zAsy+o`UO*lX{eXLONKG;^5u}1M)$ZVF;IBl`tA&bjgEFq4>`X!=1gk^@uk<5r}ZM% z6ll8Qo!i{k0r|jU>ngtd7Um4{WvI*{IJ@iE#W7e84ba%ScGK&PH?4750g17dD~L*{ zZkUzFkoa$C{aFhT9`jl!Ab-*eig+yDAVns{H%4=U!x#A+7N@YpI&=o_*%BO83LkpwSMC2;jO$moKqz!%R_ z1ZhL#=1JAFu$ijLno>3e)M04*M1IQT^e8tpRvUKMR`5D(jQ{=RsHpL7C%L3?2+_hA z9{hYCZ_zkuT}k%a@ah~|nZ2a=%iN@q>O79&J=tH1c^MdBnckks)MUuicbuXkm0{Bi zyc&S1{v&TBQ{UOYP*@+ppjfItT_`ky)zV_B5-4-1XQX78dAd(77dT@G{xhEwbfuoZ zth~_wXJO9cK|&3kCHRl&5rF&-yZPl>x)Es(i^QITq!Av>+92xqpS9l>2prmiD!9JKsBq49ei zzMk^6C32{g4KAgl|9}>>%rIr}oJgpSZDLy2-qlHq-12&R;jwI_RSJ+IX!30T!5EvC zy8P2}y(|71;?~Rg`y)4L_+2<;D!=7B7Xm>W9_6WbUCSyzt7;Sqo<4%Q4y+ik*fO#T zMscU)P$;o>T0_gJ1(_Tnf%UNr{6ANeh8&yIv1N)y8dnj&-gFQ@o${~?B0D&5>Y`Nj zMRL$YzdfPXXC)kv>S_99VQ)Y$HmUq=`#hm}Y0GB4D7lxYxl-}_UnxR)Bwq{HThU+`y^j9dm{wUmfejdA-iQmUX-VVNIkP*!M82_ zV9Tp$``ORdnp1>_BT(Yf)?wFn`J1-0xSfltodjU9-Tfj(`~8nnkRl*OP$hqY*9p7% zu5JVsQ&Z82*|n!Vw->{9a20_wpmk3{k}{>0VCkW)XSct z_M8nVztMY_N6jIJkeU<<`J1k4xuIlV{n66p^o3o&hfccJ4q%&{2l~RkUP%|^JA*k4 z78Ds}0}S#KU2+^Rg*j+zHxzp}!zj0bUN;!fhu}Q;(YlZ0*P(nu?sIifX!B9La30SZTdwHe93B}6?3-c= zyLHj~JD-lPqsa*sf8lvvig{Mkm_ZUe8Riw6W@3^QknU-{fbLl54Dx^>az71}o4dh_ zcizji8^s(qZU)aAPc=@|*_$XSjsOXbbS|z3$7cX8evQS4O4aAU%STlWlc7MBc`p7v zf!edWw&2yX7lH0GPrWbSjjsTKU(Odl5o14TZ$MouAhjzXBd+n4&R<^KUvKQEiYmTZ zfxiYPf%dMy4jmyqM?ivZKtuzfaS)MdACWmHv1JnR&m>U0U|>o=iQ^6EYjvQjIH|n; zmpsBC0I@y#5OjNHSB7jKOaQKQCJ*JLP^Hz0?z4AR4Aw#v2S!0)DFFvXb(zqbaya4z zq*z}&m^+4y1cxYBQdiIERTj|v;*>1V*Yj3MS^CFfi%f?a1%++WcaDH{-sRHo3rZWT zPaEEKp0+bMBQzMlk;yO$pX@WxQg+Fh4IhCuY-0ta2mm?7bbw^E9usk@pK-kzVT%xX zN*Q?}9(k)5c^wo9pB;(T8Tn-V;l*txoLUsOZPXgqTa>*hy5y|4x$dv$v)rpT#a7kdyieH+NgP>sD^?NW zRhpqZosf&;6sNh6D|wqMwHK%7!n=*&W5D2}Xo3NZv}*Htr{(cWlkvP=7h#g`Jifn4QlOem z@Vt;-UlMTSZAbv(WCQUif+~K3>N7z_3&g4OMSU-l%el3))V}N}*?r4Nu1_wOt}E8R zOg3Tzw}pJKl6SazMKxtS=PnWRMD-k?NL+K-Kk5YthPU56z2cWSvGe-x;xId(v_1c9 zBj1zT+MK@NNw~n@v_QtYKr5plG#NLXK`;`fuz?y-R3vH36~47A^o}kB;OE%!!Zehk zOd=4Vs>r(|Dj*Umh7^@S8cDEbYzPqm+#IFi-Xk`aiv1xYFRaJckcXBs% zCgD{J6|-{?b>-Jqi=f4nZ)a2PRm;12ep%?c$*+++^wi?%RxB~+ps&r1?H-zm<)i1p zB(V4%Ry%W5t1s;>MPIk9TxYt3=DgVBqJiNC#sIciuSHBBMk_xa{s1$pAlFwRjrC!! z*b%7KUh38{i=X4b)(NiA1|Vn%X4FU}#!E+qK)(3Ly7=cc;{P>JXqGGjTPYt5}=*FUf#Qn3n7K?{8L`Uxj&Gf+$oI2r2;3y~X zfQ!zMY48w}1K}#n&0wmqT!?L8sc06}f@H{k<1q78=?+TkZ#2n0l+Z(>;cd5(-INjU z7^$usshhiz6Oc3<$><=J!MSt#lxjLMWBY_^`&Gl}17QX(Z#jYH7y>#Y9wXCMLHoHM zGm=Y0O@0OXe*4YK4hp8ox6&QdBrLRH9rPr|j6)sx8y)Wt-B=kr*;6JMELb^*I^R7` zup9wauTKPOP!D0i*c`6#rD^hbCtH}PMu>q^lD9@ybLyM@lqzcMH_dM8TuQIP`os?;VrDu z>0aWqUInZ^p!Sxk)R$%7_Ym7xP}3*w-2f`~iwwh!MiY#c?#H8okcvQZ!TpNm{r=(RvUcN=U98W%vHrWDsnFor18}E1RSzlbep4s~R>*7^^;C&OKYa*ZZOat1o*t{-1Yy}0#PPJ) zQAh}iSQ59i&bP9uwZbM(*Ml?)EneA|kiKZrzjX^wr47FbAH{NG#7Qw&pc}jE|Bd+g z8^%Kxm3jQ7>?#`R^NMI^I4(=xLD)P_vONAKoP~*Tf=X)wk2;I%W7QdVC*$K9-NM8N zzI7_?bvKsD&tcI*P3xZqCf_}I6tU+BqECrxZTRZcd^U>HEZj3xC1H+>>R@~WMyeoYq{lEmn>izP^oS~mgl)>wloib#dgSY%z1O_m4=q3c=7lT0iBkF~RGh^k@3Ee_p? zNGc&nizuA}A`JpkQi32L-3%$+okMqb$I#6X(%oGWf|SCXJ@~wJ&e!u7=F6Ua?RBqp zLV3MT@bVkr|0R0A@!E3ZUD$>Ow3erJQt<8+zLQgE5TmG5_s&vHHf{6cQk~Y#Cff?O z3F}t32z<*yYud78YdvGyY-vm5dh0jAb_CaUwCeV@-S*ekZS&>rmuoY>AMNCE?I5Y_ z_=oKTwd}ZAYI*1mP&f@xO3uYu%=uet2Oc%0w(Jg1?N?AM z9NE*@+yhfl)&3~<*Vy+c56nLbysO>sU)+xcU(IPP_PPfd&Kw5KfS}8z>jF#t(yh~i z!HX%^37o0hO-{R}hubm-;csqoKHaPoJ_xU0-hbhIl@vOq@cmLS9Zv3Yv)KOKcV&4N z_$gV7`YIO0J9a4lbVjV={}>&tdT~<52G}G>Q^yn)k1st?AK{IA(~r{*A3xeU7N~xG zK>3}9?a%gXWXD}i^-n)n;AaicVUH@k5??dsQxg z*nR>fN>}Frh^-az9MBzmpQhuD^^|`y9Iixvud!8O^2t{O!ejiuLZ^z=Tuqi>h{aa7 zC-A92UHHeBCKE-fvbhMxc0o8%w!Uns@y*Y_8rxQJ5H_WphBeSXBV^GX0(<|%*j}He z0E_LX@OH#vn-UR7Dc^K%!h}FLWta_;; z1?qXDGWTcr5C|8n`V!Jh>7$Wq7U=tvI_~N}!o8wd52S;~o2&;h<`t~}*J8`YErRUN zV|W6f6Z^CJ5yBS@*^#7pdmB*_^kkdSGTZ~eVvEPOi7TyKXb`Q87PJ+o?XkKQuj`n& zm7u@OjvQu^_cuKD4`XXT{dMQ>Vr!bD=!4CMfn<{5i6yg}=})h@n-xgNyqg{V8mllX zR)W7U7ovN!o0G&3`$-MFn}VqT-6AoBfjHGAy&=y6ykzjv=H7 zWvG9W4lAMb8O7D#B^Fp}>XefY9?TjQ|EODZ3@LqdkJzq;>mN1lh-D%W+hR7t6F7pg zJ<I}hpy4xqhQ!E`Ao^6`GK?|GGa8U0bR#Ub)#KPN8&=8$UiQJykA5GwNYc7- zOc254xceFKhk1saVn)tJB|qT_PO9T03C|iwe1Eg(RQ_FbH2{c=ZNB6jyMFjJ=kDfl z5TLQ80kCVC^FBlPE$dbe{Eqi_v+cb&W`<(u=YTxY6HmE}U=Rt$;}ShoV6k0Q?-vuT zp45LqDkrPWeH9M{SFnA<%*41=h7b~NvxiEreP-_JBvzB)U{66dG1?`Yn62O}8OSs> z@9LtwVdrkg%pwTrr`RS%bjLnF%KMPI!#Tz;8@le$|F(x&^E6mvXvAf{tLInyPROZq z#JAqRQiKPuBgubMXJEYA6}1i>^`qwO!?h_0r-T^<6t%`*q832XF6-<9dQ!#dcK+-Vfq@S?`a=Fav13-AJ zN}gO%CEJK;P?HT7ALgyXW|df|n*>vC`x9I2DP1Ht5UkQM`Iuexd9h~geqvpxDre$f zjqU7E9``rY(l4qZ>eETn6`hGJW>FJbyK=^L{XGgcnFpyy!3@ydcki9|4$`hb5MlT` zc5kM`bc`5?2s(3R@W-JqzuyjM;kOn%+_ZHAz_YZE!dd+47 zL4?Nu#+Ki~E)#j_S)L4LVUnf2MvEz3vA0rcsggb9v)&=7C1B z$DCI0SeV{8Cu@vU#n*?H7(`7Z&(awecH@kw7M=|)ndT?01hF|cHKtkj=BHdr8`GZK z=^+hsh+Z}u`zRlN#^dq|6?Fs!k>894hVLQ~0gZ6`)iD%aubk&Ec1aT3QTW(J3Ajsf z9(y7XTZF~dG$ZPKk{xUT2Km; zne2NEoqc~VMVKtG4KIrDtgES(u_!gFEiOkcW~zCLRpat|VRgA%vu|m-uJ_mCE}n!= zwtlnY#;>Kp36`@zGFEM97t6lGmlt@0Ry{YaZlTZ94aP|3ytO>5Fe1{wjCsz*nP04> zg@NH>2W?|$6*c)nrKUW0MAJrFwbb~s<~^^q=F58Oo^<~}cN(-Mys7hT$F(#FlszLM zC*kPNU9+{C)qW~*xieZ?HdJEM3Rz~?)CoNqZkqny zK>cU-^59pl72M-m_5#ahx6KZx!VfK_kGUpe+$Y?XT7J}<_Dg%Gpf|g3nE0B6!d|EQ z_li|6K`?vbRZQTUSBzhgoEio0P9r0lHvz_$_XRboPv=$`Pr0nt`cGvcysA9$bh*#u z&i(l$Rj(t426~Ct)tpV@^QoMaalEg2t!h z;5EJt=Tla-cw%Bv(4{)BhN)X?v8LutPb#n(@4dCHwm0p)Q)fAWO_)J zHhDcZ6gxJ?1h$_W9@9$N8tdDdd)eA#+EPy1S{9JJM7Im1vExv;bHpIy39#csCl@e& zE0pk7gd|Xi)83a?T+%5}0{!ViZlGL!pgf5~Bx#Tar^9ZoZhV6S1QK-oj#`hz@e)-s zz2Q@qlqB5G(abp5JYQ0^0)1g7*xVbLFPaw6)>dPHMaHFs38nFSoqT6Pe0ZcO;=w^Y z@Xz!Tp)`7WWsp!OD(8hWAAMLH$VHIYWtLQ~H7BgIJFK7c%L=c2+D~RVZu!D` zmJdeZl15(|X2Jo+wijeH^jQHa>DsEU0HSv5lyvJcb~EsF8_0J%?{vG|bh|-uH==f* zPR)3R3>C zRj;SKaapVUi^SdrT;6kz-r93fAu)dPN4I|-^TC)G@AL# z#ONl_=#LZ|AVol$V*?0jl*E^4nCuvZkysOvoHvogbFa}d(pjUC$mX(zlU}XQJa7^L zy^8k`vsPkE%mEhL?7Zk-`J5N^oG-l-#OoS{} zJV*uTj+yd%DJJr%aamZ%#7%8`E!C-hs*PLRj&o_s*T;<4laBW!7c}{(Kx;AO=amsZ1aoL-;E&Ng#?+5MaM041gfzKt#Q4!oG?`Bx*)6 zCDKSH#yck_Vv-~eB&N>UraOz-F(zeyOmYGzy^e(^an&T{j3pI6Nbbj?sBSEQ>L-sR z=`>u6FHPCYqNGf_l&U0@>Z+vZ`=%@hr(D-c43nj1@_rg``~>z5o@xZV2$C-dp7A%i zhXlozuYGl*$_Uv5>gg)Ag02~P{rte=Qy??p?@)dLTgLm0DU$gPKkO*X-z2UE2$wv~K2S*r# z6bMjc+jH(O@i`Tkm9-|6RrqsD{BupA@H%G$Gw#9|Yl=KQ{yclxyiUhFJQH*0kUX>b zdXIxxVvKyn=lRMX8>mh49h&&nnbch88k3epY= zrjQGT7z>x*7Q&4Rw|xo;G7As73R9b`y)lcfXp6FCibV8_bUcd+VMN6+kx~GnKrJ=~ zC+e~nKUFEVwFq#L$xu_vlarEV=#$1qo%Q0tW=!2# zm)2;;6cytj^~=&D>`ySVPga~|DU6O60>M|%vVE7}!zRZcMZrwOwKhB`cxZG&uhV`f zN!2#AKguiL!K@${qI-%KnrH~G02W(*TY6A)2f%q!mZZ~Dqu)t~k!pnzv$&AUx==w4 zCE_!RNWzD@I~jgwpsSJa@9JKXnlsLtQ)NU2 z?oV`$43u3?%U$8OqQ*jnpG2+pp`wx=(le2q!9WjD_Go?AUK6)o1KB#oB2yFBI;NgF zTUJ0H^1)`I&T%ML@QbJLTwni1pKEgcH-Ua%oCZsNRrx}%pcF4(f&8bt{IrbTr7`*W zB5L8T0~G{~Nkam$3j=MQjW8rwQb<7xHeT9bL58eQR7RpRY5TUP`)ZDepnV_ zoi=Y><@%|oR|fm{9uNb53K&#tXrZ~eh;-B}pq;-Z zRjDQ4rlmBhr61NZbknj~V&ByvE`$DVGPw2diNij$^ziq)V}b8RL~XZYL6;$)E?moO zW6N%#lJGxm$lRche>%zyL9~$}sDJc47}9p;oR9=M9+v1UDUT_G=pSo`{u}_KEsas$ zj#2*rle06z`D7usouGMVCUckG$?@#V&KIFw+=5lCI8}T7;g4N1nOrA`VO_#4UBZG9 z+`qfN&`;(nckkPGui0kFG_wIl1cm08K>Tf#rw9E*kD8l1!8;_-qPxzYDWDsSu(I2Dpai7zgN#j{z_EfcKjYaIY~tMx5^# z)*t4^AAzG5qBWp(Jqvj`S6N72L1_ivJjZnX?W}==F5g<24K-Wwn-rTb=q;fI@emLC3 zHSF~;Da(17D`9y4$%94nmSt8{fNfqEOy2slBy0R+w>kM>ab#Oa7buRM4(XmRF8^Zv zw9em_c9pV~)Mmt!`oJ+2lp3r`fJU<aco#Pi(L4tlnKt13Bji< z3KtXH9vi%O@^6Ra#c|!Fe!P&;VFSd$iYJr52m$5Ml#08tntYGOlCkEkB0F`vAl9_n z@+&o#-qR)|J_3+b(zG7sHg)Z^xptkk`?g)`c7?)5utn)P*=yXu8Y-yZ%C|-$Irjv~zI*^L#;d&E{`(tZxZE1iM86 zBorgKOZJRQoRUlPZc9UPOAENkOFx!Y;^ z0v1~Uu{E)ErdFt=p){mx9p`di7w^r$N?KQ>ckP{=cojOqcXvwtUS8CK<)v)()1qpA z%I@{^ja{Nmh4x8t%S|cIP3f{tWx<~JBgX27ii+5k*w$MjE9go{$S9tn1X|Od)6QkA zI1SlyH8!TL-L`E?w^iPoIm*RY;nlmf{Bl^HaT=-jC75*o(Y% z?y5@f24W8cm+gk?UWOm#vtsOdCCz1N@5SrFAe8e-l=vxSLTN|%8EnE?3j28;`vq)- zRXT4e{OG=GOMk zrXV6bc65BK`SXn39grei-(1oCPk8JRGmeyA`d`FW>U0f>n1T3jcgzpl8)fxvRn9=n zKi#pvQUt_en`nBE*yfMmntEd4HrW*@Wl6?7(@C=T0T5eYu$8I(i`e3d#vP!Q>!teN z-q@FXtTJrL(;2J?uV#C92@J6!N$7qHmgX>>=56MvU-N?=`k2nc{SS z6d{xuQ6Cd$2Et0NsQZ>vS5o(9V6WeTu#=R1GHp+zzND;)bEzU>8Ia(`ScAKieLRZJoev=txg>#SA$;vvfqh&|H`*ZA?Z~Ye1)sk zK&mtVu|*HRdLG8{Y~WcePgT%Xq(QXwcC>))^>(~lD{MC>!SZIW;B6L+p%|N8_F4G^ zXyBl_n^1tUer06vsCnht&~ZB{tsqA?3+?dfs9tt6*D~iy81H%pZ42Ltij|Py+31Id z;;gejZY9vnU*279CVW$RvyxAB2I6D2nfMJLwutW7r?&T38~7@4h2M`J$0{Qk1|uOe z5|sjrErwhMC_9U|meHEk#4AH;!N9MQkrtcS7_~kUV>(B#@r&hMEwK`b_srpsVhNJ(`bv!aiGp-XJ?9(1Qw;`!lkK@OnuM}?phrpE0|OkD zdoh+pT`3Y|`GSc*6~4)QNyqDfsgV~cRTxfYGrk*yOFQhxHyp+mIP#&ZT#u`iVHp*h zyp#KQjnLQ{l|}Xp8S%$xOa|w1=1ULLn-^=%bmrBU3=CUU9we{g0O2vRGUus-l(WtR z{xgSipT@J)lhB$dlf9HzB%XM40cG<4MS?NmOCz=!8X^cW{7Z! z#iv3>GF>9Jp6%tYt5ni^a6?o)8yVW|0U0ha;u)M9+CHup#9V!kCZ!3AzxakNS8A$m zCW0=u#rlva#GHYYc)k@tY-=+tIc7zno+m!^IAzuWvf3Tuc`q5wX|Q98$+lqZ{-ZDC z?ccxE0jz~h*_CB@)z|=HdkL+i$pVK-Ew8bjHUk>lM>Ei6MzzzH<&G>jsMN|0j3M+Y z_dVGqbcOSVMAQO@onlRDm5=-?9D{O~h2*aL62%2A|jVzd<3{n9S8 zGQewd{Ojvng(RTho^JSoQCb@Ip-Cf--7z;*his7ik$!w_$rm=KAp_mu{R9!>yvPW} zp=T^-{Ze;R90@~)CTeE`is7$$D(B>x?TTT`bouf1Lt9o!XM^XO`H)}FzrRkt9x|%S ze{*^Lo?8|t!ve2BRDgRYYKqJdXV`AQ#1k2Ib8W7l;U(cyHx{9Pj!gQvP?F@Sa-mnv z=yN|#8HQBlXkClEPhB-~9K(CLbF5#!{q2q^C*MpKJ>V(7oUg-dQu33kxYTJQf!}j^CQBMtJHc}UVvZ&4bz1d5 z1RCxX%K9?kET@OTg3WAJAR!a#e6`SNA_$0Pf6*|Xi{il*6~Yh1hCq#xdwJ0dG<-~ip_pLqac`(DAd`cY3_ z*X5pC?D69tvJStuFZcfpH<7^y9UizYg`s$4d+k70tF$~jOm?z;#*o&?hq-WydyTbU^!=<8&VaK zyRAsL-^b0*^w(!nmQ}mStXt#Bt(qz$#QT*)H>^(Azbd{7LB`089Oqk8O-5RdR;0gs z7B*g~<8Q8uYMx5qHR|XEXl%(L7MTPBbsw-Mr!g0MEtW4VR=LsEf!r89 z?slHw?zG^(5!&Ij<*}O2fry4CwN*GO^7YI^X8Kf;eOvJ!_c;U%6Sh zFQb>WqLgO#mbHq8CXth$#;m3ejaKCsn`%{J?E)?RT^mDQk|!#*PksHF04c((zi*|j z^{m+NV>>SOfXr8R5F0zLNxS(ea$ypCPtw48QF~tv`|UXUK(M`R{nHS}cZ%xolzALf zd4ja;9j)`uVRDpaEz84yQ6c_PjO*{?X^?=N@X z<4?TrL^r+z8}~E3M%r^jk$#Pz@mc~yh5iJ|-$;q|7bk6u2_LOTXuQ$}iE<1#mui>t zu9HV>uSe20S6bfJJtt(YxJbso;jy`Blk5i%7(FZVR9=6Ksd0=^R^{W{^Ta4H!wTeU zuTve0H&@S%NuX7ufW*o)#uoVq$U7qj_;f{qY!M6E28-v6I1GW_Obs{)O#&GAz32xvAW_nU$R3czUVO;&2M>09T^bYI_}(Z%-bi*3sq#Y9Ab$SN zkPl-b=-oC31vbH7wLX(3QZgjEdHK_-Cw?`twQNXC2_o&=vVBbgPwM*;kP{T(0!|W4 zuoE=a0f3(}CJH~&Wd8z+AdTexE&F+|Wcl;J=Ns5KkVo28m`eDY;P@wXI5&BsX+=ao=V-ni8%K$3? zhIYoN%h0H2VHaPSCV82s!OXL}%=1z#OQadipl|@O-2i7y+K2C4vCh=U*KG=VcSu=eNj&nJ!l5L9`$|AK!axkqC$n697P#Z06Bd%r^3k> zqaovoUXY6l@zjNxOU!wup7FiK|7pHq2H}EKah$DVcG2Td8$mFAsX`$8Albki$gh1yY9UuLCZ^@hu8f8G? zFc&l^O*33b^BpsFEYWeIF&J4G;{|YF5L+)q@Gu)EtqlOM}e-h9oIWKwN0GJh=PWo(*feN*oV#j>9_r@8V{46+EMz;d2fb0rsK*v;=n zF8EGe;3HEouU8O|gco#U8Iol6^#oq~;wvbMzv(yk$1lIRk?IS9kxkp3N zw}O&cY#@EoB8E~5EVh%TPu9#zBLhn}D@%8iQJ1hJR)T}pk|Z{69Ja_McY%Wqvi!D*{ts%?z2_=~duNlEER?ZdsAH!(`<>e-^?Ulrcgekk@3 zYx+tXlmqESm3QkkN$EBHlOyI==S%CU&hN>CS#Jf65n!rs;jYKuwpgF*P=9kV zOP|;fwAuEmIZrytMXF>pq-4%@*sH%~{*Yp2VYvTQ>#AJqs($NEa_f9k>!-<9&C6C3 zqBdQgHbP~9Zicr#i*7TSDYKYq^FD90A!!F`m!q1uQ~S4TXSHL8es0I8=pyZKeBD8$ z-NE75LE2mqUDYvmRY9rEO#O%XnKlcZTO~ttC9~joQ9bKSj>`gP6-V=UrFs{$YuA2G z*K3`K_MI+K^XhJfZjzX4Nw;pP<}A)tB)Jk8pw;9+>LGvJBmdi-jy6ijC0kqD1h6`* z{OQpRRi^%$V^~s~=!iTfIjQ$_8t9JY)R~$Jc%qo(+BHuDk5(7KJlv~k!U9zjnOH}i zne>xB7wC-d;*8AK{(Pj_w8;K|lK#@w{s^1_1?qtq?SXi=0U$Ky-ZPMNFyMm z8y20V1&5^xA&E;(TNo5pXwT<8eN**B^R9Xxn+IB!I#|)7*%0!W(9ovi5ZcZ%)FV5T z)VPq4IMn_^Y=DIfwph&8r#*^O!pm7Q1x=b5Od1Ir9)Dq9-8lSqb9nhlYtumBy5PuW zC@O+&cB9%)aX567IAYa1F{k+{h1IMO?ExoJP1aKa@qzPO5ZuX2&uaL-w2_H4*)LktdT zco<4T=s;py{m8e58&;iSdVl+KgcrQy}) zrK$O)rPHO=r_1ep2&nniVHquY`9a;X%;@sb?J^ee3T|E7k>(1o?aJf$6>@HP`-2}V zu_&uL>rTj)pHV$lF-AtQ?@(}$R`DsKYJz>kByj!CY9;Z$YFL3(8 z9=c9?9R64)la+Gf<=yF5`VFe22^yJd9^G!nwhi#~hVXAt;gf0l6A(|)q;yD)#M>wy znW%+;8d9fdKWG2`H> zs#DwNq?6~7JmVsKVR($`tuw2dco7V&4c~yw5#Ax`x*0ZexF?xQeLBW@5iP?3uG3;zKXUSz#*R?3u*63 zC{S*o^363x2YD|SyLA?awHG^k86fdpG{g}F2noavL zpGLK)E3tg{V^vu1Kpqhu+bw%`hAVZbpns$*b<(QgaZDF~j3ETZvH)Y2tzuK2 zaB`oJv96)D8DJcDV3n^?ET1f0ouH7PQr~sbDx8w6$dmo;j`{f`qzFKLEQ}x`Dm*ea zEIuwyH7PkI^`F5ugDf{CKe;HWq^P{KQZ>J(x~{gNx&~luTglqnTH62Vj`iB(dfZD9 z5QFXP95C2U;nMa{b+50rZ*GunuJ6Ek4z~Ar_Kts^AD#ca*grd>I=#L^x<-A%SV1l9 zb3mB);VN^riGsgLIz_7Tp0WMA*hWyl4Mu2e5sR(k!dj;vQo@T*Fkj5G=fjB{R?~|? zG5O!qUijCOAOeks9RHxDDSo!~Zcg#PtszDs}Z+DE(8kGSa3TSL^=e(&|u1r=&{>9k-J3I#0 z`5PYl2873Me_t$ZtfZ&khsWwW5R2`q7Y6;m7F!xR(lxY4Y5-`9A`zJBN91Ud=}+m8 zv5p9jea2u^E?5g@u7f-a{(qzhS4d%R?nu2O#j`XvBiYe{a-!wf_6%bbg_*XHMV0w- z;#74LpT}vb4QwT7dN6JO9c%%_HZRd$aCAG_vKRAT-Ldh^oqtIYm>GfOm=Xf94K5%E zVcy@(43)SaY=e952ix3__WKBnEgTUZ3&v_MEXXU`FDgV^-7mghY^yc(?-yIMGTHO} zgK}W8HLs8%G6SRt!~#9{i)|IL_`SwfwiN###&+-pIS?Kzquh+wVgvov*p^{;Lr?BC zwj)~IfE1zlWvkBl!EqaWo`(Gq3W+&@*isC&citnm`00QYf$&oAUSoUOOCGXz+DA1* zQ$+$Swp9ZvIVC?~toeVs2N6<)!8eoUXZKQs5%F^bV*5JM^PJ8Gyz1UW)Ki zsBcn5UC04N!?^UFn1tqb4$3X0N)U*l$y@FIi{F~i&5rU&L z)%X{1k@OZ3y#=dFPlj_??!lDSxWI;pki zn+_RJz|Y5MYG0VJa$qXmuSJV}w^+0v$ZB=IPQY_H@u9}a#E2kFco_WdrGY4o=6Q5N z9mcjF`yuvcBNI4j@2ui$USAv|M-#H|SCJe!nCm8rKIAi`QCxM>S%elb6id82LCrx5 zaH(e?Mu4$Z^Bp0o4{SRy3=q=8$tLYXFt%d?XVM1br`c3jlMEu(M2b&#!0G67r{UnC zY)af38g!e22vV#l>fa_=Vrl)6l>84vbZh#_8VjO?fW?+UdO+scUi54JX!@{NX$6VB zm=9RbV@0H4&n={7^O~cXD{J!pN)etXoQTT`%vHtLJc(s<8j#iD-cJZ}iDf5IE&NO# zqm(RTlqZ82Y&ld)fWh{GNU^DAj2aZ^j#+S(Sh{@B7{J=8OnWzC^bwFEgvQrT4~$sC zgJiY0gN>ov((mo30LC_FruCxmrRVj;Cs6gaq@aJ_ zx+*xnZ;b*l4uHa~WflovN=PU5+Vl5C+&woz^Th?g1rRMM;wId{$6q`B>2 zp@P#qckA_ezDN(nx<6pSC9lPd2w7Z@W#-G_cd$(g0lH%{Q_|p(qVz|pYLWr>-LZ7V z)O}^qX;mWQ>PM8__Pj_tG(g6OzHZaK4H7f?WY`PYM z6U#iaDz;FhqK_0ptso&2()U!F}`xk?0LD`ojJ`W+!*C?6AyJb_S_TlY(Xy}8WGYmImjysF4AL4#W4js1;> zxzPzjvU>b;16_i7vCngdnBSbiG`OcY>qCpoT;>KB;5Z!RtVm_n-}#{|>EK?5H<#MJ-|jdvP;qNI31v(IUf6%emp^|?i&Yh*IhjQk#wp2w zJ1*m6p97&6lYZ|q9_Mm1!B(p&Cn-OnOtqF*unmOAgz7VzZl=V9ihz0FET8#TVZHy8 zvP{h>-QPDeKC3Ae3=f+=8-q&v6&&|^O|h!^wTK%dQx5?qT&sO*z8M(mcVQNm^`6)% zsMem16@vCeJ{1dZOU@t(8f}ipR7ejnzThTX{*b;{j^v_hWf?pk`lf`}A0rjeuxmEFuEDO;yU}JbaVyhFv+fJ>)S%`e*{+E+-|6MDnNxjUMN3+~-) z{I7z{a-1I5UL6DC<4{AvY?AM@Cp;sk43F9j)UpWWc(;|A`-t*rwC;YEi~o$`DR-s^ zx?>*Rw%PvDH%!TtiK+@l@#^Vc*r0cV6@7US<4@c3K4(K~a&~-kL$27(z>!QS2l=)e zn*ha|@BK3j>6d%P-$0t9-fV!y7Vfwk%ye_})S#yC$?a~;JO1pL?SkAss&Tmx`-v2V z`TUvhX*jcAXdfjuD{=IXVoIQ^=y z3r~Uu^DkTcWk?pp8Wxki*bUVdbK7c57hY6S=&sfdgi2_uiW*aIt+pL;c98Hx-r?VQ zT844q4QFedUf}aysbAMwp}ew+suhO(vJ!2;dnoGtw>t(bw!gaw%OBg6J+^to<3|*r zMegL+6z8WnX7fl~yOYcInUgIGkH4XYKdeXF?3Ip6rWk-{j{NdB6SdxHl4F*MBVnB*5FW$#*0X6 z#SC5(8?+aIyZgaeo8W#@=X^u@xB%yot5B11=Mtv29F%Z&<&_fbh{klo@Tv8MGc7`)Pt90oO#2 z4Q)S3*%C}XHuMsuG4=;Ewn<;LP5b?=#{6Aq0yrcC0`&u&0t2El16=z9Qr7}<9t3*t zlKb%{2S5TNd6Cw(?dd!}Mb0L-bbuP?5-{tL#43Ui7Tarw)CLKp@e~X3;8AJG0^Za~ zCOAzon8v&hpkDN?(WR=cQeQrM<|-NT>T?JboVL3c!Yu~wx(aCt1TfpspC3a7i2;+C z!6jzcO=G&bSlAs?n3Zi9XkK=KR1Ou3X=yiXrGRODHX}zYT+1<>Fe&_VZ}{PE_y8#4 zlrdsYCE^!2;<_N>w}$cEZUj=}OMtHhsYaqYMEb=?;tWLMF`+GzMA30X5q*q$?Gr^> z7$xfC@$@4nHD8VlZM6E^Xf1>2&py#6)zJ!AJZxmSu8(3=OjWo(#`wgj$k*lq-7(!J zPoX(aEv{I@eN_WhuMv8+N07W~pIFjBFN#@QZ(`9RlLvYXUjJd(*TVv)5T{QZ)pWk`Z-^EXhP_( zIk4O_=b`>|!h=wxn{+r|2I+xpZhjcWU>K$*6E-XZkH0D%lsQ3{xg!P7)HljJ2+Zuy z${gv;e7c|6j-GYRi=b-V^ETjB{ zEJsWR_!6J<(l6(AZjN48j`3NJ-XOO!f1T5ZTq9XCb(l(ngs0T6T+0woeHYa?e0g6q z>m3*P!O5{C1@$t87UWm49>v&>{0;3KAnlV3)2J=Zt|?`5()4<3s+s55O?~}CgMtKA2JAAn(a<)$G+$oDv@*r>-1>C-#P}C@aL4ob(9S6mt;IB z9lIf)aIv3)mAbPBDWE%SvN#}HqnEf^6P~==CU5&GptlQ4NxurRh`Anm4UMBkiuK9rU}MKrpmLqe3~l0+S^jZ=pi}Cm2Vdk}}l!F-2!e zLM7cF2J|8ZhCh{94f|P*B1NqjkRCIuRX5Aggw|>waOsA8 z(5C>l^WG=cb(U_t8m4Bpf-zc6W>&6!ZN&8-x#~0Q;Pt>_JA7g8JeUW3)o`cC_ks%8 z$~1%us=purx#~4#_2kn4*P#4DTPJah;CN>6!0oDcqM*<|eL)02jBmD)ZMV@ahsI(ScbgA&AEE z-_LO*ewnpB=q$S_DZ5+vPE1@5k}JPxO1*SxN7MOyyYIApE%k75bniON*BBgd8A52@ zL8=`}w%AcT8A`P{Mr~gCEL8Tn;J90KCw(crGq$r6vflX;r>o>ySEXdvykS>uKv!>8 zm%vch^mz(IE-zD= z{;@nYfAfC1#(v)y4PkDxtrH*$f`OQ3^p}d3EQ~@P?}Re{;JL@aj1qlbTnR-c%_WA! zpIi(S3C^ce_(D)0o}|ndwak~KTGO9ss_+&;afWI_{4_M69dd~+?}~d;7CKN9OXs2S zg+suoWpFhFUh^OSmH3^aL`i9w-5x$1q|`ExgSxmlyo@ul7OJ~})4Fx2yAwJ>XKjr# zI`Vs~wDg4~y<*C*#pR=?l$WejmlVOjwO4M}zF+C+BZX39Fh1864eon)4 zUu7j8^V^a3*-7It8YA#9AQM{C%`%{LUlS!Br*=1_lOJbTteg)VXDS`nXdkCL7=MX7 z@riz7PJH5v(FDwU;zPy+Ah5OEp0GokJfoX*mYBTs?v|E|lyYa6aaWXEn#6tHL-ejk zm32x*WQx;ZD$ajO2suX-Hg&i&_37yYeT!a$7pPw>rj1|Zn(AzW7=q_t;TqmC{nMj0YCNV#R*cUqndmInX+zeF zv(|z1SkwBtA=-uvHGG3ZVZ*{`!y2udr+DMAa|67+;qDK#!Z*=WHy?g*mjd!*Bb)MU zQ;K&e%EDVJmRnDQwhr>QJ}qtKUu@~$LNub&Y}Nn>j3QYkuRi8tJnU-mx7q zmuSp$znyVfu9r;|u$RgIwtUex0m5fT`Qq6yr4I@h0!60cL@)2A2*T#F<0CEcQ*R3r zLJC5eh4y=WQd_V7^v0K!2q%yqMZdX@{d7%JiB!h2(D-LxRb!!}S*z`^D2z<2QTL{# zXsB6evAy-CH*E2KRKr&qtPYeylEu*A0};30p5N z|4>Ik_OZOys(~ZnD;|x%|GraplnGw>oqTJ&bF`QqJVVxgTBg7LzWsq^dn5`%^^d!F zeAq^N7({#gaSWKo&)>_SmybnW8sN0Saq%(m?eD{5fdK$v>u(={2#>|a#V5py*(aqW zr=_N6re=%XOA!h*5K;sHQ2j?^TaVP-0wA`n54!Fb+kUlsjqQl+eRphTS_XmG&VN`1 zqzJ3TfD~bGe@_@dYypk!smZU4UoO`-HyHQbF%XK_eRu59GuFPXv@VxZTN2*Iy?agX#ZB z5mw5_y+=aWaUm6+RR11qLG+viz1a3OdMmhaGDTi0KTZ1Mq|rFVW1VR?-TjDZ zC)1PO#UwqH8_Og!TmrV69V{bLm=k8?!jzN3mV{Vr5rb{KDWFC`47Op!?FGf|^wi8H zl}XGj#h^tOmTc$|bNhpT5L@h$NB#80hgJRIYlqd}#b^-SF_ssE_k-=M?%I!f_^SUw z>BD=C?N$_^41 zTRQ&fj{T#t<(j17)cJ*`{^{0!>Lb+>*NiUhE!VW6kA>r$NxB91jH$se_kv~L)6T{J z47P5UKM;eh!X>iZBTDZzUk2T)^*|1ftBqhuyz9+qb%pCKd_z3v^%SZR=j~LVyT*SI z+x)VdeRxT|!p*Y^o@cIyHQ3$*fW|ibH)B>{=kMe6f@gnD#M(bMvoz6_|M^*m0%&ZJ z=xA@x2Sf~Re+}vZ8rvE0h7ixD@5>SX%>=6v!QK3q--Rv@H(Etb`c@*u{ts7o!Bu6r zwrdy>kS?W55NVW>E&=HVX%Ok|m~?k{cXxMpcc*lBr*psH+TZ&2{s%Ayg8}Efp5wln zOG6d7<9kuQc1T~+&y)cH0E!Tm$a+R*yA}XtOA-wa2~CO31TW9r z-;t-Z?e()mR8g=WqbmN)TTeL%eitYE58^s66I(Ww79TNvy*qXuP;!oBk-L|)t`x!A84&tUu|;EBcr#|-OVN80oEN-`6NWqF zl?uM8pWr(37{i;(N@IULJoX7mg$}Y4$pe9v!V3FeGgbsh9IFpD#R&NqC2P?q~5!rAin*lLQI6?MBQYxtdQJKcdm{R=65WNJC4<<*k z^}{(pu^rNQxQJ^<%%$_A%ppKMknFFXqJLW>E^t1OFjgF$nLR*hBuOP54x~^{=t6dv z1DTa(veI6WQLDtu(ISqD={ zYl-tgZBKNsVZP^!1KS6UhroP+>zS`^5=WV+V%YR$TXZjqEtK~6C}z>g$U?B;oA2%k z{}|h=9O{+?ab0+(v=I{nR@y{K>&B{rmtqSX9*fESR-#O6q644^O=Pv%3^k_G5=rti zFm-i5uM6#>@D!l?W=b8ei`2g@Z=8|M_HvyRYnvu-&jzv$`;?X>BBZEsVKvnC+S-6@ zQ#5V|=UNj>?c7sRG=Jwcb>cGHx4+dmMQ?)JV6(&M;~=~w6I)Q{J*{j>Pu2St)G{jQ z<&?g%dMilXI+=J{eI%V`G}XuLRBujn5p>LZB((IfeOmitjR^ci-oEPE?cPoR2PxCp zzQHi=@y%lmirk=MNAIkGAlU5PcVTrB|8Q?ofegF4rp}uBvnDV-;whSe@G5@dZL|M* zhU4607jffl%NZ?_5nWXG)chQi^l+K$?UDfH!!3&pcgBC>Suw$kOm@_Ry zP*b(>Hid=YzG1~nJVDfSYC2a&lvmTdzCjYD1!4iH#MNxYVI`> zitYsfiY>$#sZh2^_D%;mU`^Zk-HtKE(YdU4-M zLXB%T=S5BH6&_3Nuaj#x8;?yM0mc^DzW%M)NeA*x`JUu0DfT0W-Q!6`SV*xBHNer-&PqRXdHW)}0n^zGCTGYBMd8+KuBTM7R_yYF9SiLr+YFGlum*1C?e4B_ z+4us&pG>?I|MY}m!=0w9#|r>O2zxLG=d)f@X`LS^a{|ToZx00)BSbyy*4$cV6mFC=24EGJ8)xbV58A~9)*-!hh2khoOCBLgESO)10VQCb#J@9 zj5;X*w{4sx`rIDbhVu6UWfsqfNYxDRVb6zFHr&)8bg7+k< z1tg2bmZn91jD_SLGD4pPQr7P zcYz=%E$T=iLP0Q*E0(AyxxLpdu}xi2x;IG`g|^?VJ)tZKN3Up8KWMODyK)-D#V1x} z^OmgKbz14=dewY<$Rg`!gf)kOZ1PMN-F1K6byx`{Jx9%6UDX?1tsBQu7N@#Crwi6F z;PBX{j&s+oUSFKEb?r;8)jo3`$8uR_aDn;h0%z-@7w)py=Yp*K6|il$^j+V-eY?-1 zgOCpKp&=p^#&GE_!X)x7^*G|<4+E~|fMZq&k&NH81kt#k$C4e1JY`++Q zIq0!t8|A!`d1FIty}F~k*!#Uq0uZ=C%D~2!e@|J^z*~3^>18Tyz%6y>EyL;~ujEtV zyJ6bkElu^udb4&&B|Q-ri3o!!Pq5!?_>R z6&A}KgylJpeXhkKi--eDV3&u{ zOtf@DUd$)YG{%^D-xycX7*)1>Zxwb8hx}c#*g!`(y#}Swz*yG&*pl(sXcYu=I4(;Z zZ|enRTV-$i1tbSHWWcy}Nw9EZ^YLVh_olS;E#UE|M8mF&hnNP(w_nGH<5)$CB*Zu* ze2+*-Y)GJ;OCZ+qOUFsfD)7r0;LE$`D^SKN8o(;WDe*u{njXZib}0ESFL0TI6TWA2 zx1F@MnACp%3sRx9*P*m~-!@a2;Mc9@z(6u;Ea3!P%9tVHj6>NSZg35V=<(tA!$BEW zrAQTQa8`8C?0pa|Luyxi@VA?wqkz;mMW9Qzicl;u;5!vhtiWxmz+b9ZgoR8OO5gNP z-}ZMbWN}1TOh;)VU{3<;eM!N;2Ixi^GOH8LdNNZE%PO%5Y@m7IJ%x%}81 z1E(DI##&XCD9F1U&B7>ir>G9ST)U#5wn24fxOvV?bvOnrdb)Yy3m)D@dA@j_(hYeY zDvAoq`Js>X>0bGfORzyI4KbRrIcNE&Fa?Dl3;N{>(wz#%q6&EH3+AT^z&8bJ?+e%I z3b*A7a~mz(6ACY?3X2yD(asCiQHv@U(W;GjYaNSvV~UKF5;WS2u(pbRyeaOWDpven z+~Zi>uaY=4SUkdxHKxKpNmVkl*n;m~vi7L4xL8u(khJdD8pT=~r&OxsS9-E!t5Qvn zRiAt++IFTwIGSL0nOOF;WLLSD(%fHWTbHsR65JRM_%90W+1~9j-9e6upf05}&v)9; z)D<4LsUIFeBA%p`R}gBC9Ut*KNjN*3bi_%F)1d=9cR{-EAJUUL9hsX#KMaOqQAvK` zp!$|v1)vBA-g+Fy)J2t5Jk=%5I&wCKh)5**$@Ta z7(>-K%HQ~)*Er|Z_&2w4slBn}u<;P03DzE5h$Pf>uHA&@*VOP>*u2!#cHQ(Dt+~@l z%^<(X*uR-4qj_kkd2+jXOtn~*xWys9c;*muE(mMk5NipqWL33feQ9LbNT42PG?I06 zPjyr#uT{RU_03J|k#q7fRofBn*tKfgEnb;p z650haQyuKfa|Jq(j62Q^K|^=iIN~HCTA#k6_Ts*>s)R_N$<}oKu#!`$P44-3B2jh0 zi*~8@rhhT*TDHkx80unDpSrl~x|*&sf$3&TnQF|;RiwJ_s~D7#StuOdCqXL&ylO&`MAzHFmKGR-`%C&n;^!MD#rE)dkA8F-{uLs7dN|G+c#viG%thJ9lNQXbE@zy6^J$mzsf zm4q6O)XkI1v5xAP8yb35zE)l6iCy$9RE#YW%mkY^{TcX+RQY_)d3>4m=+gkgDk(iJ zhy*RXLM!S54HR3?n`v468Gq&(Ra$yDh~8EK2*HOfqMRDM)d~%oKm8NiGdw zV_O=qve2?J-dd80Ho9f}Yt!XeQhpVJELkCYb@dCu+Ltjcroa=^wsYFD3yHF8mp@0V zZOJy})E8|~#X)e0r`CNUu{yzpz=(Ay#ZMoE9J=Q9ZXJpzO$1#>IrR*_?F=!^5a`In zLE=P`p%f__+COABbo$8Ly4U)4m8~@Tht1`u4$$>EB z{YZ^i2e;U0Gx&rM=(yF`gwp*aNv@Q?h-sr-8QcdsW(RrPC?(I_Mck?-l00P^OO>HZ zHD-rhK8Ky0R^296T@uSZNJmqjkH&|VdrH;&G+G8ES7t_zeD;pYagJ9xTc^2?C4@%j zS0C##j+a+k|8PI)d^qV>KDksI(~WB@%(pxK`*auaXObxRL1z4KY6>V%WM?7uEn!FA z)d^B+5M-Mu2lM)R*c!CkM2XGYNzl~^`0p7JxN$n<{jYOul#RT+$q(RjN(2B!08|7Y zFF&ximv4|?K#+f6WJq*)Y+QW8e>b-A(3x=A$@#HGUL_^(Dqf3ig=9lxQ*(oMTYJ0o zOR?<|22h0I0mYY%?U>-p#&%Y3X?aQH4^V9XZ~`a-P;3uWj!)=ZUJsAGpa}5fuCK)w zxH~pZ^alDKU~Kd0JOVrc#`b?rY%MoEQJwkzXJY&B?pPe1RN+6ymXRfYqQE+D42jbX z9!b8-#s9m16UY6@%-wKJKoG#D$C7`mZes54vXL^_WJ z6k8DZ^dDpUuh@dl-ZuF?lWBc@p^J}==8BY^R``g?Ye)z)JmJ$Tr zp00H{jqw2}!sXsn(XTW@ci`^W=8zvzdh7G!-R0q&c@BUgK)}GRq5r4Y`lq8KGViT< zAxaVhD1rh-2J{Px;EQjz*X8%omjYmHL;ZULC{pu*yJMC9?f>qMF+l#_3}M~L-wb8P zTnA7Dn0sw307b}-up=GljuZz@jzvi@d;|k3f`VaAjJ{5RZY-D0zhbKwuN7^Wn_!#0 z-;-!kyFiBVdU(u&`!|3h>=^E%IN$8=0*A-oDbTzzjrKBpcD{FG1~VV*Wxanz5fqH} zb0SAG_H&bsa64X$ZJto{OR-I)>M1O)Jvb=*&<&sn)w4#x#CCSDqqOC&z!Mf?E7N3gWQRS7^ z>iYB-@wR^{!9Z) znyxh4*hps|G>2dh#}hdrDQ!_wc;NvHRfNE}gD5WBNCo{o`%bX`~8A7?5Y zhAF~h-B5?W3wIGHwrV5hcJoPu7Z!elFN`fk_kpw@yP&w1O+9dT4E{T(G!%+cu5b@k zrargQFbTv>SI?IdAzn>HZMP2sy$ocqdC1$KD3^5D<8>_3Lsf)8RdL}R|lTo-E8QYpR^Tf=X~TDX_- zZH}=FaRbA8k_al}&9O{%F{MT-mx=SkJ9TTH%gj29G}fxIT3`hK6(d{IrPznq@QqS3VUnH zlt(gngBE9*RT#@dN{k3*aD{~$zlAv-XJh;*5Y3qNtc*E*Wo-3DrxO2zA}qyv_S{cf z@E{eg`!=!-d>*xoV>H^Mn`jVX{brRgwJaO=AU~~qU8po-L?!+PuGB6QjG>|HL#D~X zK3@=OXHe5~Je%00d3I9L7F2Y$qte`nyAE2GPSr^1Q*7lcBRJbj)hxh*#tzpsvxhy> z#2N}mKDw$1Unzi7SZf_rxv7lTO?zVI;CY1m;dYNeYv6|7KACt^4Zak8lak2`)mU2t z@0@Oe*WV6bx$RjSGo)_i)PekPQ`g>;4$H;bIe>lZ)u)?bC5PR$U0KeMj)sJol+<;g za@)xKlz~!Lr2Y~8ylIVg11*Mi^@9Dpc_|>%u>`m~Rx1>A<`Rar%khhT(Vkat*c@l7 z{}=NERw%>`D#1HWA&yMgFxrhQPh+Tl7_enH>K9L9qyS+-6;{!3@UTS;X~AbP$N9*3 z&L}dD1rg~)P&5U1PM}o5Am)3Im{J?y6rK2{iXD6$>uOGD*xC>w%4Hw#ECvHmY;~9c z6hZQ$raGtCQ15VHelj;YPkh_h>T>WLJ}>q(X7r2G{m@^P-L`IVJ=gC?TIbojoYw<- zPPJ@l5Fu5`yW;wuf>)#P-za|Q+f^rx1na~6Oq|ACWQ^eo$?&sF9Q{x-A;@o&6Y6Ut zO71d=5?>9y7F7Itcg*Quu(fP_+YWa~=f@P+V!4|!?RbaPz z@bG0~+ujRx*#FR|_0@A8Qn;wnxK3fI<|nrKiaJ=$jYV;Np#}uH_SJ}*n=|7%Eeq5w zuD_&*z&z77MG!Xm&^vPC1Z3l^(7NV{S_llCo7KC~+ZMJVAiA(zq&Q2|Ph+blMcNdBA-Rx|L{jjdKo>Df>=IH z%ez)MH_>juTONctZ2QiMD;y1T%Ns#?9pRT!mq8r5U&GaUZ4_m^<5`WXGuj#1bs~30}^bza+{D)-a7Wt{TAqKUocrRyk(eVAK z6Su}H)H6$u$b+Tl{Z&5rB4KHOZnn+(+9>onaUpmtETH%Xr>N@09%bC)AmNrWDnI4h z!`_C|bT&$j&2%`Aj1UJ?_6OT5p-&R~5uy(dlr1WAbX=z|hsV}X+V1+KTtlOA^Y?^m z9#HDoZl-W;%6gYeKSdlqe6lT!7c(MTD+6mj0>6akfA;ObY5Y*=uVpX&sE}T6GBj&4 zdSjxEYC6emIwEb_VQtzSWvW+hy1ZjbXn^dN1HC?LMkU{{9)ZB@21~7cPep>0UT8;hSV~F;h_Q7SmvNF5#E%|QE$l|wZ z3oy1Cq5>KYtQuT%);#Zi@L~D?6tFqBwebZJiR9S;hAq^Fjnq3^Oa|LGdbZK9Bua6% zDtYhzp$N>cD1vY%sh<9CLq9uXdl<92Kn+NH%RDmcTQXZAa(i-7NBba`PJ5R+3b%J4 z&)c9VK9G+-D9aPnmnha}AD^lj)YS%sv!i+Moq=L&JFAcK&4Bb$-_bXWtSihOCj2j~ z%=;Wh@lVbZw~WED;ZX`Q(wENiRpIk25tJB^R0dwy2@$vr5%>!cgbirSsBeACU8~6C zPj-#=`iul@-2fUP=A+wJLpTYHpLM=&Z$MG32~n`Z?C&VpyU1XR+T90t+*=?#&?r25 zc|9-;JSN>e7ScWNS&@lYV~ANj=|M4XEj&pqASqc<$=YKG);t%jV-yo0uxxWF^GtTOn>fqL{VwUZ>|g3V#9S|`pv zWUAg_sXpzA@{1Ct;~H$}7AtUfEcBpX@<><;ZZWh<(dp8_$y6^4ojs#9F6?$yS`>~`oQ+e`0ZAGsW{5F{P$@R_MhIH9ZxGVSSr`trVP=t^9?mu9x!L1s1$b|?)T zpsPAt4jdlK(+}MNrJs4H7h^dY_NJd2IH4p;p|EEFm#-XdoNyNzAe1ZZFlDfH!#}~x zC`DzWDLcp3X5#;pWiob|QFNgztWt<#!VS;k#jEDys1`t|=6uNF#&s(q%Rb&UN`G%m z&L&^8lP$Z=MlTZeb-+!UJx6V+CVP!t@rQ|CPfqw+&M)}f#*ew$qKLXix%#3=hJ{EA zy}70bxhpVvHi>nPNp*D6)vg>YY`n^@?7-szba&i1Pow-mr~JUhdZGS&_+7Bd+vZsCJx0r{f%kBEe_i9qJKL zSAOKw$4F$LHqQ9MQAu8G0B7qATafutRQ4WJ2|bh9V;}yxCS04pi=+lzMO7oq^H|4= z-_6I_EkL78&l@SMDt}VfEhc8npU9@F%68-DCNTu3a#*93+>;@l^Q$OFBRD7T46aza zw%V)K5W&NEsMhol(Hx=9(n--;tZqxQ&K|+c$*B*d<{A34+j$r*>Sw(>em|LIJ&VkT zl%H|_!5>1K`eEw4VXEVR{eNsyLo|N8HNB;BJyrr@V{)@)KQv$PeZfcj#;ifL9CqBi z!osO-98-#>(qR4?yrBkgS{~h~=`k&0|mq61Vqb^Vs9?oa3o|?HRl6DwrMcT%o95>4#8G zMR^q$9~cOnobVAdh?6I->O0BADk-SHeH~^(h>^y2%e1!c|y9sjCKn=bc^G8XR2Q@^LMFOYA=M-vR@I4_W5sekPr zG|68moES_a*e^s|OjY*FqAjXZTP$c9Dq2}=epoCgSi1hU^hS2+-gZeee5tWz337G` zTCimtcbSo48A)Loy|-ndcsZndS*g-)?D+Qt*UGfS=-e~ZLdnX~%1X=KiU-!}x%eul z-s;{;>OsruvCHvWF*${&7`V>f!)37$>>z{BP>If2V5h%^ zP7ADbGr3OlvqwcS)({f?e5#w~2(97OxF9p%%K23L>u0Tase&5PwlVd#yeqU0QXlAZ zpLO!~NY%E+>ZRIWGxV=>*LphwW3dLMbAHS3-CC~9SFhyXG?aYaExP873T}u}i4Rf7 za%;U-!QLa0Z_K0`^yj{z5J*T488rB_5ZQWD{(Zl~dB3`NKX0WeDV3mTWHGfhF`bYo zllvh1FHx?UV1DUA@#;aT21#3rQ01s*^$A$0)^)j|bh&x;5dY?I4bgss(|*QuWzOY@ zCidv!aAlZVd(^dU+-!B1>v%}%_%z`7Nv(aU^f-}x{Ex=tKKjY#-}ar>$KSJG_x8ro zKdp7}teGo3U8Xu+r#^k{T0^uwg&xyK`PoT`+x79F({E=TnzD;v)EQ8KKbCfqlz!_M z+MwK)K_a@^OZ$7!_Lsf}!pgl{xG7Qw5B#HWQ}no-By5w>Eb8$cP;9-t|Dgy$!6Biq z6I)2=z}T1oxR4~z6rZ%9j8w>Xxq0~og+;lNrDf$6rP|dsHPZD!u&oz}r~0UKLau{&U6`~RW{EQL6)D8eU}e3=2O&jYb^>b=R7Rb(Sbtkwt1z~Ql%i7h;V zD3gF>7H+1RKDKnfr5uQTz|6B8;HXbe*~)B2JVgl6Wf=&W9j@n z>5Pp``%}4cSsEpc-;CM+b9d}`sooSJqpFDo3^2AH2)7by{;wNbsnDDTU}Kx4pCH-N zc>Pjr`;gOL50AN_@ct{dd3BwyjP0MV|2aH%O1<#H*gnfaQ2>lBj6ugg6aoHWZOsc+ z5MXT4Gk*hu?Lo%6FCNL-`b)9Z^5>2IcXv!H@JIFDMi3nU0tPe9DrFI{GGuJNFt(q< z5TPiy0LE5%3rCnNKnLZu*h&k+#`-D;OWw%qnyg z*P>b+9@nn;79H1b1giEl{6i6H4__v>)Md>$*{WX~Zxt+0TX!#tPTQ_w5YO7*U?G-w z;CxIjZ-r+}ex2B!cYjbcc|{Q{VOThq>AQ)3;akBFxtmxHknsdx^ihxpTMZDG;ad)o zHgQ_^eI81#8lhTxsvKjSd$Jzkd;5GjDvSjbT2X2jFJzP-wATQNV0u0CiXy0i?T=qn z1lpTrc*y$jn?<9#ksDxROY6U6J|}UzV!aDgT<24Xx>ehEqxP#_M=Ab)e6dUG zNrK*Uvwr@+hsW4RGJ-n;h*JzSV5!snTmxycyR?S(o3l%U=!)NZ4IlQhesW@*6!sc9 zo^{W9JXs6om*i@H_x0(l8|!qGOOG6w*baxaKoAiB`1*V`t!UozgF?5gMU=8-D^gtEQ~{ne_Fz1R&&*KVA5kt5(;=4?D7F@jQKZMwU>jH7*2i9ozOv|_z6k$-V|2N6| zz%zUb8gltJA7VZT5_s>$HU>_zUE9=3r^u@c{hU{}wNv`Wcbw_bRC;kz^y@l>b?|rd zD`N{yc)>n6TiZB8Ok5A32%>Y1t^!UV+JL(o(bm=rTNihvV$B(>nEX3$S0x7`#Z{rU zM>b|R<$HMWcxLQ?U5-2Wg|R*DjBUj}tMV54_?8Eu1Mn#6b7#_FKHc#mE5LY>1eciT zKjM5?ob|4EkwCB?QpFs#@TGgAH8&Gh+u4)$;}I{lYGCZ%aoqJE_c=k&qfR4NnG28| zHp8e(>N#P~4_e#a!20?@5IN?&nN&2(aiYKX26H{cJXo7x7a^N-F;3V?e3Iz)v5!~9 zFx;0(hveOGKP3M}dw6oTXMps8n1)ppYG^q*4#psS)J3NdYmTq-z&dgsRqRLP3K~<9 z4fLdWrGY_=uMs^P+DMl#cgN_0M6@j^FMD?ab3*~e*08WBk*8HJ92_G-Vt?8HPFpFm zqoCZf@I|o&S8^;-N>M2$=wlpWbI9FD(MSdB(TY*@z^l+R%v}z?#h{o#hi7zWW=cm4 zxlCe%nW$U59|et8rQQzjaz8GN5fM;|p|R}o`9+WWf2o$ha50D(1&Xb)A+f~)tLW_& zu(7Sq{d6lQfzM~12Jvl&H4Zj6(a}coGl9H0@yxVLjje)@x`KY)jG@i7o#u$`X}9QX z^#f3BnO9Z7;zwFvzn0p)+#Qo>X=Yz?T45ac^(=aPfpoJt-&_0J)^k2vJg4GMD3K1) zp%OTtr*h}!kKWwKiQQ07mG1tKCPY>{Kq*(>nw1#J7~{;`Br)JX)$41DEqUT`GSx|d z%)r)5OTHY*%$+g6yS0^;HwdvBhDPeGQijg=9PtCDk?w7QkJXO^Et`H`l@8LPuEsi9 zHXBfw`;CiTUN5SJoTz_tUZME)FnQa`iz4e9*Zn6`YM@OX(!#xoX-xn#J_0t>kraz& z0EXjE3T>2~oV++6-VePid-{x$OZ)~o=I0oPO z6M1%Vq}@6fMvMhr5~DDs+(wm0%k!!#{&RP%eyrtWjBHQP?<$+AM>X@EADAUk&~cJJ zhABJ5?MbA)dUEJb^;Mpf3%^aGl~9b@4YcKfT%O8I5g~t(`m@pR?g!hdSoM+-3uCpz zhvy~KB1}huqZh{Z0Q=_Tb`0$KF=+t;+Z~b>ZOm7ZiTM3gtoux?DdN2Qp`6lcuhM$1 z(wd;zrk#gW2hX0Ma!ibw#=6-@Y)_jv=4Qm^SAym@zUEZ%=G1rQka5_hJ>S2~e}AXw z#k_|DALoUTr;0M?)$+}<Rt6Obv`JN*7W4oj=a|2?5%Z_NZ9hMIqW~NZCGDo*zmI0=xf?o&4WpW<7|{GZ8Ror zv@dLeNNrvF$>bGn9j$DY@@#!6D1a=hK~Aa3BC4e?s*4p+=xrAbD`sLJ5RYw7rAJMj zOOpz+Psa{q%(c&+x6j=J@PoiYe~G&dZNIrd|Jy*{I*^brUATP^idWEvyhHPRker<^ zzP7Hao#bt{!&hrP9n9e0dJF>;^lV-Z8F7xtHG0=qZ)W_ZCA6i>@|Y}dq@Qm?*04i? zV!Ndjs`}obb1q5HR-B@0WVH*#e^8gD?U<^I&5~Z{K*}fiOux(ZT~} zWb?e)&?=Pup3)1RB^Wpmw<=#jF$v!-Sn6Y#^Sv}0yt3B4v>H_T=J9md)C55M0A?XF zAG=WDJ+kd>1?MyU%|}kj2W;u16z`+l?W4BmqlxXS1=7$}^3})wWSH-3)$MD$<$DY5 zXU*zoO93P5=ckhSA|DuB__<;G+iTf+*OU9PCb~!ZhgAAUO!~)P_@|Ntlp0dSU?){X z22?lL)q881?*=5Y+Goxuwc^lzi?s*9+9IXo-U0BJDJIaMvX1wz#OS_GBk)<_e$cdX z3L0ZDj#moT`(O^-z z$6hzK3I>->C)m#JjLv8Cq4)jHW4i{hh0Y^+VUe1Kf3Y*r2Mzy%!n1D--!{M^E`%c+ zvagdzycdZm)sCp}iWp9hz)RpDxOXLDi~RDC*)13O%$8+V1A*2N2^3r6^~ix`xe~I``?=9!qcQKYqcN26;xXkCqk+3)=Qo&S^}H1GIkNXTnxfx< zbCWu_7L5Hd28p?v_c0o5v1W;Q`Z!=UtHjtJ^|7Ptu^=M?3pN3(eQz5!bvsHQ&_0o) z$VcaeIM;nEcQ{`!k$4{mYrh4-0JcwDeeu>?@i)*35r#HV$_cRn30j#6z;!X%-Gpc+ z{|w5+YzP0`dy#xf(LzJY;swew<)TcIr20jwnuelkZ!yYR>J(P{FE>fu2T2{u+N`m~ zeGSEKKv;m(DX&jnu>n=@fo2y$4gMuf2EY}S65`8}r3FT!tdzAy-6JL@qgttVJt=~l z!CZ3E581(md5&{RA#?SqR|#cwa{5e*Wq%*a02BeT31zQ8^o@%1zCrr8AL+hitOG(} zHz4OO`}A+$!ai_h06!cvSYV@I-f*}8d4z_HjHwL5Mx&37>?98efPX+%h)9u`xlo?j zIGahQQpNm;%)nmGKE#QT4$1yd#T$gi`4IUo-(3)o`$u9mQhk&VJdYTBbdar?6jii= zOf(@#St+qbMaXX`vopVUAHD$g{AZv9Q=Eu?)VbLX@&9P_)*ls3EZlzrCng zRjU=ZxM3ivhrKx+1TM~wFLvoG9()uZ5RoX~E1p_R9%E}+bS&9mN?A#4Y0gjC&o0I4 zN>yW)T36BCJD{g~+qyiEdd6OM98mVQhY9GjHw{%+s(_{1cITuIE(i^&4TT*txCezr z#HPcuwg%dbsd_-Ww#O=r;tIXuDEQ5$3PePz9s-#Xrq&=*xfvKAL zSj9MG%#zee<%|p!-u8u)nFY6+;i-z>37r6aSlmyJM{>(rPZqzTv)1%u?J#{MO^O<@d839?OTR!ud9O%01pg^0xs(MhFG z0p;S&l_vJRN%s9t+Cxc0T>Y^^DAt-X5= zOAZc7vkd3nr9+_9$@-Mjg;vv>)IUdhCYWvFjBQ^5O*MJ+pm`LzqHTY^4fuaG=%x*l zUG4(5;ts#!QVCF2DiEK>Af927IoXz2;9*iS(zH9$y*jGSGVl+*i@uLGLw9{~(3!;XbnuZ6bpjWeo&oT)h0vpHob5-`+Pxpr|3#E$* zXL2+~i9^Q}lf^k}CUBAid;FAQ+cd;Mw2y<;VuP}pgL%P&l?{W5$9BobMIA*+o$N!I z1ll#t_I1hHjme9rokQd7Iu)?MpceGUyQMdHxE4uwIZ1bfvvg&@6n)bX|E=Dn8aQ<` zV5B`??}v3+5&7uqvh)RxQ-%I03D6SNS7vF;p;glnsl%4I(#d+t;b;u+?#jt*+sAKZ zcSh1tamSA&TzIZm1L($61v}sqpiVY^(@R3t}8cVNfhsJ_V;8ZKDG@7nHmn$Xx)x(?v@Sf zH$8?GIhQb-GHTPm3q1{0W0VS}ndW;WS2h#TW_Y=0bewzbIJ^~2)r^~GK#Mc$=Q9%+ zv*+})vp;7=EoKc;X8+X8Zfw^FKg^P#&mDZ5JJoIQ51zBjo)coQacTMGMgX4os&-jQHItlIE^R2GZyqT)Xh8sV9a#kgcmHkD8Fk$m!BT5I0BDnr&|A9m{&Z zd^FMe!14J{+-60n`!TjC>|*ONcJZH8!ihEHwN1&+?NJWsQt(NqxdNU0eXAMdW$Kg7 z&(k}}b?S)Iaq!a<_p_vv64BpvZjm!mjg5CU8Yw>w|qMwxc7w6R#-3%#Rnwc2OOe*sj}c ziN6NhJ;YZO;avaf`icv2Ge_7Th<2$kU1ANz86EV=zvMbI8JVav-MN&5C_@1@v|etIdkxblG$S;A4cIqfef z!pp`MKE`XNNU6%`1x1)8`-dVFFH{*!Mf#w|9xK(FZ8Cds)O}Hd1zrBHi7ib%yhax) zDm8a8ja(4_m|lIdTSd*L3}{5jTHRikR2t=+>jk1 z&-eeM2xQUFtO@OL`d<>rA_0hzEc#tHK3;uU_?6ug=YZdj@F53Yc+f}o4-})^()su$J+#mo&sC7Dl`N!D) zLlJR6wjSjKCbnZd?~tm-*m*Rs#@XI;*-VJx9bZjJ3;nm) zK0^?w0u$Rg4L_utd966$@x}j|*tXF^5m>(jTRVgZmR0Aul2^qRw5IgI>~7s3%e8+a znC0Y-I8@*Z8$_(US;OZPol-V1S&q#K8)cDqswho%o9EDe{ut!&K{1#Qk-oqC@9TMokhThcF3@omWy~r2E6!TO<0o}?DKP!SPpQizE58lwZlxTyfpyn(pbCs|J0$Kn zt+7bD8m0kOC+nF9YH&K#b!B|7k_CPEfTj-NWx{_LTV452xP$pS-||G(;k3It7ngT@ z8a>ucbSSzuUr>bM3}g>Rf+u`^w&nFvo7FD-JJfUk$8%&RKOJP>*rQv}QVU_=fu{{qq5YNJ$>+faeqk#VYFcD!VpUplkHVr}Q^EPqJRU%(p9WGz*j-7v_bHotW+T+w`C$FWmtBle*4JPlwg{cTJ zJkt7j7|*5nZ(5KaC}|^1n<6XMH?3BEQc&!)LZ{^yyr_(U+b~3R0_vL~c{;K0piWgN-V^|R)s}}%@uqRRGI5)IuC(^1g(f|;uf($O$=86#dgy`=CW^nBNljdtYc<&*}sgR2Qao<=CRfq z2SKxr3LA=5b{FD>;;(~g#-14g*AglE4H@wzpmAl`q&k!78?l+TKZJ%pTlY)w@NG| z{MD+26i-&J=hvr-?(P=nVjyl7j@}nbz~Z%aO@6JoH7>5j!CNpBs;yi@zJ0R%XYNM(-Nw53Ar2ty9;+CKy7#B~ek|k}&F+2N4NydS7g2g%%YlKxc_kZb+~_1o+v$C1*DiJgB6# z!(BAw%;fSJs<~pkD@+J-4FeS0FK$ADN?*fk+|!XntCEaIw-??qn-ZsdOxb95;k*BP z-TJ%g1op5aND8|#WysDeQ;@u_o|ud8&Us(5ckJOknQ~>vB($t3 zpXBi}_w%R1%k=&4b$5Tpojw)o^M%=rsTJ4N+Lw;DAHe?Zbj`LY;dbQWc3t82)bjPm zc@kxqLyevfZ<~)1da+RaoD}={S@-9;&(Eu>pJe&`D_33!)E1PS-aB!sdKsz?k={qO z-c0mrCs*F*ggzGzmTW3MRCdI-SC$XCK2_h<5wCq3rqw@D`(i2kiV*=Z2xiHz3x zva@MCycdz)w4SH2d4r~T_s#E{iKx1YCS$yf&dn1hG$$ZqYvkl_0`dO=mf?7*En=f> zcj15Mr_G0^bH7E6WMn6iXD5P2Bfn1Lfo|{33HDV1YdYGi&g$TyI%v~5=!-k(>o^z( zID}?86m>h4ZaNqtI9hW!rkXG^%w~TT-`RpST9{azHplmce|S7oas}T zuM1z~P+Zw@Tdl(c;Ou5R_l~3cUY+~lth*A5#|fRsvVg}W9q+X=@2#=Y{f@_9G*3MQ zb0ia76cbN02|UbvPi)TTLsy=36kbdN&j}#-gmd^r5(Fgq1h1T;<)3(S&%dCai(c~= zi2rWEpyItZ<1OYK<0h!~o7U%piI3cEOkyO=l8;DTVctjJ#s^v4x49-(d@fdtm<;#Y z3X{(7FoS&goAvMuP19SEwhZexeVPhjO`8T$((AZCk$$@Uuer;E;DGQp-jf*Op^V6% zXY0=pz>gLn;7H>L34qnu$?S+LJqP=#B*dwLm6Yuz1DD9^&?gUJ*9u z_M`w42?GnoGy+ZX2S$TCoY>C)z@6uLe*3gaDYDBp(l9oXWWbDUFY+~U6wdo7YSpNI zhp5dBI7DY=@OpRq`8@;wM+SmV2?U&6*>V-pVu>$4CuAf03P9`$=^+*=elhZ(7%54$ zJo}ul2{~7BJ{&}`_q9Swrs^!&>S}>jYPYc_cd@tu8eKKHdh^yj6xKL-*0#hpb_{Vg zjUt!2HtSDpNO$~}{o=JDqAmkT{-At7u?=d>C$B{K6k!{xs_kH)EuIIlt+#c_50D86 zkcba(rKgT?PRQgg%pQc%q+-yTdP^2GQfF}KW=SSSIKkE0!s^75sl@oR#Bx>X%Duqq zz@&DP;&wfR5Vc~qT&B*1;z2cLAW^aC8$4E+Ji=8nycgVU;@kmt?&3_DpD)3u0+Dy6 z+)<|j8CwJzmnm>52Y%>6ek#s)7wg_oTpHtZ)wC;6*==Cj^+4J~p*%tm#|e5lB8dWW z5GNX_+$SO(voSq(COzpqJ&`aY>tjag*NlAI45A-DFdH&z08V?Cv4Wea$(l)Bh(nvm z3vgPqnoPu-NUhb(1*EL!6j>jovZ!^lI1;nC@1pqjv-mLy1cUfRq_V};s>#x`C8Skl z?y`kcV-)US)o)dD-Z|x*=jJHg#}rgp{y`<>rO(w%jMXsB)lJGZIEekKB0_OZhBr%Q zi1Avo-`W%_&t@@>ZbxH~#zs=n8U(do`(EcmLauL8?9Ef}t6uLf?H{)9Z_lY6Bc+`# z72viT5S~;J?rawcEl9uw=QK7XH_;>%Bq%u2;224!6-XLo+GEZXKEEo=Bq*wsqOVpf zs+D4>FJ!Q&D{5XSvbiqmTxe=lf7@kO->EJ$SX~TU4Tnw?uYNG-b50f}EE&5mp5kt4 zassy9oF@iKrW;yT3JrhV$*nG=tPr;rObE54!e>0atOeb^1C ztvwG`cAFUXXQAyUe!1;=*(qnak3uZ5d(qhS??OBQ`b6<&Q7UlTsR zI)PvlfiO?Dm`k>#dbeDnfKWm=V}1A6#qLAen%}@9ihYgZ5V6LBntVYG^;8YaA+`=h z*bsO>p;l|4(W|@XYsyvk3$M=9rS9IEd_wfKJ4ggd(`Ryu|TYXzy|U2t@=1dJ4hoWVhAGnvQSqjA;o0?Vy=@{IFMe@n9|({l20tdf;Ckf z&{s(})sX7d1vh19HZ`d`wvj?xp^knUP~B|A{v_x?VKdalVDJ_iA>PtCWH9Dj(&Oqp z2W=T#YDvpWS%ao*lMYX4r0$r0J!)z_!fHE_a(VHhZ52I@*syI4+_ri6?apO{W~*&K znH>QbCXs1JHfs;^X-6w;4{L9a*=`3$u0&~oTmKyjIvp=VI={mhwKR-b~Qf}iXc0%~p1nHUjB6E^_G+$1&NW?Kwi}D`YMm#E)?c zCHc_ir@_r+21C&15v-x^W!Wy*rEb@fe%_R!pDDdEAwwZ4Yj;CX&eklB;kiGCyQCk= z`da76T#li`>#xc#l3ad)zpZPG?3aAoU0Ttq8aY@RL1ZdFk>NZGfj#b!4WZv)E8Z<( zJS>g=#U6XYJSHbP_ARG^Bxr0TeN44yOpB(Hifp|1czWVpX!LvLNw!xTvUh}%L)A$=lbqy&pEcEF5(I_+Y-lzTt2Xzi5WV^7Oz`C3ZX;ph39VAU=7i2&Zd!-BQ(Q&DB)e9|3_U0oX|rhMJG znSzw~N%V3zPUwWwFy`g*O3CnA%kb9E zl`)o2XH6?prJs)7j!s_vIxpc^)cSSBJbL>x{eJk@pI3@7S;Z$STz`v^ku6ry!dBaL z#wxp3Rkl{^kk)Yc*6@C=y$n+#F70gX?d<3se|0oY5vEKPRz>r3-NSF4uV|h5Xo7jg z>s@K|2a9fL^$oT#3z_5%@-IX@D;wXjHmToj3YPjvxNUyUpF(=+D}6lmh5WqNx>o7P zO5w=YKy%s(WNnt*Yey1q!3(^Dh*$f&rIs4+4i%*ugKY!DV{)*IPsWHmjob>YEG=ms zxg9@pUbt=f#qeQF<1n}F!{QNW$!!?Aa##v8T74K^#x}lGJF0#6X|}a(A9D1E@z?Le zqhA*7YwqD2#|m3oTsvXMd#$F=myVC+uuf7}iEcPh&8%Pr09>%i{iD$2RP{ z4-j*Tjf#OpCMG0&|IhFkJY$iPBvY_kCqw4Mn91$lfnL-yQc8Jz_w@>sMvbTM#LV%zE^!8&*YP~JyNV=d)A)< zWNeq4Y*KcYp><^|?>&*w{Dtbv*SdTo>ERjM^|ujJ(y7?Bo6&+0k8bu==oDbsjPwNQ%y3#Oto;uwwHbbP;5=$ zQ3Rq+B&M@n{cy@NSiOFP2oBd~xCD8DK@>1NMjic3q#-L@LQFCzMn$b)D^A(we>1kk zG_Rhe7Z@d)m+lz>jxB?6vfY#^Jc!0s4bae1dP8|=`ki%*2<(XqAe(K9Hn02-Z#Jpi#K`|tu7 z9y=SL=Fb3z$LfmDp23I5hS+9hKH_oi6rYc9?Eu*a0W{`|G5p8jF}jkA39->NfY|c9 z>UeZ)r^F3_;V}&}=AK8zc9tLp7#{maZ1aXYfZefwQ3Q@<+0BycmH%XHS#DNvA2d0C z`MpkcS_!86+rROs*!rn>4{XJmXL8XcmapILqz8;(GNld4b2I1twt=z~k7hy-3i0tn z4!ekiUEWP^mfjyX^G^W1 z3Y-*rQCiB#H@a*RFZOo-0b5ln3a$x>a9@MSM3DhHRoHXscn$fuTs9gR(3zC@epG^( zSKy#3}(_b5~}kezj-Bp%toi zQaszbodEc_UOG2Jbohh-u_Zs$ebxjKK>JYKDS4oo+E8PNxcFY_frlegkPfx}!i_^?d)@EA9@JOszSL^y?|60>Rc#fC#Sy}yc! z_)KM@z2oxD@`-C7&NhaA$*|eVMWJ!{0pB}f+ZwU6mBR4dff{nR9&(*q!Ddg1FR$4= zGYMWo=X$xXDk6ZuDV*3Izw!99@!BW=k)XiDq3S9+2qFA~S{}6_L$>UZ>36e^nZ~Oc zpzmN_mq}OxL18gEO}F^{ymKY&D=RIw1!e%WbG`MXUJR^jY|^hm#y#7>Z6|B)EwK!b zBGl;$8jjX^zVQ_ZUVRmg=^c@Bl==>B4GwIvQdk<}`HYydT>B(`-It%X-VDDZ`2~D1 zMiU`hY}Qw|^?iu=L=p6iFoQRE58`6nHyya{KGl9*p6I-`cHXgHE3ag_HY6)_Fz zxDsgIMc%~F%T)w*O-U&=*7uagaE5I~t~JI#D-&dS(t3+=4StItxf`PjO_Y3@G9mWbD<>kXAe-)p zJxT3uf@7-y9z{s~YiFH`digb4YF|F-?m0x*ew(vzf8-myVr$P-E@d|Pb9$!Y;74gs zA-C3Ise?XWQ8_F?Q>mWt8L6xN0ec+BYzt)**)-LP_VAMHuPU?9k*w760_;54-g5A<)bUa&?g0SEyRy$zqk(xAZn+Ac{ar z=0$LbsrFo}!(TtAwmS4i(Lwt3*%hI0+bbC>Y0f1A!g#-aw+tKpt|j8n*PC1+$95Ia zv$!T#4h*MjNkSdpt@7*b$qG3fgRrRI>km5u9HTD3-lm<`8}nVt-nm|9{elDAzZJM% z>k{?|`uY3v{N-MCsXDwL>LcFCTLn?dTvaBeh~bBAhO@cqK6AV|B4>FY_=Rj;cE+v8 zX|!oYdkE%8bloD$hSR)y>Z>oZc6P!e=lag&5c-DabH7N~LnPfV85;H00Z7?)bP2KH zPx;$(!urbHz63)yb5#v3IX8$hOzuP1tEIWZ%Dv)>Q9$vEEKuhK1j!J~7}3{%U` zlWV)90JbXuVp|$l^RQz%eK*Q&f8A$adi`s<4DsHf)t{%E-4hwCG!tz;7@_Rc!~4Tf z`KO<`N38Osg7P`SvtI&yewWJgRbHeLKTmN#`=WSneYN0K_NI061}e6U_1;WQxD2cK zm+UahL=>N!IR0}7ft(zItXLoACss)DFAyEAggAXg(A9C336;FmC7cLeC|kb_uqNg} zCGE3*wL|o}PKaVhh{_n1#@L4b+Aj}JQ?1TA}HsXVcgk(Kc}(fzhFRAkQ}Uo(M-V6iRM-ca%V#OQhJnia z-u?aHVrt}46X0T8?y^n)zGcUS9Lbf6%9UQ&71!SNjOgP)o-2Qs>+rSfofF$Qo!g}2 zr|AIs**f_J<%oCFZs@8CYjqK;j+_~^?wQ*PS+(xKfE9SmUFK4eMACz7ATry>L+!g+ zO~iNV0yEk@Go4GbCn}yy^HI&wN?83$82vbd8|K3fyd%9&k6D$U-*~QwsrYO?6H4&% z^y6Eh^?oW4Ak`293>*W*_Nyr#gOyKmtm+4_?bgPe+GX8 zC;y-Z2ro6_w>@0069i|@gpmwHwRDy60$f^wgydUWmt8G!MYxa#=UJ@H|RJF}dGTv>#Hk%g!p zB{PxS`;lb=W;b~rb?i~Jk~|E7Jfizi68llCfu6mnylCjknElaxy+7YGDF2S|A^>|? z*vF97^HCCcZxG^gMkE-h@dD#c5N-i;u_E)d<=bs5{QTbOuJ@=HnSJ;+Y8`koOQ@Rbl^IKkxt~d7+?57vaZ( zrsG^f3^C#lr(8jS!a@=)APQ-aO`fZoc%GA3otWrPWRE~dQ8q7L#h_Cone? zO|`gpK|+)=S>QvmRHs9fU9vTr;TnQ4tT{~qE6=vM`XHait(4l0iQ)TKYWYW5@(PtuWX&;<@23S8Wh7Nslr|mtwS2~nn*=|kx#!c*CeU-M^ml&V(rrkgir0U zmY}?QhdcwWxX=AQDj9Wm4s{rtd7h;8>UgkxS;2Z;!F)eVL6b;0Hg_4%4^txo9NQ>0 z;+RHaD#rpyVgX%ULF!#Y`dc!SABdmp0L286%QL~?M?mgkqx4jv7Ik9g!0SqqA|u73 zdLFQ4cVc}bIEX$e=%%O>Do&G`#1xg(%TwI!Ts*YcETBi-GauN`)iUM=pQzw)|SCTvMkUjfWNE;0qSC+-AG{pg&y;x8m8Sinj_Cgf10)(G?`nidRs0 zm4Y(q6ZN7zol7NSQYYD1B@+{jlbPEchq&v*+pJIOUD*y*MR8S$T~)kGReV1@C{&{; zxU#iA@rd&%Ni9}OF_}wq*Wm1SKXt140^)n=Hm0v+LRL=90q4dLG!04a1JwjoiSBzduc5v?(Osld@H7mc;BbTQ#AE^^^L zB*}TOl#IOmpz!uvQ?+YTgA4Swr>U%_XA%kZ4nu`Q zQ};t@;GoQ1NxQt3>^WG=oQBkD)37H;>xwzu4(Z75J^elp!{K7Nh9djYgqUBKtX~$-QWx7# z%+D?!LQGLyp=Kh@W+I^OW?WCfmTr*}9$8RNU#|Ip!_<;~jXd_xg}5B0Vo#Nj9*rNp zt46(sOME7Wy;^^!bzaTrz2awC%Qa%|bCv01=M-Rt%s3_X6>a%AlE!&!%zByCqlxGH zC-z&9_mf@pd*HzaqOeh7GzQ{A2I6!Jk^r;2SU8Y)Fk;yzT`iYOXRs_}kfMC>YeHfC z^87d+R02(`(yXaw$gbXXp<$^B@vNyS#NL5msH>(1T`RaClM)Q-8>y zcxG>D4QqLYY-I8%WqO!?HgtJjHg)kQD~XCd>$xY3!=y%gr!recdnXnP0G{t55k>zkFRqbzj8@3&%QkeOfw>``6^T+#1b~ zwU?=D)PE||;wGMPMZQ`29buJqoYw{HiXn$jvZt)`^H!H`tc$u&ETJ zR{YaV`0ghUR}M65iqu2-yELz6)261{ndILb-Th6))-$GGXDqPIc>9^3BtG`8eQsuX zIs-3U-_9b5&l>+duk@QmERVzDAPmHc2lK|8mA_ zau;?z-qCt3lJx+I4c(0|88iseGWb0og!8&gZ6VBJ0jMORXF{#2i(2-Z%G~S|Tg7W% z1@`g499ZOs(mvnxtKCQn?I)uzks2lUm$Y=Yw1mO-qxfknTZgMZw@xsRG?X69E*}6( zZu!p-hu99gwGQRjR|Z-ShgJ^fD_3?1jjTt)o6 zy8YL9cccTe_1J&rnBw6W5S7m?A}-uBufoSuaT~kEAd3jl2Bpx}2GB|5GJ=ASEpK;J%6MOsk`M&1x^A8Fj z_6rP+3=R*cb^m`Vw%L!nV}(WV-Ldk2727&^6ai3dlinc0SUS7AyLx-N`k;sd!$bYU z{eu%z(-S>&Ba5SReGBm6vCV%OTX+=V0Aud-_sQ`2D%!s&!mS)45Jg~Jg#eDN&_Bmk z;-6z13wLarO|s#{mM@W5(#9YPuGsPpWaU8PS@j2F3UYE~iQItQvHy)C0J~$KQQaBr zV}()D9u-@u{}S6od(ns-9aX+nsam*VTUDs~7)7w)D35*XSW439c)q?|RQK*z8z~|d zxeOfGg7JafF%@g{&Tu60ux6(-9VjU)|4K3dY)4ateaKUstM(>x_|tG;x`{Ohv;SK~ zustaKBjE5Gw@np>^I42C*&?Lbk!8^3@nRc5Z2z0F zZxzyvY)0@crpQE`@d0y=oB!Ov2ldMTwrm^)uM?{OYMv={n_P$ zZ?a|`br|}(<1dFVh@7h&Y!*H(#v<;wtu_y8l!f@R5hFeg{r$lN1EFu079rjyuqvg`Hmc+J51MvHfoT zj3UbaRcMOez)kptA^*78k}<)=^_y7538~FIw#nPwQG-cY@tQ|q`%IA_+@m!HLnu23 z_V?kMKNgd#{PiYbIUF*8`My4YW~5@ z%dFo9y(V$}QmzbKvG#34YQB)Cewqx<6*$?*c+6+`EA09j#qMc)S-*i*v1p> zKT9m^6i8Q*-%ms@Oj&``yH^Yn6?&M3tT}PhzXnK6Ws(5IR<=++eo#>}9l?IwNpnvk zudzUGgCq}H$YCNrU9uf!--1=7(kC@j`9t4nlb-w}TesQyO*q+Ta1npDxbi;DCdg?z zRja8_`Q&yQeVt137B#80lhDEK6Racf0dQ=4*_DuGb9xYkBH9PlW-5hL1PsjZe4&72 ztFD`FvY{7WGu2Z~AoCODJC-00oY=O!F~syq7zCgAQe$UeDEBWC^abJOD*Bxm8tg}gRYyFmoo|b-fFRUpEmFQStpup z()w6<+JgTh%XLfQ*IjCV*o`dkm))eze^)2&jcxS?OHxOK1QLnf`<(jagM?&IV3cuZ zw(qa*0ZhxYXd)JGdQnL!MUd0CV(il_4M_&oM3uN|>{w>o1Zl0tn|N08+>ij%Arky2 z34@BcAK{9vR&b&~Yc4DzJbjqb1IXCszT^TNTbsu!f(WIj zbA~2Kx1dgnVOijTHWI&J)lGEV66A&46y(B`z{KWPkGo^yvT$NMg;d<}J)`kQiPCrb za@2rNdPn;z!TK}ht*?%T;2GP-SreL6Uf0lOm;TGSu`IKT!$RCZjwbV8&qyRJBzyBV);@wWc)Ynin~9AGoWl_mR_5E;di zE+Fs#E*FZ$20LSHXph_+cUN1#w@%hKJiYlndSPATDKku=UDdxJQ@I|wwAss{Iv5e& z+?jt^KA?Ylrg~ht%~9sedi`{U0_9* zw^#L}eCd6)3b77PpF38mOCgC*%Cy;yd2jEXk_zsX(zH!@TO{X(j_!3YuRb{*X}zi& z{qvZy4fn&)d()`Y#!XV3`stIEtXbJYV^I@3nu>b-fi@6Dxbf&y-&<3%KGa6&@qgCu zU_MxDKE#d+)N99-@FsfsrmpyAj8Ny|el99`v3RMdt^QoE^&+cRp~iJj(m|AdV@a*z zEuVpSiR7K2gGf8){a4tM^+v!=_vM|EPvNB{C&Z_c#)`Jur|!FY{R<&14quFGA+}8` zHalxzuO7}+OihvJRIY*$+V*y)cJADz`v#{?qv}WJ7+-s1O8kIb1 zbDvg3djJ_*qZj5o2vHm9N(%x}gSJrvw!G`Cp2#Ym$kv|d5Ko*6PatVQa_UKe=Y?PY zoNz9hDBtT9QH&550n^urlr3)w21~(oRTM5l$=etMJRj^$0b5-kC1)RQV0g@wsH!Ix z`8pO|+3Jmmufc#-;kZ@DCu_XCINUy8i`%%SHQ%9FvcC6zcB+0(rhatFHZs{Fx;OEj z4E~0k5PkI5CQcBYZhwPp2;RECC3*nqhkz(mN_()jlT!ldM%!&Jz$2g9iyrLLFX3+j z2Iqr=`@zqzz~MxJt{(zpRHWj-QV@E*#JRwfn?OATm}902BVa=3a=tBq1QpRUx$Xq@ zJ`e71V5$N$*Yq>jak4Z(SeiLgPS1j82Htf7zvBiWy%Ma4$X`|mLe{xbUu}diP=R*2 zKvVUpQ;^W29njM)&;rr7C3HZC{!|lhd}|s843F)qm|PI0pF6pJsB!73Ga2Ma2jQEx ziKkz2D#Z4t_w;dG-h_v|$-pf%Wp0nbn1>slZ%8sJ6Ww^)v6W)owM4&Hbw%LKXEI1d z?&3z0b7iq5dQfsjeQNYLZ;!IsihAel`GG5%t$~kykB{>fkGmmydoudPO|=cN02qck9>EaWIr#41Sod;r5N4SvL`JLjs+$5O=z{$TVK>rJKLCCgRnQudM>{m4twa3v^>_%_Itb z?m`F=6C$}1k})Y`O~vB_0}}SMlLi7(5~$N|sevv+mZW`70UVzf&f6DbNR{r<>Ay_M zWlN$^N~#@js4qxrnolY@O9E_XCywO4si0ox9wg%su5`B)5n-Z>s+ekCESFk+4SAZA8#6 zM6fbOp3(tF{qHsG9_Pk9r^;C$c&gT|vNm+8w#Sr!d@y~2(n5Qd^;Xs-e2N`cSSnj| z5Ko-(`AlxM^kDYFcJ?>!nlDlaNX{`@i8UBg7Rp66T3ESO9WU>dat)F!O+dA(^RYS@ zLVQkE=F%jhM0ss~aYYmwKN{lNWAi{zUzdGh632K4u6*ye`MwMBYl5#d=i);e>qGAV zTB{XB(tywjxfg7J+(8l-C{h|5($vH=Kml3%;yHzOc|Rly7O0CFB}(=Sm5dWBf+VY? zifR_<>K0HM3SmWookhi)MQtFx4w9gzJ(TVR>0Xkz{fWhc+)P6Y#iN)dP%e17_Loh` zVs;5IGd2f(vf9{!KAEC$)zXcgsuEYa2@To4bsnP!oiw%{HW}ggg)V~2uJ%GnYtkHz zzByl&-C>m@sHG$ByIi0vFie-f@-x+$bV)LjAC52goealdbmRWy7It1ipwR(mhanvd z2$8wxKT2~mRW2h4xGHP#tKKC=zLl{Hf^D{Yt`u(IiJ}u^Tl;6-iP+ZYf8HG&hgNM>(MfF9$r#kt#Mooj+{dFoP}DpOVj9K@9>;81plsO`YT4IonNMt4 z9&8!Za7O5oi$(jgrPewzt>Lw6aaMHxNsHznF{$1qpG8FF>kM<&)7Lv$!@7f>&#uD{dn$aQZw<;0!)98;e zD*&PhLCyUtWBn<2{SjmX51$5H6$cO<2Bf0~6v_vZmjIj-Ud7z44p*1$p4{^{|`Q+YtsOL4bo$N^`Z%a253WUg{U%NYd^u6-1W75LSn4zb8|K8QT2zPD)KIq zlq~#`c<#}nQ}m_$8d%;ZaqF}uQ{rxxYP=iw+f(deg4)G`x(`0`d~qt8y;;`2&gvRE znwx}leXiW`hQJfn@}@GU&1_9PsJSm_e?}>l+&X3J{Qa!m&sn^6*cO`i?90qq*Wm*9 zVM@4jY zr3%)^3$R9ZjWx!W2@-b{mZ#lbG~L1vYrFXCR9YuT_*09Y~L6CR0s=2%yr(JNxH$xA`rNKV5Uyp?X)G}+xl3?6QX}Y3qhNJTnN5YbP$5w8~ z{x40Krlhl+u1l$;o5j3m>b#HKF168a*`Y%PnPax*LhjKn8|of(aUr@@KNhDYUTd+o zWUsk@Z)R_==~Zj%tNm=2FS+hF6beg6B%viMH-bK2OJ1feppVqZwcSWA-v!<_wcZ*D zm;dGA2=JFrdA9ObJ)K%qo@*-|JA{3-b>$gI{u<0V=nj*AA+11~cvPQu-`I9P)rz!i zQF+($OW81T!{V6HY;~{oc(CokjttR9=e~SjM-LL$9Rho^M z_8HmoWb++?D26)^-|2qa3nhfpmD%-!XKF9rt-Z7!E6!D44DgQ^Y&3cwmR6Op#WU5 zbvjL*hdNq@|7Uls9MT2Gn^ir`so3ZXFOW!;X#nze@QiK9Z2&xD8%)le2!<=RX(Pf0 zfMQ#&{{`|N#db2atEtX%1rNSE#(NXF(I5R*oaJA|Rsr(giftQEs{fB-tK}N~sMwA^ zR%~ID!Y2IMe;)3xM|awu{r?!(&Bdc>f&RB;At^RJx3lPHc{1)@QilkBY5E1tF0!w(#qJ z#5REGtp8E5r4LT-Ma-y`F~N21epGD#5!>?--s{8jQ2}T(Vk*naSG!LH;fk%yPI2$Q zD8d)ZbpPq^#!qXeHMEcHXLUT79p(&P>it)-{kJ>z6Fl!jmf64TFd2GHX@C8*j@nb0 z(uvkry%S99?-K>%Tq|HZzJWWoSerFgh|taW>&%9CNw&w*A9^12fE7rBm7FmA3cdc^bv6ijhq=BTvol?zjcSWt9cOJ?H)BH+mH)%C-uWT-V z^W!^Xq$3XKxCOSo!YV?L8M+cMfB3Tz4Xv6ec6CgZ)3U$u4Yd%H z5L$lN_O+!C!wjfOCS;`JW_2BLFp}sZQOo0nM-jU4(}0R?fPguo`-Sjp%42b`#O4?8 zxc+WhZrEwyU#|$?T=Wb~)o~#L%1FYx{vH<4H{o}Bc)&R?i#TCi%w%djbgDn=Q!So^ z#Y1HDwnQKILWP7bCVu!CdLAF5WVi&PK}>EoE%gg|S);^gNI!Mi}9C~rMVtW>oFO!qISze^n8Khj!9b2ko|5kM*NVzV^upHC_ zRa-xcYoVU0_Lm%jM-lo%VymNSWYi4JR7QQbD^e3mOfvV?)(3OhoBT>G5`#5YW8yj2 z{K{+=pxV2eFFR(qSbZsmbWaQ*J=>CBfUKrI12pgR^}wimP%%>B)D)u7ShY9FMLG;! zmVQ_%!pGA_3I#JXUnE+rCP!2amIOxqxHK`1xC~dN-o2K+V#&|2|iy1B+b`k*2&LUC3BUnElsKK(VE0 znp3SQtZGV8s{6sS>^xo6f|aUrE!bR1`@7i0P2zlpBytx>5KIS~Nmhz0A6ow|{RKU^ zxx$P&znym7Qy9EUJ!|dMGIR&Wru`vQ_kGy1^ne8)YM@HYHxWdU<6WTl$A#Oyh&j1#$}i`WhgL08N2M5qPm-nN|VP8r09< z2lfp=vx!CT+2+1(kdDc;qq6JS*V+x98!mMihGei7fXw!E2DjKq)sLf`&*NT)IolM9yfTA81_0cNd zmriC4Q~josXr$bqV@Owl#3R z9!&^!5m(6Qt;Q!SL6MdI z{WLeur^v9xTnlQ6-&@O3rJ3@o7W9h!S3ezR;gnjc;&qGddu?gn~OdR>{sGq^Y-nqrDwSBDpiJQ z+mHR<(RW1>ESJq4p&FaX&z&Vv70&jenmdq2WG)NU|Lm)bHqO+I*kdKVL8Zyv3evwF z)C&Bg%xLsJ*uxa6QJ8YX9@ez9W3gd0GI*Td$y1}}w?Rr3oah>FR1A`FviMt{Bxo@k z(W7c$OU{)dWkeT^zir?oc6)Y}Y!h1r-yK`gr`)|ulR+5&l=Sx^KTTCw^jZEy-rq}U z+p44rTK0nJgpqo*q*TYz`;~KN3yRBgDcE71FzLcrke1zG-+4{qsi$;TjOAXSdjP zK;0ws_N=ft>?JxTBt9`BK2s9BobgVxw!E1kxvRDOqvTU_YKidDs^`5Gv!WHNua$s= zFhFd%FRa9NtuA#nBqgk+RIG`weZSs_kaB3weD|Yr^iv_Sq3^TVn)YM9_S=8q|KX+W zvAr!2MeyYc@e6HyaQlBFWrtSj+*BBKSLj z!4Pmzy(G_=gFzl6aOu9&z#+;+kJ%{jM?5SLis)!J8<I?^nX^s*9+@_h{OPxMlUY zQ1(Fb@*teYy{l9DQx^%NQ%0osM5f0_b@D{#{ESua`SivUm&nUc)QiBx%fQQvxSyZ& zhX0j{>T7y$N(pbhF$=mmA_f2^)x(HccD-5iNp9JFN_Bl?xJWtC$+#uRcK*iOWN*w4s04&{R%-kG&IhK=e?oTaJ_L!BR^xEQ; zNWDz}3Wu2ux>-VcjWG_9U_IjiJ%~ymq+Tz6_ies2)4QucAc|0*z%<>>=kl#6a?0q`t5`lp=f8d=Wi2=CWR&z=QSS2eHgu$Vh? zweZ21%=Mh8*Rjajxy331v&jBVHeZ5$T)=-OP0vSWr_QPiK5qu@3hDz z^q1CDKDv-dinJJu5HF)NA-=N2a>vkpIFpn^sC%nyERh^?@n=sn#!Nwmq*?v+Yo;7+ zX7C$uC9J&qro5J-qF$S&@+_=89n2cS-awwwLZR5(AI_nX(I!yYZ=qO}rs${1?tPi@ zO*~V?By%?)6WW$J=B_+ZraZ~YH7$^J`Z24+Eo+&)dIS1u&@4>AFMAJM&8L9BaLrsujXbc=Pn)N0V6k-Bp04;h6<^TC-E-C^F9yD z#mCAc8vWS$Ja4V#WA08Y(LpTvP2GoqJUU9DXWI392=SYK^^Ah?%-VQtH}&jLVNR$o zm$nGEht(UH2(LCFKbxo^q+q5Po*;T7Dn?N#u1z8dLy`6LtNwM!Z^zM=S{6R0QO-20_@%)fa$uh|6FY=POL$8Nv(N|L};(gECJl45l8u4md&Qw2=F3JJ-BtC%B|@;>dklK5SRJ zYgRbh#3hVNZM?>{OUT13aCgc!Cd5PWk>PYjoFokl~gcaK*60$_AQm88%sm=qp;c0 z{rrw@Y?NN%v3{$up)sQo-Of>V1hmt1{VIBsjDIic>n_Uf+gTwI(feD8QdC46G*DN+#vawSd5DrDdw|JkZ0Ee`12aslHf zV&-TN>nccYw2u=$a_<@HN|3N&gyPXRFv)u(U7xTE2rkXlh>A6){xv9z18ZLuhr)u z;WSm6g%qO&_fOm6-0AxDWmh~-G47#xlsox4av5cdCO$jK^$0k%J63Bu)_OZ;G`kK@ z0azbydp)vZmjc$>J(xQh4O|=UTm?foBJ?`)IXDZCk-uWY$I7CS z`*p_#g*#^{mp_DbHr?;vG#XD+trS*AE$D_Js~;Hgt_)UvSU{hs?OLhl{5pPbiV&IO zn>aDuIf1-}ijS|L<&o5>fe`+%;H?vmHDvWQu+uP8_*i`w{q9(G*n=J|aAj8O? z^RNhhD|+gOxn)4TWv4jrEbJKFUTSf?#bwLj!(R60JA;08n}_Tl{TR8B5qM~h0uwrF zdL;Xqu&t97BBL?auKdegpfvIN1X1NPqUy`@XD3fM_0QFP&w-ydI^WNAZOXPpSG_dQk8XHz}bs65}+AMt4aJm<# z4Dj5JWS@P_ZkR&ISk3r;z4!Y?jDwW-+z32jZB+-EZ%xeKhG9)!8w?&)Dc67kS4!U= zmgDmMRyf=dHfyK3jgeOSs(jR(v$~Lai&OrsqXuibtF8y(?#ZX)e%s?kpJU9jV@9m+ zc>BlSA9{Y+#BVD9+x?d^I zKOU54Bo&)fz%w*9C*)@{<;f=uT_=pl=#D_fHUK{~EIcAq=5cr|Ml~@hIVF)O9h~u( z*k(}`{O8z~D*YeFwg#`Et+uVbv+8RnUf<*J*nd%karM3_yqUS_*~KZ?(vtcbkg@$w zvE3uzKm2~I{_FVg&)Vtv<=OSg?e(9BJ2>|hmaNMEJBq;6VIQ|48T<^}$J`qX$CE`22id`AW-}!~6k#0lzlyEPCUUj?&^!+1 zrT@Q-?OjXaBe8ueTHNNitCFvfqbwqr@VGnn)u-r@*tS!W1B$KtsmXN3`<%kg+sl*X zKWXp3cHQ4z{k8uHK;^<$-_A!cp=frhr)i5badEEF-<3)edq6whb!VG>K1B&gTHOXIK z`*(M2A94K=*uHq#@#H_nwx&x1es=f^s3KsW5d3p&nWJh6u=$Qo`mo>AK1LDP>rlu{ zD*?yW_Nec_jBRYx;0Q}j*s%m$C~C$jjEjIMV$Waj=3xvBw05vITs!ez^qzUd5Ql<5$xW6xmq6neL`0|L($f{C*YLW==NsT4( z<@v{hRN$9L>q>eF3Af{gzHD;(%F?;{k5Pojj4ktG66)eQ3dKo;_B=sKgH>Fh^^fQ1 zGAyZhDMdlH@e&xSCy3;G!2w)RdDx}^vE?>KOTQj7WonS1=H3Yv9HTY$LI+O*P$~mo zi9k(_VwwMUxJneD*t(@7s(e7`AXg%J(ICayTgdVXF}NkX8#O1l>D1gecoei7 z{aqlIYP=!)yni+kj_aBKZ;Mg)U1+ymWQK*59Mi_aQ>Xll?7_+xN zGQU2qSLwzEq6l(h;;*18ars2WNdjep91-bh(;wfIw6R)fH+;<9m@UmO8@B?>Ypi1f zitR}G=kx~6J>e38WFU$FX~>$(Cu!P{`(|c;n0-YQ(0YNv>2m!i2SI9~165uH;pi|I zeKob41Ul)%dX$H!MApxAz!j;LWI#PyD*Z~MKE@--h*d#rR9e0v0eogGtWYNJ%G8*G zdThqUp*?+s&;*7hVQ2!oVMqPkWFv)lM^1eayNVFB{8pZ_opII-SSaOsRrJcWA!3E5^kxxBgxBfGtr~ zhdwgno<7>l={th_fk5+Dk&X)ds|US|oHneHn7>ZNHvq+U9p@#A+N1z>D2#Pcgwmu=4^?8<$AykTHKC`&bw)Gs<^rR-8>b_Xt)ise{!tMncjbYx`bWi9 zR0I<|=~bLoBWGf6Gc%SCEe10tv)LxFscl6yWbWRvIT!z#aM9Zpx*RiggEnOQK6MgB z>*VmE5X=ozc526j?zu9aO~u-j7NU_%$x9^Vr*)MU^FhsHz0YQ7a9E+zu=+$W#N>ri zll&*>0bT!_;@6#Jl?CwT8Ews~5^b#V>OjHS24Z4>nU>dP$y=3C=#;A~@#0s5=PF&! zmnI+BXnPL?>O&?f3)L!`XAb6V+MTP{pYm}YKqKvU&sRLoDctWpiACAV=$h7p` zn&+v`O?rPbRg3i#;;=-*(W@<%_ifO?dOy^$=Yg+4KONI4KjCvP?7a4^c6N>V)O?j0 zWG|36Ij|8x+?D%;>2uq3>crWv`RA{NqaYs9=>5}`3!PGp5U3jVDyE#%OT9*Y)}R+6p?**1r3XEwd$O?wVM5-R2XoDS zYG-5O%bJyK*z&`LmX8Uy^S4sNkhZaInTF!pYm<$Fh>X?3hSStW2dVSx%v* z2la8^lx9d#4XRoluVsUYB`OO~>mW~iv!Bt7rSTuj?j7FV=8ye5ABSB0)rzb>4p@z& z3QS)3>oHn~h{3HR^{sOQtqU5g+1v!z<^!teZMev6+Ql?qyV<-6vpGr$6l4+pNdgKw z4+O#$;`~n|c|>k^o<=zbC7@`*rL_=b?2t;db_4A`f`W7A?5cx~{o&mrrS?gEI-7pzi@OpY3 zw@u_t!0NsK(VIlT`yAPf{MvN6#e22o{W@s^0;5l~h7Xhb%iU0)gO&v3KA+=V9}+^} zENS027~B`GzE>q^H!Z&R3yHjce1T;-*@8F7ES6|yei&}3*sV!=n|`>Zy!cnVgtC0Z ziyz6{lD!N3DO>re_xzt@1=-435y`f4twAd@w#nNfsVKoHAMDi3f`Msp?9^baRJ@X= z;DRPQOw*9df?!L22RJ?WBv7m{SSPzIq&z(YDM^P<3@w2yqh26G^g}55tgaWx(YG{o zn(&!`va9+Fc+5K>JX3302^3orA!n1ly z=ppV|29v-l0V1QiG;!-yHPRuQX!Ir~TgC&nu-@z}IBSxk zirWNH&@RKhHI$|?16H1~a+BeSp4mrU9mZcB1Q0U!%m}wk(V@)OC%Mx%)hBGathwQ; zntD1zdYUqlDXkPrNi{j3Y+!io<3|@nv04-bN(2r4V{;d5PZyKRYz&ed=&PJ_^PJ0l z>1%SCTP>RV{Tz4X+#Z%(RKa=%1q25(WCCzK8y0=ySy*ageVj~Q<{ABJ7(Ka1gVc1M zV0**fVnf+w106-9qJ{#Kc783N@g>OE!yuLe)~GDR^4W#;$x`fBnK+I1I1?9>{?s`B z1J<`UP5Lhi4Jf^(wVR>&h0_7e7yX4w2Zi@UMRt~)YT7F59`FQBHghdVg3b-sC+%0C zF^j**`x=519~%}hUyB=6EBQA_SH(QUB~82~PEbFWh!S^5iQ`O(&rJy#S*gZAa*%du zC}v7Hq%;avYJ6Ur^t`N6r>uJPNg73avskK=di!g)RCnTXNPD37war@=+fs^->4Nfd ziy-;1v}MAI$fdNVgS2$#ipj`|qJavW9{bb8^nBw=RH91K)J~cya3L$0IKHx?t&-MM z>?cLdL3TL>A#uG%|b)6&6ZuCq# ztP`g>t?(O6XSJcM+`aA#iikVG9>k0u3SlW!EUEo6cmx`1odH9g$(u;xc4^W`YVwLY zN+BBR!@AQa_5RHD3_5+od(Z975V_j>gzso^5yIch_wg__5DPMpQpE7L(+juvZ@GB@ z*BatN`G=rJDbGe0kNmT%M(vJ)t`bGPqX9080yUiiKJ5bS_5$5oC2Q1Xs}3*2+d*RU zW(O;83r~)vmS(F_4x8I%d&(9^1r=w@1lMI1_X;0Roe$nZuY4;$_`hhqkSPxKR1J-6 z4HtS7xr`Eh*!mu+O^C5AvE4EmE7|=3C2jO0*pm;)BxGms=Tbrn6d(rXkT5?;OgTig z8KD}dJ4NZ0nrJ{ zPMBiwY=(9zv3(oNu0#ObDc?0-URkt1jxg!$(^=?e{a*nxj9no+L z_XV2vNm{$HJY|U1jYu0SG}CaPEy8#2gYDZw*BqpGnFDE%Rvnu<4YY{%U)~8YU!y<;~84^ z72EijCEBU`c2Kquv?Kx?nXZwDkRR>%*hW(bH0zRe2%fo5^z*(g9ei__{rceL=mT=Z zi*ZC!$_xip50*_5|NM&8`C~^APRjax3Xx`m?kSOwe)zdX7G7q}YS|Rd$`qZ*XC~@R zZkz0<%e4n>lvboO`fq05aJce%&+r2@a(o7W?eB2h-ssNC>&X&!I=o|_Q+e8;RP8iJ zww*3Hr`~C(ojnKgp3}YGetwW=AkL_-)TpL7Z)P)4H`Hjex?>ZgI4ap>C|uxTJqU{Q z^2jpr>16d=-G%Zk`q?Z7R4)c~Ee6jo#@sL3Q7--AUfR-J!g5|pNm;^gSW=r@%D!L9 zA%PY0!Wh+IAG=Rat5^ILmK|q0&6iLfz$$cFUfL%Y)6!L9a`LZkC^u zt<)>7lv$1r1H+Q5DdVf~QLsngW{761!s^6CpwCk3V%6C4r{jq`;YqLKn)0-bRgul( zwDHKbjV{sOofR`!l{p4=xW9lyxlPcg<#5p_&0jQm#Ia^4_6 zB@y0a%ITqw+T<9YZpfqjRJbWLu}O5h$)7bNI6fm1{pBrnpUi}eT-TP^x96C6p&zWb zrC;VL=yyjfxXHj}LCW+R%EM%`l+DB?r9lqZ0mEO zVyVc@Ht6(e*UdW4Dg++KOK~~SQsCorS&z6UQEnQ*ITYqS1T)=R4cG%}w^1}NW1gDF zadIW-nI}~vr}*rr{WJ&DSi~x}W{bYg&9=z@X^~n9D~VAni{Zf-K7i~T)Y2R_DILDo zKWvFPgsdfZJotCnK)P*KT7-{YfQ|-zj)osbzf~QLPY8X}yZffUT7(%i-*q=WW4rKY zwH9`KuOhnTExIN0a}ig2TY2L1aQaH@+pU%0-2I9(Ju%Zgdx0qevX&4?Q;1sj?~|7q zOk7Cxc2&S!LhJrII{X_3F8VW0&SwF^L17_55g}3GkBV(#LO^U_N?2M3I3*pNn;97B z@Dj%d*d42=g#RC6`#)8LuidR!uMiPA2ZjcRM@OJT-v*|pp);ei^HbyVBe3z+rMdqh zw)+Q%M|&v8CsP<3e`d}RF9$BKPp8q~kB+VENlxOUV=K&GoF@^g@;8b=m+&`=;8ye) zMG&GOm#Z(7OE6I_S4=N_j3VfqrpY}jw*2-MOCyBRIXREJV~>jMBe7MIf1Wl|Qs!`y z{=ZQKXw%<}Z3MM~h9zF9S&lr*V-%srVgm|PY&lnPEKUx_DP3zmcljbA(NMVs{uf1P z1r*yj`nOMe(oRuFQ{dEwydCMMJENHro~R;_H~TZi3Z8o20{s?qRfg^VpNuW!*(3=~ zK&#zmbu4L471j0W_IRE`tg<)6`C#aoS!h>h`^C{foiFbDhxY6Lt%|n(b~4DM%s55V>0iaxB+V?z+$7zj zu&fx2-nhR5&#)WBV8#Q6#~w4b;imXrkB+Uk3+-NR5P`)|p5ou(F-(3n&Glg$EGAC3C7!uDKy3d-5iGmJ$XO>1v0V2Toeqea4GUAgsYM`80WD;rN6uIFkd=B= zY?X)#RKWxY0`f&{j>v@?5C<9Ah$8mbtwL??aQW7x=@j6C=tcB?D!iL$CVir@*Z{hp zHf)uc4GfP7KRHPEWlMU4=FB3*e*j)I5-(~V8J9I?Q_BOQ2=CO(9kR=xR?3%@8x1If zejH>qBc=%NUcWG0Y5)yeq==>)SNYt`XfI>#QT0kq+GZW*?pUOXFF4nP2%hDgVx~zl z%TM|69OaXZmr7@dy^4G{RzSL0Dht3{fY=tYD3uL@cIs2=*-f~T$;W)8XTUH(vEA01 z$uwy!`R!z`ddoT&0^=zqcDDT74pxn)XekyvFH?zTTZKuh_eJB_XpQPDHQw;G;&57l zyjNBS1^K(Z#T>MVD>Mf%1?qkt+XYcR!P%8xfWXeHGhV}cu%)>mUC?UhI-yVc>YD9K zPv%{UURWIy+(P8He%8edteyn8c6>MPtVu_H!#2Le@$;GKMlTpytFhlT!VLf~O zk@Bgn(>JfJ;WZvTEYYi_i{{qxDx0BqUvGO1eXlB{9}r}91F%n8QM}L*Q`@_D1W(%V zqpI}@j&X@YyLMMG z&nF7P&OzCt32CuD$c40zz!obZJ~HZ66r7TLgkqU2A!*D$=4IOm&FA4nF`A;d(2jgH ziZ-bVMTdmXBU{hMPe zWJkvN&v@buQ}LkOu6;_w$K8)5g3BYOZa3-Ke#N^YXi7m|KOJ-6ijDawkg5Pdio7_{ zUU6oeDR~`=&&1=6#T<|+WzU-#x^v*&;Zxm*#E(U#%1z}8&}oep_Tt)XEoD=sLv1V^ zQ&|bHinn}Y2}+YWh@S03EaYPiar>gGQgeN3XLD&xS1t5uy1$ZD%N|4-DP-ZenQ7XH&^w-=cLFY7a0d$Eg6!#PCc==jY0m-ox&x(Aoa zZciDzF}?itZi(z)BzjAmz_1{XY!A(f5)ehW+bE5burQ9qSpSnYX#raD}~u(#yI70gNqWg6nfh(fXrgMNbXh>kE|$5so5V1-9K& zXm^WWO6W^P&Vrs%E6j$|kufh*Kvy(R*#R%FnDFa7Q+1gCnAP&KTqu_9n}-Q;&hoyg z8|uy7IYXlej<=a9>&-oau~ReEr%73Qr)jLt#s`kh{Rdl$S%Bv~rMDn>?N{vLR{{u5 zt$vt$7M$l6+{FH`jV*~l{v?ZP9WHOk_td(Xta?Itv>mM!2YBc}JYz188QbL)4R$hh z5D&jL51(E#-=cJ&U9!e!DI0whO@TcPK@h)-8mb;&kR&K5YX*Tr1?dloP{pQZKvPgv zpzZy9P-CC1(iPkm#BZmaX4kuk9-C~}XDEzJ8Ui-9%fUlpeU7wm5@fX)VzYT?x(Jfq_a0#JnGOHCYsR7as9M-e{Mw`fl9TJR+n#H7&P z$(W+bl{hK3guki#qIor*$BFlP0>Rsl1YVlbUYPrggRWk~C1}tVuW`P3r&F&=ldL{vIE@qL^E*;XsO8f{xI-G3--lq@)g@xdEiST zV)TWKzeY$5+r;$wRmJCXN4H;AuEbyn|=V?d%NW*VM2MS=| z4^S)$0Perv8(Z5t2CB>juA~G;&sfLPr`j^w#0F~E8mDew@B{Cv0I&_j5DY*HzDh}} z?-ML)u>DYK8!~5mDUA_>p_Ni5gv1=uD-nX-q6IFq%jr%JtQEGDO)GW>OSB?6qQf0_ z6GJyP!PG6_I&~cuG#x*;jMg%T0MJ`@)3uC(98*&vz7^KA()T2k}S$e(4OI|0R3 zi#+sqWZZ`+H%)!q=A7Y0SE377Ln1f0fZG%(7ZoPmX&*huLOoj={S*@II!m>>C_``~ zvjY@VZ)o;f^A7l*9be_e6U8Po2A!7?yvIUi$;j7amf1&fAba! zSZ#4Q*Kv5{@%qy7MCS2+0rBMKN|fnJ)EK7ESQF^v5)2T0nA6!<%isww++T3+Cvcgw zAMqtZ4HETl*!f2|1Ti>;-8n^!@93Jv7VX?2EMz1O2cwh{Cf{X&?1w!&(A~$i5N-oSxl0r$Ejb$daaG|l#cD_&< z>aD_7q^4a|=THO!7wxqaT`?r;-4uPXNHi2wF}6@K)#fyZa$3P!f1eh|jlOgcY|D`@ zdCp^jKK#K8*d4p|%f40hXHyFjgfyF!3I>;U^1?rU5lD%ONO=wlkTDKO5^Qg55722U zd#|15`eiNVMSI!+dHO^Y)=O(TA)GQn4Rh%+xKLZiRQsi zQaiOkm1!gC#={stDzx%)?FJ>fab@*W?+xV> zwp`ZRdg;6RFjARCbeRaWyx7o&@1+gIZ1B8v(>yWHffu|0v6Yox9zYh)hd&uq^vqYL zr2F7GsAegzJ{qfeE3Z}IspF~eiIVa2sKS>Q&4arI#u-0Kio{Kyf=%_Rx9ZwcO(4$qtl;0~J~gJzB#uS~u%kvA0`eDBB9ho+NofvDHfQ znxS&xCB^e?wN%MIH-74@{)L{SO(qbsG)OpXwDQoOb`LU4Qr4t1#)@8^e2}95M?DKO zFePGa^e(_6kiX)9uUANYZbidopWm?$<@fFQ`VkS<38MUB#Z+XPBFOeDIIRaValoFA zu+SO0-TApScq^k4TShA_xXWM>o^DubXXb|aLwFK-91G{U&XQW_kAg`S)9QwFhdl`g zxX={QvBMwjuwE2gtg&w3%P%ljMnc;|^{$8R3lQCLB0nOa9P3fO?BT?5raK8)8|i)X zY39>!gn%+cUK|O|yI#{vi8lT|aic!TW0&U&_4Eq$n9Z}oM}5rg^?^fCNFMzkKh4ct zNn=C%=Ua1?y&7oeqkk+mF!RQMbmzBP2h6;m>2=IMp&PUj86;O7q;?oI%N%@FKiIS| zSba9wMmnUxJ>;Z2q~kEu$JadEGBi9pGnI+`%Tqt%*u1n0<(;>V2pT*l@f&D9y@ z3LfoN@`ud(cQiu=S0R-OR=t@YN3F*utjE5#k0}LP_f?dCOinF>X)NxvuVh+_4!3JC zYNCj&ZLMNrJx6lTpNLDZIJB~jEvq;ZuKZou8J*l2umA0AC0I923tIktBU1RXqjH+9 z>hKVeXI*PMYaKHileM<0&ipG=swn!Z{kD8Y-Tvgc&J;!0k9L&I11??43hJXYnsaEyKK8T>?00z?*rvW!EHjl;YZBa}>{#+m)u zhbb_YqUe^EC6|(^l_R5+qmPEcN+_9GFS2pWayi&P9TXMf_!fJ^@Z(@P9Wd2NSoJ;3 zmTkGw#t%(x*)?Jr(s@`mxQw^ATu-vn+x5Cl`l!@%rK=e-d=H6%t(cOxf1^I;bSs;r zvNj3iue3OJ*th=X!t1o8u2G}`hNS*jE3c79V(nNzsO~WC);w6PXqWE{MEMTq?K~0g zJRR>`j)Z^zZW)3`+NHl|_pp|Zs=1CsT7~?}&OxQ>aP8!GI|9%14D2fHHH#nQ)uFf( zKPbNb-gw@9(D0Ur&k@$n%=daS-q6= zfSkt(KPb>UchMg0TXqIxI?~)MC6Ctj=xLu>{vx@JcOY3wrwbp%H>W zVVCx6Vr{x2?f1jlueZO{+nmuH4I@Y`FJ2Y}e#NQl=0jxBNx zi|%l3o;dwu6oG6iY9Nv%(QIY7u0WdRxkLn&T)mMT2a8(oUSIvcjBVy$V#_Vn4;xWa z!xR0#iS7S7wm2TSCFl{eYU_1i;fkKPRRMAV*7pKUJ#yz z_PsCg*~>2B>pwd)1toods|cH;Iq%VfSY(e?N|1!4Kt^NNEk4=>J|IOG&tDOPFR_wy8 z=Rab5llw?)0mW81pLRP*_2A2PvL;>be;He`Al98UqZEMHO8w2)mM;wez?Qs(+KKzi z-`z3hZ0xhYiY>(+c@T-b8SZ~k1ZXK)oHT_wb&|&yAc|lhKkygW7QYW-19rzkZuI`@&-Rvh6^O20U6oRa?n43C*u za-jSdMR@VEb=^T9$k-M?65Hl>8^Zr3ww+fy3NMj=p9;PF`hdEE+>Jzv&4mmMk3B{a z0LAui6oEj~zjgpmzw-A0xvSOhAsSEJf&ZciC6$l6V=E4*Y<;@HW8B{qxySipqZ-C} z`;HvHiNQ1dzljryG)zg*S2_JtY*l1{tiVT2>+?xIhAf_WZAX#w`A@j_{tHUBA}%wg zrU=b5<|W6@%jDfzXK0o~pLk~sP2t`bYc9C=z3P5woB)7-bZl#eReI6>I<_&mi0)g_ z3KOl{0V+P%JIStHZCkmXG#)#Ju{OiIMSuiwklygq2pI<5$<~(^*?zp{p%h+_!gFTW`hCF>>EgiHn7(0Km2fU0S$TEGBKsAMXuN z{R~LN)II?!w(Gw$`C3sbb6-3HTN&A20#RcWto7U<;`+TLDRJyvQ9pDixcexe+abJO zkzZVf`)F?B;GtmxiUuKM>2zx-+>(V+#vx(pOh9N&i7J|?NEXbR!o&+2%l{ii_-Vq| zBA`U(E-|=)JrrdoTtJc6C%w_@3usar)D>GN{wq|@R1>*(9*E70WvSB z!h~;hX~Loz6@u{nbtP%%?@uqi24$_y=7wPZ?T*23)?J_KPNtBwRB>?p99nkU`_*!{ zIRp=R(Y--((u%HFjZfqjk1EI)Fd6(4`9pmIHZVN4Sf!6Be2WRZ0sxL}joT+O$Q66B9l0XqcIciHrbC^I!PjtxabBbdaBy#NW?h+*oc*7S??ffpqa(Xc zHv(Bl*l+MxFy6aO|CtQyVy-_M+4B*+K}U#oddIA^@4$LCou;=Z0Su2RV^!*(m$URp zi*Ut&Z)Qs;N@X<1>*68WMr_edm8PB3$vurGt<|g(J|;7n8${-!I4;vcN{s~+w~NDF zFttA3x%O8|WlG6x%Y~~}5Rq|fkJpq<11ZPWrgKY>vpOHp?c~LgkBD}StqtI!W#=CQgOSAfk$0RcqpHg`q~JosdMUB57FeRxrg5UV4$ zO&8ZjZqJESpx}f744*A2L8cR{6C)#gkq@FFvn9&TqPdg%g&?uH7Mi3B5AQC6vX|aN z%B1(;`y*4_4g4oo{hciFuMm~<{daxzr|hJATwH5|E+;O#Z1MYYp9qulb$r326zw0R ztqU)qAHr|A`VC}kUG){O$uwz%c_un`e)J7bxIPRDKkbZVX5E^`Y8x(@D~m)(Y&u8{(7>gp9|9uxp08xP>;J;7m=5o)%!W@!;%rhfb(GU6pmmda z_3_1jQS}1&t)nV4w8Uh5$m^Rc>NIIWxVZP6ChI~8>(V9bvW)WDLP9B`&kxfVn=(E- zn()M~0H6I5pNU?dyDc9$k*}D5${Al0MzF86d(u6r#VMTy>P!+6Ky1q_Q2CQFK*^YU zexUT^#z9rxGE2QBOMc=Mv0wn*S{Y(|q)kh)Fy|SS=GE_0S5@b8ptrW{Q-`5i+qzpD z6{yefs=LUkvy<6u3|hO)AXd1gg~^5B#371Z1*S=8CjLnim$kj(wJl8yy1B5)Ye)|~ z56Tu0>M#^)ceE>z(~981C>pU#2(~LN3&zt#6pBj&6kC1}(m=PpjNSmLw z6AMmHcxb;?=1y+tIzpJc8IJEFc7W{DGqtcz=di0dAcPV2WGXD?DhvldoahxiJb4d4 zjXxVa9G>Hry|+YwR2!kP8}aix`Fg%tGwfaD)?(L}lV)!G6S@}k>wGOe3p0m2`K>0LD zNTWbSBShnk3Juj&_g~-M)A}`ih!bF5(LkypQ8Ny#w}0uUU(-j-a7q6KX zA2TGH1MLKhM4O2Bc98cDY#dHt4p)k{wfvH#3{G#4HXPy)xh^jiuYHSLN^>ns!=V;6 z8jx5INW+dQ52HWxOmdQ-e~qWVRG(Tp%s>66taY@^dL%#&#U>Zp?k~XStQAlQ4wx{p zW;QDy$xw&!rh$wDS13BCJ^8V?kVL{N7O~Rf+dAK|z$>NpY|{lQm4<`LXVT$J!Mh4} zh3>&xZs6o5@CoJDUpiF@cu4yEoxuK8pkqkelKl@hht7TM&6^AdH-~O=hkbB2W(U@x zh3L3D&dHxl+`DQ-u9^<@nhOiZD@?H)ZM-{J%>yPr;6*=sRV$@gin{~y-=@+;~;?%PHY=@O9+QMwiB6cOo?ZV@D;yFt1c z8it{}Lwbhp?rx;JrFHHv_&cxby!T%F+5Qh^%{-X3j?eKvUSee3t`61Tuq373yU%`A z-(+@QKdFhNsZrLhQFX6Lj;pz^ugRILsko{s!LJp5SNl_?)_A~O3R2r#4SyJkvpTEQ z#jUd|rgvbLb8@eY5LaYb$+iKDJ0QdUf{k*V&`Up(cNHWD3W@!9f zKe;!wa_~E30qP@NkeNK7zz0*-grNt+S`P|v>w$WOdAWIEWmqA^tYILfVffw$xH?%u zvC87-veEQq2=?{;-nf`DWMBloB^zFA#IXFWHizjSQ^>cx(3F^@E^eCitJwd}DJdnX z`BKM5kr)y;6|jd{S~LgI21DXSN-wn0sTHl(Q${g#F*1mRl$ZM?*I3EAU-=okOKr$`qMnqPscW{N zO0P6R>mcHNv5OvgmVw7Kvs$;A+)LBN>BF|}H${?G2a+}=uk2WQ97?2|8r@t3rGW`G zk8ogi12b*6Beqw51WjrPuWh9om*U>ncnd@FJPbqU@r^+0w+>`=#k_E|ZDI zV(G+6*yus&C}t~oJEf@!R(w&~bfKFRiC(h8+d+h`rdT5qYMVVt@v0xA7sjTveE&N2 z*_HITqW(C#&$xQVIP;JWt8V)nR$X?X31QF&jL~*Mp$)Mz{4>VT3(XCsUlWAM9VY}| zM29*)32j~xbkYFW7GIyPK`g|lQ^AsCU^YY5bLyMkme0%-_rMfiSXXde<|^;BAqB`( zXgjiQ+UaQ8Ww;v=Z^m43Mo4W&!)C@lWrm^>K2tO^lXWp8PdF?1ZdO_Gp;DoqFsoBL z+c-IEa5?+Ey*HvHIyRL)9$PLkVs83d-;#e{(&C)T$y^@ZychR;xo_TgxB0Ea`67xZ zC8hmktjHA<3zen$H53Q8JO>c>0pC4nQ|dv%aWw>7# z{qaIhA`r89Lo)q>UpEjh`C`9oL%yuT@%iSRRG5m_Z=uOBujon3#7Wsdn|f*C%*<16 zsHAVqw@l&shBV@{E?>>9s=hQu2rg9VG`hUP=ypiE+78Zgvg&pLb=#C~dwIR`e!1go zmF=&$6PWfbc$g}5`CE7y66o(vl$B9Tnvs8aZNd>P_@yz#$~c?_AhxoZ!VDu4dv?Zq z1!;S!LwgFVd*wL$mBO*rdS10<^H7}c4a@t^xBIPZ2dynoxbH%(pjp4yJ!#iLX>9=& z!Qt?V_w$0qFRq8(DTgCVhsJ&I!`0?Lk_220?p!}^IA?T+TJN||y&Bu^d?!+TH(7b8 zTTf5E6knGeUyL-Jp^VHIuiR6N9AZ5XTS|YwK>uLBuuvdl>l+ml8^#tNoe21~;M90X zdIC5lDMgChfDL&M`!~u|dSc zf;YC?1KB+3Y)$;X_ou7g&o-wBoF6YWSfjpQzPmozoGAYCFJrsjk$>*p{O9)icpp$~ zTi|~kkbvE>|Dp&k89*ZdP;7C98T|d9tL?1%KUQo>4S?M-_^ZI3uY@!SrfVUO#Fi0p zb?t%JQing8G+lonw%H)HM`DYDzJd4X*hsv8wjPx6C!^?vw}<~n*Ppz8QX|= zuO2hDg}El*ioWLwIqdD`X9O~t6&S>s6%{(>>~#UVWAjV||8~cOzdr1ane9LO57=U| zJnwv{*mi9JjetS!{e!9(VgRrOcE=8D#)mV3-7zz=wujxZqdJMl-7yGr7Yu$-yMF}3 z@BGiPZMvQwX#3BxMP+&0Du@3tJoZ1twhdQA$EH(G(ZZ&aSV8BsoA~1@Fg*5uGq(BR zb_6f0uzUvI)&azmWk!}`NOhy+e=@eHtQVsnOc1KaR9{6n49mPJts0k-VC9+=SEs0% z(xBJdW*6WIF;A*L3uR6D?zHm_{QhEwQbA~8bp`bIPv=An!p$`$Lf_{o zL{i*`@g~ui?X97_HdJIG`r@LZZILM(zI2*>(gy8qi5nY!uLjW-+$!VnASeC|EMM`P z^P#w{n*sl#2p>tdyaSSzKVUl(cQjm&1_ksDe8qYpMn(EF*gG>EFYzH`Ys;QIH)tr% z0U3$f3QcRvGF9yOH05H;m1~P_(as>gIG7jSCY4P()7#CBn9n!%dD!06FJ)VQ8w8*4 zqkdU#`0_lXN8m>a$m4<7lAcBF-$YW~b@YB>Qu+Wy5olgZWlD?oih|>CgMf@JddN=f zD+7SoN=f4n?Zg!zwSv_8`YF(N<0}rLV~nK+fa$UX`N|l!!pU5{TRa&fV0f%AE|0Tj z7wjON_im*#-lK-5#mr_{dS3C_& zmqC@)V4?J7{+~wNP%t&G1rsXMx)e;l?x!PksnwzI1EcJmI=j*gu;s2%r_KFL+z5sy z6!Ec8t&1J7vwsmmfkU1h+rr02y1ukNlOl8KWK7PuEfquNY{@k}sH}rInOWKX}GgcR#@9{vE7OXv{w5Fv!h%KIrI{2T5fd z;wH+3Of_zCZ<7~V&qI}dO{(x+=?vSaF{K`S+ZI4&9T8nPAH5vR&kCs+@w(*5hyrnb zXmA{rX1*AgFfGWV?cbH(-_Odx;Sv{+hVLm^Pa2?otmzi(Hv^SkOjUrmq_w5Zllm^E zc?Sy1oQKR)Us@Ijdy-ZJQK)1S))ai*CsnRVu*g>fq6nZ`)dp$HYR`CUQ{4sCK5@05 zw?j4o15WFesg^aja*I>K#hS=7zBjPDr4vvc%R&E)+rnLWcCzl#rJO)J9=CHKHt*4G zX~XgxBigdL(LBU8!jXE+3i@M^`~AADuJ^lDBJ63{u}7sG z)Y4L5!9J?7?rkJ=@Ym^rb?`D8IJ71x(TL< zeoGNBv=*}EGp#>+>jY1F?VtPK!QK7qDMXLm7#p1U7 z73;ibsFQUC0YS=DgUt2ui*6g@KGR?GDL+pr#L8fJkpigT>f%% zRXcdbTGuG^hHM4#tGqCKPk7+F2K1rPFI5+ryIZF1Nf5g{j@08pPpQo$We=S9h4(s4 zBB=AKeqJV-n;|=wEB0g87S-9A1iQDG4&w_&7a!P573Fv)ClF@8XK{OH8JhuVR7`3m zvh25|3G6r;?3IK*c)UJuXyF_LyvoEb=1sux*sMLJtH8om zTRGk!2aTXQ{ikb&cGWd@v!iyq9d>L)!My)6wvssfiP(RrMXp+d|DMKlE=~ZY2aTq%dk`pl|-K((6 zTqpDGFZamK)>rVbpwG@g#x~AJUoGcTify=#18Fb#tIt*Vj~P-^P8ZTk(lFn3~mUjgb$a6c}F)T58{kuTw=ZqA9XlrL8 zv;E!WYuyoDsR6~d)j3Lx%A-TVL(R@ZFV6!Poo;Z(V>llbP;4g>qn(sIr=2~6vl!-i zOqO~)SDaDSoMX~Ny*Bfiwy&6WC7Ab#6pnaen-G7T*0BJJ?PXo;gzt}={2%M>KhQUS zU=etWqkl#M#}Nj2%g)8&t$!w|^8S3|jjs`}#%E5bVNOyX&$;QNcN5QztkRC+E2!!# z@`;NM3{PO1Rbi?3HJ|fkCr-4ROgtEz zEFzK235g=w#9%`b^lQg;9ZhocE5&9nh(;^x@E3>yBl0(UBn!XPm5bCHx7RlXk$1#Y ze_gVf5u@a|qXf00R05;W3ZoR;qp)|QTJWQv^F-L5ul>6oZn-6sebVFu?WuPjjhElBgU;!#qEm59oxmZxV@2v z<|D4hdCh;u0GlaD#nT}BsJj*fGriN&G_Rj7(7!48qM1N>t!zkQVZx}=olwX)n=ss6 zXb(gY`nf&NRUJvJJVPw!1JwjHz!u2<9wcfz+*Xmw{${j%rSn!bNyRV>^$2u$QnQwI zvTMLSp+;bCKwD7~%632+v?P;66O#vmgIXFN5Li?gm_{HpJ8y%11*ss>q8&wOAT3+l z6T&=6cI!=MPAu~*uxl+WJAjmRk(8hDmxnUw97P55*F76g(wWpujeDfGFFI2RH&SUI z=G@P)sZKI%PBI)?rKP!n5L!n57G9NFYVNJbX?no;APSa`j)4OM#)%~4& zcJz@+GtfgbieHNpibt4oW^%h%!9Hh#Bn(#StD@*7$mTOY+!;`ZzNBQ5Oee~sgH`W= zv*gX)SOH`C!tGMB=9)K~Tq&D7G+W1XwVAwhZ*%pT@~TAhjLh8zoc7pUA<*;o{FMDSKW?GXj~OwznDN4;;qO?4{N;=@pF6Ej6u&ytsla&X-nbB2KzD z-7mCsBOulTE_9JFtGY0Zq}5ll9HX)IBKv($h;~~5{Mjhfe!il-cd8uoq8x$wIif%X z5;Go37@k~W1x7=~=b4IU$?Y05Pn-($$N*w{pl1>d{!P$fGxk%2hWPJhm>_v2?OjJF zaYkQo_+W1(?zHopEi2H? zd0B0|D5;d(je-YEfp%-iWNQgf=?e6G36uWH9A!u*V}$8pk}UIGfYy9p22gAV>vC)x zWbI|@90eGh7m!_x>mu9hRyOK>44C)~#OUuK`(r8ux-$coZD=w}_(FXoCe(%>8mA52 zw1eX0LIF-&G591yU;zC(4r{_Y&%B_Z0X~3V03(&4iV%mvdZ@abr z2yR75!SR|+#!49@EyaEoo-(BQzGE|mFCT}{LxeaS7eKe9sRHrc{cSkiISM#B%#8 zcaR|)KBcrc#VgY#Fc2}>R;8r_p9ZUg-d<)(G`N0SoThQ>wn?Ql6P$Uv*6sACn+&gq z^3ks4uWhfkK8s_pr&)keTlNmp{sZA>HKzXOJV)dEsmBZksEsg}{b zKm^@VjF+RRORH=raKyc#Wjw1UIvedB`!R3cF@i(vvX0d23 zMd*icNlV6Amd4qzC#ZcYICLktg+#ZKCit82Yj#4#{;Z4O5T2=q)e&zPe4TW9QYpno zBz@Q+_h$o%u9HdolLXe3gvHcbnFyJK44t7(?ZYYkBXRv9GMkMEqCFRF3s;IF*F+uw zpM$I@wz>1NY$+lgQoAiIYA%CkTuWy(T4!|kXMSMMex{o(7n@Z#p8f1QtDG?#HZ-fh zHEV=2*GDsFEfV1DSVX}FU zE?8v(n|sQ0Y4NYc1hD5o;Lod(Xmif9tOnj3Qr#0?o?R^3G4`v0sjc$=x@a!uu;D#T zJ-)CExE3lo796>yIJpdO{?jx9!d*qBTs78MondN05)wi=T*WKLV1KLi+v^loq(!^^ zYlk%DWc8Gob&cxH+MkIrTDEa&)@Q$^+gQ@i7NXXWtJmbC#+k5@-+++V{*1qtU8k{F zUkU)2?S)h{f|JIExYvcGH35cD5L?Q{b-;$>2V%M9j(hY?wQ?~9p^U`LaFx_gEMc2t zVA6?ecqcCDma%o!ss_bUZ-ij-meok6jePaXy)B0~+fM0{0I|(?-Ug=P+}N@`K(D?2 zZhM2Wec7lVi0w<7U@N20GNkb39nfE+C^q8&thzX1`h+rL@L%HykGa%gxpWZY3jLnD z_+FmZURLRzLhD}X(OyMbY^C0h>c8`KY2TsE`>yl*%{T|pp@r-QGwS$(UcGz3=ol>X z8EL*JV@Q|)4URrrnkj2&T4)%YKAe4KxngB$xY<~^=l5%9h;P<1#Bh0giC66U3AOj> zK|0vTM*X(z7*5y>=36<#8oAMJ?s6N^M?(XW2!LVh3n;cB;eHX3;n7inY{Bsfa1baS z0!dCtOH544%*jp7eW)Vj+F}3yBDOFfjW95X$TmDWHZU?cIWj#lH##%5G&DKBGW36j z#~vNq4dl~{ZS>QtUDUh#KY(I;#YZ9uD7HR^cuXp2xtSe7xMWmGl0UP$Le$@xE%vf! zM?dV2A$`xw>5Gw4D$?nDM;i(3j`gQV#pWd>^M1XU>-*ms+f)`1qb>$BT6(@>_QUSj z{}-^WEdh4NCWKWx9)PXQoRuPndf8H~{rUJ(aowAh7O$t)#Ip4j@c&aqFzk7aCSfcH z43D)%vuZDAkZ^2|Bz*|Ok#oD)87$z7#fgU0m`@iOc6j~2iESCBKQ5aG@BUiv7kYZD z6zKWZX!`qCY(lp-do!sDkswe0--pW`VU$3|_FohM?k#_Jb+q1*{-#Cv&)wzj&dNwj z3viN-!tlylboBG84+>pyhA$S?P6qBj#a2GJE8v0H2536${0jP~*oLCD{s(MP{sG(d za1O1nkHFRtB=Zm0GJcDa#(&ryBjoFfc>uOCgkp~sTdCY<|A4JiADos{KM+0d<+lV) zIz-dF!YznJ8G7eGV(T!h*$G4u3hC2y9~|2s^RF3R0K^s;9wY5<{YPvg(_Zi9#9ZqC zH#`Oj{k5B)KK;6gC?^3Rwki)%gp$15N5yu(`28dhMX28bGPYtDKop_%7J~X*`$4ho zm48%h0b)DKCeQ;ATLDX?$Bgal%g2oET`B%!#&$y~<3X|A|F=7a`nWrGy#+)OZn%Fv zRBTyJ{zVag(-C}#-%t89Z;lrupP%fE6X`fDVt#bp4M^x zm$AKkAhz6-JQk_7bLQEHzfpDSu7?z1C zQ4_*epif&Sj{PBMX*CwG3tYTvLk?CHzP+0#eG_S`RB`0O z-~%>)4i$k)rZ~S68d>PKKxwf)X{~o+EI<_DiAc7*Ta35>MlORTXO0p?Nm5FBGdiua zpH341w(#(nM1a_`g-FR7_ZuYxRRqqd-Ne?MiL}5%dJ&Qd1>ee#SqXizbRv66qu=mz z8M+G1wCt5L`tu6*Y>KQBid0v1rb@a=iglCDQ(zbg{61VP-=OCjW1;zi*+!*q!#>*A zlL_^gBy0{h6FO%Y1pu{S^CG#(KFYYkX8@n$gPPpmDwj5Hz?vP6gte)=zvUBJJqCaU08@<7d+DS1Nf<5k-z1{>z_i!EKn` z(sTVnzmxpo*BsLoczV0i>~8pAcSr<#U5$5sDMyfgUX>NpndbJoTS<) z2=0U#g>dWSjme&2^FmSwh4jj&mrE2$PPA>y-~>7{wJPU;*uDoSwjWnwV0BHd&$B$XWxl+^I}HwIUo(o^NgBDnYEHAw^3LoPW0rr; ziPAjeQ##v)B5>W-a6@Gsqb!b|eHvyC09&qgFgdk82e;yuY2g`bD}<9^idJH#z}6CF(z6_tMWtR6+yXi zgNAffNv3KloHGXn-{topHqFM|A8O>R-8fQQ z=owY4&FfG7fw(3m{j z+~7r1L4lC;o>H<~_A5EZe(Cn-KE}9M8LmjVGg_o*1THBDdIrYdL*(D1Qap)Im z%?uqm`5iep%2DWUW2n#nswuOL(4{(qSuZ}hTnX5uV4(RBvg*3#lDX<{fIY0S#TV%k z6;Xd~b`ok2L=lMV4iGEbB923zk^MqI?UiWIwDWhWc~oqNL5pdZUeHoXYm>k4R}gXQ zv7TE!2}u@NfA<#pOovSxBJg2{RLE~Um(3}0*a6o#g-D*g98hc@cgKDKU)}y$VqNQ1 zlm4*`px9nkt~<9#i5dJzFX$Y_b!oMEKjcdiz6$+#edIFYPRL%8!Y&QwBWOMeL>>9s z{$=~*S2Xq72c0$ihl(xHvoQK&1EK-=^%?kTB!U2XBeti}BY4CfB>`W5oxI#zfNB(@ zKC&^LJ>FO7Z^xW3>yD{$b6MN@j0USl8aXTt00H%I#aq?Zy_Q z^*-d1+%sz2l)V-}sDCNYa_Q2?SJ`qp!E$w)Yx3OTEwSIbUS8}`MBvBdm9(}pvgY4W zyWzGLVNiGD^1tr(yWdiW`oaAh*9D%S+CJgYKuy%ZQnyLXu)(Ge$bV(4MJz;H!OL+S zpidmw0 zLH33j4><&)U-pkxzXVmudFdd2|^4*3v`V8Dw>>+hIB9Gb-&nu8Xq zCGnB3ljuub=-2#EqX%LuhEPjdyM(*v zlbIk<3|>12s=JsWMFi6uOfbA8{Y&m=F^sw&L zDI9Do9IMA7(*EELQ3Qys0OMy|g13ZSKeAE0#Wdr{X}yc4&7`3Z#Fodx=OiUG zAiFwaMrU+?HL=2$|U zc1#eqp_vwH>r`9sRP92N+V&;&x$_D7r{dS)s$%KAF6q}v;huHr-rLUKCd2hF!V#Gw z#_C;c9WrRAT{bc^7G^Udw8gb7rO&Q5is8H@#WpM#~Sy?;u6GV*5(ly z#aZ3vQTW9%8hSgpdCR-zW1z*qBT%k#GRH>qfjY(G7sM0S#|O;E>n9b2lB&!&0d};- z#ASgJa-qAjrHh}hbzg$ju4Tx2KrTRR`PFs_!8!9*rLhH8|ICZ+S0#IIsxx|Q@|s4Y=zQEp??ZwLN_;+PYc)@YVa z-wH$Lf>`rQy-c;2rE#vRk{hRzQBITF7*je5MY`rhdPwm43R4I=;VCgYDPx-Dkl82h zj87Jz74^YsALG(67b;-APN#f7?Y6_Jo`)-QhNC-u zx|#d=l1yB$Gu%{6+(RPcsavIEj!Q^lKdnWbV#p z5+i1bU{X=Rq-dBT=|aCTm_;&$(y;8&u-#_84RwDf9mQpq%|q(JrzI;ePv5hhJ%E&B zPM7l$!}HSvr_Cv8e`we)qUIhr#3)PWs=;D3+!VBm6m&4y^xW9K&et7?=6SonG2ySr zru{4;_4zq%TqtHffCKHB@*TDEfx*zY{ru-U-q^%GzA!jc)3rcI)hCP;rXON4paz?8 zf*F!nO8vH6$g@zPO|+VWc~$xPzVIbTEU8a!h%`jx)&PiY;`{m{KN5dYNq@oKqKYDL zd6EC1OmVAW0NPA(LXr)TiF~RqsDNhM32Q3Kc#>Asuu9e}ovAt73Zdc=9ySZKLQ9@x zN}joGKG6=cM|)Nmf-~12w8DgNgJ3`Ss;uEt8KPM5wwuVV^z;4xvcucw#~9^ougfJQ z$}dUVWSkM*8Ij;_ZNw>Uq>Z9am@8Ha^^nQh1#>EBu)?sk!}f2|8Z^T27upH5(|;%Z zq!j4jTqGNLQaKFn`1`$*BCzu1RwWCW0lPpay9~TaoLrJ8xf33piCbBf)>B2WRuzk1 zts+$4sm_k8E~~39o~)KVtFFMWQ7U%l(5h*2sL@ES@u;lP9j(y|W6&p)GZ3h? zRjVZn$UN8^XgK9q=$N~({1FmA3!a5J$+^|Br zSqsxbOZ)Ew^u3l2ubR6(2AdSsfJ=N6$D-qDzqWn9cJoHyJm^neV|9`Lh)j|{ZPPMV z6TrfkQ<5TROBNfNxb&a)HVz+zW755a+hu*y+AeNBCm$K@FF8#fxh=7~au3=a9oblI z`TMjL>1)|jmgmUf&ruJaqnEUb_OvqnYJHaCfTuGy{k!RFJpx(d82QrJ%LoDrEFu)< zb{gGwx<8>+E@?OdVJs0&%!^@fDLUGN^)GixJ2g6Z{{XM~9n)hIJS^gZ;guE_m8jAZ z6Oxly(w)*x5_oQ%%z2%PO_Y2Cor(vNO7~SN?}-=PozWglrD z*$HUIK)ky0K((Ao4yL8PArFYZaB4cikgw2AidSyaQW<&B-~K7_(r`aTGq=do!TZI7 zgd$toA>SnbQZs*x_(qVc|8(jQVvqkyipFY5F(gD|fO@!vv}C(+Inf)juW9iFyP0uR z^8j;Xx48L;qx7zE(>B4DrHQIFn#97TKGii(Yl4p_NMqc}}ExJ#{g z6uS79W2DO;+>@SC{`my}TR7?XOAjI|_Hl-zQ2M5|$^xh7$?dzlP7DX_oM}Ia%_lg9 z^!b|Bub~sZ>f-RebRQ!4q?lKP7^?xZjKs8tgv`>0)5fISp~PpQO_jsWXG&A}c2ndr zQz8vhEaOuJS5ukz)3V&t(n{0HHq)l5)2g-8TGP`F7t{KLGtO(>*7s44o(#@^WC3D3 z<=?ZI)8l?Wqk=nI{chGnZMKOjR~a(9Q8yb-@dPx~8^wwoBQzH$mzUVI3rU?zX{!Ho zHJ7#gIYZW4`nytI>K?-x=&y?F~deu<||2YoOEYJ{cHX0^`bBJ13uK-a_hh^6`ArJs9CL&Za5#ZB?wHE^7l z!Hh@0hL`u`fj@ru@ZjI0p<(Rb5zXeNE9W@Ex1}rhO~*5&+J949E1S)+R+#(22K z(HsUVXlMU(rcOiF;<8R2w$3-a&KvoOaBKbV-1&R#jZed0k@_oNT~de)Zp`j%NW(Wi z<7}?-Zb}JGsd<4knhn*5Hg%6SnGm9zz!w`7dBq`kMkmu;zZZ>bx1t6*+hP;Gw^ z-~P7M?U1@XT)iDV?%{=F;?1_>_je}nFH&&YPU!Fs!|u*H>TbBuE=X-R@nv38*>1|q zoA)7osZM<OS=c`2Z7Q?!>+K3{;PT-&|(6KB6PJYIlyAblXd{_pJvM?j># zvrd9_r7bl6h52<@Qt=*i%PrbMEm;wcI~5?=q=&sffTsw*8NJ4N&!Nc@0g0VMxZ0n& zuz;G-;*A5Fm2OI~st^9J-|G1nu&;NA|BE8z^u;nL1H{&D z^J&zZFM+{)9NB{qUfc0S&Di{rG!f^&Nb% ziY?<*GFRy^UZnewv8}UNZzd28DqDiN9Ak_DitSR9_fyQ5EW}|Cz?N*d{r@PoB;K0? zU=H(c@{FqOk&KUFgqFFFQG{&0_J6x$9crQtwTBDU`8yAatrcdgA10-|M}6eO?${Uj zum>Mxdo+DNNj{a|_pyplMiC4Qj{(H?O>^)Au}wd2Z*FqGa$4g^dK@16P4Y-=f51(U z81%h`@J&~J(C7;EeGNEwGW;CHcDnrW)ihocJUX_-!hmB7D7L?z{ioOlQ$2so*s?xI zs+`k+V*6sFVEtdlmVfvmV~au37A;9vxDhSE`LH|2&)5Yhw%<47@V`AMwoVTjTc^IZ zhbY2U5&&%JAaX#)_CH_?RBV%RSLck=Y_@hyUU>XvWI*}{Z0U-2{sCK%+J}N1Tt&0p zoOolV-8=}~Osng`u?4CK31$z&V{T?Bg_Zn8#bsU?<^(0f(#0k9({9DU@R$~mu^q>- zK^ZuD(s~mA0n7RUHyIY#T;&}L ztdDzi;4xzhL=pZcV|&jAaL@mhu?3(=~v#EhM4-?bH?z*RPK4xd|)x{TOHuH+7GbS&6`Y=UM>GO zJoYb&;4+U+Ugo?O)-Y5*7ee{!e}=~dGH~+P9 z_TGaq5yTMMdgZmgqegeUP=<1(H}@x<&sLty_AXQo0a1j<-LZ#^t-_n(-!tX0@_fe* zlp|NmaO%I;4^adm6cUBf*x03>ZEm*X< z9`_C0DkkKr?H$Re zH(_UwFw@Ql?{Gy57BNW-+np#@Z^-3a^UkS#rrCJ7#-i3;uP<73&4 zl?shv$aKh6Qe%{T*d2pb=c&QY;!R+&EGAL|TCflWTa3vxCq@R58$6}|cE>*IGAZ{q z;^!yK70ML?z&1ROGvAe2X^u&4s$`4HIe^*faxb}qf4ahpOWxLOKV?T2p3grsSLzVW zta)U%-4NWxY94{9z2CoGxjMz>3BuId)B=c;YMDL3#gjgn0#Tv|V#`UyfiTlSCk;5Z z4p}50HM+Tr#zLE9ztNuW^of%yfj0+pDCNEnTh%J1L*tCalr?34h)?9qReu*X1fmGA z>dehJvj<|EujY#^cu^oJSEQ84Uyd?6WT{Z9y?i2GS0Eo>WZjUwR@*;S1`yjH%--r< zr1d>QR#qmP+FDnE&{~+IU0N9PwwQ$a=H zr&Gd#*>2bxjx4eUPLaeTumum581w979k{BIFF#E;g?I4GJEc4j+r#Tg^~lSggp}tp zlz#}%n(yWaf8hV56z4r_i6lOG93CSnh>h;us27ncLyQ(^+Y*mr9G=QhdMDYIYcmQ{ z`lXLnH?VXRI_keF^wp(fp#2Pz81P2c+Rezc;}V4~=;U{%$F?@f>-np9;)B*+@x3ck zyr(U4;aT2=lKL#9v%EU8CxlIC6mQjn!f}sqNa;PgxwPuhtQ@GxcYA-`uby`N8O!#* zmo#{fc=o}U<=gA$eQTd!*U@jia%fCsk)*Z8fn%|sAOTGp#aov+5n*4(pvHbGGELbE zK(RIaK0qe`c(oU~aoP6+jOud=kGo?m@Iga266Haxs{8_}t#`>cgR_Hq-1aqFTt6m~ zms#>t`WWTyE6;~rhR^wq3r$Rum^03h7=(WJDL5m}>#QIaWWYV1W{Y2rMS-ewo^n@& zY25-*1P$>|x9m}Q;or!AR~N`YDwXWDato{&Wz+zms_!UB4Bb zhxYZ}l%kwLsw*Cd?MN1qks+B%V#HL5{BJ8YTUOA8+PQjq(C z)(i&JCjYQ>r#VGuMoxWf>GzUb1kV@4EA@F~ZalxP)UQ{E0-a3LKM|hs8Y<`?xFP#g zp()h26AhmPT3=S-O7vXTO3a7C6Q?PPhU&X{{x*a5J8E7gvRWDnXfHw*YY`3(t>8R( z@yAZ}500&_=ptl-hQ8O+%E9rk&W>7?FL7g;bCCQ+*2hncl9X@8M+PqPs*IXEqBAF# zWPX#i69rui@p~Q*IR0__6Z{8Tz`N(K*prXZttx^Q^Q;-Gwa(FPrZyFhRI<((3qlb@ zYKDOe^}leOi95Y#B7@OY*4jCCIgA_4|3f7y_%4%f=qf5vVh29lX%T))#h&LhR{t1O> z+sw${OF!1EBv8x!w!*t$SFD_?@*h3&a!N|E)kZ8YluEe0nLl|~IeEW7R~C*p=gH-i z%T~tSF$Wx5d<{<0RnwzHAAs22RwB5+P<`d1I=sbWnQfs&>pPR+%T({na&7sA%ZhD> zdzahKrpC&4$}0QZ%89_*jmx@1*}BT!+BnMkw%b}9j2@he45zb^o%Jti^{Ib_gu@d6 z?2f6q1gN9gKBw1Ow71pMuq7u7G++=epRzr)$GwORq;7jGUH6MdIX(^tWXE_jtLMB^^xXD*>MuA>@Maq6xdcCO%j*V%gNlo{8wI+_f6 z=`3~WTpm!NzuVTebV(wpbxAl=D-#jwxJeDSz zExDQd6FmldnC-bu+TVF%%|*@IDNLDop5(|cZhJ2Idign-u8k|akTRv zqZvcX2!DH#7{gTfHhJr9=Jby{9y2&zM1H_gj-pf0{UlSbY3Jwmz*4okB zcx!v0k3&e5^o2JtPBUqL-ImfM@O6F?4eEQ#>m+O5Af}%8_6&Gz+uF`xNRg&Jm5)eY ze2_ah$cr~wkVlu82A@ntcQRf#WHz~Z4nLeYC1QslN+V^5%hA&(h3#9&VL(Xe&yZ0* zI7zDMmkf>6tl2NQ8lm~YWQ7Hx#lfG-c0wx{!hnr2T&J))aM<3@uts8uW=V-wG=p}H z@Gh5dgAA8`-q(Y(;lspKW5f{?Xw(TN5u7m*C=lueQ<|j$niXQ&UoNy8#F=00K=?&; zdoGy@c``}~GA9h~r;?GcNVCEWBEjwMbo1`_;H(yUkK%E;EIj5O`Y5FDQE09#sNdyz z_M-S<+2eT83(lS*^U(x_ECJjK@8?-gFBA}wO>Z{X+UUTFq`5M*Pw{GE)ZB7u<8$9= z{>Z-kjHnUIy#9lm#G5zCjNg^xDcD94x2bmJSom@&s#<_A0G`-36k#?3Rl6z zeQJK5@2%xa&+DtoRSIymn(5d$}#E(%;SUsQHmvrj^jn z;48^YvU_!k+YN*C!%7%mCwtWEU`&dPYb8%gm(Hqw7&rPLe3cB4kI%1DR*M|E`N~*x zQd~cTZ1<;dZlr`fPd&ONo?sN4LJytk`!XjLy5LH-G)K0A4mh<=>x^Mru4y~2&U=00 z2YoL+uhQ)B()5*ru|K6m>5M{)wL;wSEsE`QsJt<65xHR@H%`-Dv zJXoc+QYM=@9WiND(YD*kHAo$WfeKQ^pX@GJEK5Hx%S2i&x}TMam@P&Ywa6L8DV;rV z}0(POgm4$%gj&z*yNF_Y?GjrB#v!_4r&R!EW=aZ~DUVCQ^b z-~9WW8@t!GkipxgRkBi^E69dS@|Je#Oep@mSujyt^YU%8I8oWze(;7?i=|JQ!`HI- zf-?WMGX9G)1oH9^oWKNJxwJ$1x5RR#>hgxMa&^F|#dO}_tN5l;f#P1VA6=naQGw-7 zi4!J)OZJnN`)40GT~GgKi2qN@te<29KiSuQQj%3tC1=o@SJE%gFuF^#3{<{Z=pcVp zC1OEOx(BM8%;X6(5=ibmm&}3&MKhQsC1YJPiAK)tmbrbh?dt>5?s00w#8!moS~v876Fz$h)}>yuzmckQ zF|W%@Fyo!8^IV91QxjWx*(-UI_tvOBAWYd?AU`Cz@AHeN3T{1s*jcxlKb8j#VDe48 zvq(+uFS=I^$KcJyEDU(+hp4ZX&5V#A1}kjfD;|L5uEWYP8`NJlM2IxhxTDvFHTE=wfUOdL1d=+y-BiKrtS&Z=n7X0(h|X?`>453i(}^KeM8yb z24VytNr5GXbnl3gB8DdDgrP%*wb+WILyo)X^n@Aij4vooXyFX7bo7BXii59|_mr<$ z+UcCa@r%P5QeHDPwzH5M0vTIMZR&U75!Bipl6Dqz#@FH%tla=F2h(plQr)p|>t%zIge5nb>4jkN|nbQ+_~ zhNjJ$<*g!2esi+^KotVb-K*z) zgVlu(_gave|G?~vE17$?GxvdH9xUt=Hn5%2oNw1^k;kH1ayVZq*B`{RPypJimV?!J zEckWsR+jL<4%Hg}@HPKgP{dtq#~$pmT=Y>L>`qy1iftIyJt!4H_W6kL zLceMF1Wn@-YViln(IgTNpZGsl4Tos z{Tp(BH~1Ag4|g&p!mHF@Ug#!liovUHb~Ysyx~9K%S>_o_7Bfq0Z>@gYl3(aTg>Gr2 z%NvAuQ_jiH)7O${div(g_;p7w=I3nZciZZ*@s93VJ&Qm2f7m+fuBsY-?E=!RC=Dvo zf=YKtH%PY#NSAbXZn|O9y-AVo?(S}oE&*xT@7j1j=iJX3?OC>2rXZhLFy?yqyn|n@>8bjd{1{=QbaE%$nRhpS*IdGTCqa@`lo7A!o>< z#Bx9OZo%Ddpm60TeRco)(0=yfJ~QV*lG1@(`Cx15fy9TUF2=6&?{86|Mvj+k{yBM`D}GpZS=v%{74(LR?EqOHm)A2$h0=iEX1O zEQ-*k)7{hC>o_1Y1k2ctU_NGSXN?yY7x-Yrc4Koxe|u-gVP6+eY>$2d`ve_RA{VIGqGD~ou6R^zX(Uo%ift$%&B%P;kIf!b7_db<3x)yP^tg_SJm_E| z16|+Wj4h|#!dBaV99!b5kjLS%zZqMp*CKrM(2(o2(bqpYM$2{5xaY z-1rD=Yg_cXg8p}R>~wR`>14y*p76y_WWZj#{cK3DQOZ}wv;8&o&tYGTwxh&A%;jtdt%`nz%NV_u-Mfiu< z3Q8sV!ih8p8b*tw>lwyKFat8IJb!&|tdf}N+sXn$hJM!J-I~k5L52 zfzE$`ZFUh5Md%pog;i`1N*;H|>bAiLXdf@R)6m=z-@PR4;j_bEwLysHwDh{j~Pa7KB|C`vpZ+*Q*a*F%}=g_(xaWwR_1D%HSv=dt# z^H3o!b6Z2w> zfA+p@T!?14a$JZ6SZkLN{wHHQ4I{SG_Pk@iXLWaVNYM*X`iwYT5m&{#?lD8T|P@Wz&hpwd5p#&AnEv)XTF~t2BCZewgFQ|D^h)MG&n!a!d$!8mb_6 zy^|3wen0wg0!r~I1WpMd7NJ3e22~~#!CWW~nfug7&si!8(ivR8b|HUr^_ZaIswce`MjTEvoUT10c|0UiH1ywr8pHZ>Ed%-<@4 zelH?x5c zNH!iHZ44FnCy-fJzntq?Y^F#%!ji;*BKRy0vK4`rIhCtgQ6VJ_%6l8hN~O+RC}lK| z_s*$*Q1|vs`s={6ln7QC_~+*`T{6_MAPpdjfG6h$GD?3C85Yv8QwSX}%BJWZ7T4KN zNm!W57ZM$j&jT{HGB1iX^NJlC&eKlqcW9Lgb4YCt(yxaK_^cjggcRkZhe~yaX-lnSe4%Buhvwe$~F4mkS<{GL0T?+RqO?yX*dwPDl ztZcCOFR^{${YtHrB722xwT6aqwjet3g5nlD)HQ430qYy)``oE z+nR9DHBc(ONOtsqcx0HZ(zMPz^YOf_%y=-8UVLyt^sXbzw2IVgTX_cn+hsJwAn7Gk z)zi8@*)o+R#rW-aPJZN+S@s3e%edgv23w6R$6rv2&SSu_Wg7Z|MIgLFF4fZ{DD&Nj zTexeq?yC9d>!V|P1N?@IzUkxtO8NX2#1z(Wvti;ND+)y?467l6=OY+eL+0TWXQ|8a zr;%CbCN_z3W1#eUn0qCls~$zrbLuOS+9wLW7D|kZ0`dnN_`Q`j#pn~+PA!BW{dY+G{kW3WW zT_KX&v0yp-D%1fJ|AFEx%y8CRGO2N>l-BJ8PP0iff03#Cw}qTc@Y5HQ*AxF?;^72JN9d=Qfovd;W_HR?syWdJMVvE;Uq%6x`QCc)@#KTjp z6Yf~mE;VC@aa;oYgRQBxq%yq9WhYgk0^4|h7j3`Op0 z(f@JnSke+ppz%|-#wEV_@GG12si{p3NrtR5mymhHc+4ePzUWJ{+1dqA=Vb6qcx=MjBrjoZ7akd>S$4{zNzVI|7^JbDP5mw$8xQWDOCG*dbobXDMIJDQDT6g z^=s!KIeVgo^7k8zC(e_hE3b;61i@lqu12{L$+tiiL7isUqj^{KPgxI#I%&BN#^L7` z(gJq48VZ78-Bg!{naF!6+j=eQ;m^O!sr9@!_|8 zjcvkbFByi#6-i)W>^O^S+a!TV!MMfjO zW(+jaa#=h2=h*G@csRCKJ+{=tFX`L+SY3jA7_c>t%Sp%nUBJc-jZ6SfU90^r{GG9{ z6lpO{_QV{4)4MECiIoj%&i#TF-Pycx##^e>ydzLq?6>!)O>;>V;G!BRlPM48TaeHB zjNXbMTc-f{G2IlZ|nvjruhf=B&-Zsm&?wx8EPW?HhbE z+{GbG{D%4C8|ltB3yG(%2y7|DpHb2XQmYBlIR&A0*}7f}egJmIoL>+q+p+I_9Iv(u zbPlGNvYV^c2~)QRlBS*?g~bU7V^E1A$L-~J>^~8F7VQerxC+Uv6S)r{HoOv1n^`-qf)R(}yH8>12 z#(Bu(b$FL^^p5icL^9#RIlf9VCdg%>E}YBpP2F|)TAvHCx1sC|m3W|QZX#77ire8_ z#PP17&WyAUJ|JYeH3F5|D>nmN;GNDrRMCCO-hDOB-KgAsXvZB@lHMsFXnTDRF(YJFe%(tim2a4DgP8tQJFk^F9sV4CReirWn)JRm@ER(*sQ` zm8dtnODrdmIjRW@x`a9Zp10r&wt7_`IVGQVWQ&#>AF2AdZe-t=*KtGazKS;%RM#9T zM5^=>stj{b-}iIzW-t6!#r*WqxY?ckxPtw72+{bQ(F9P{g=hgv>n|Sc532T;p7ZZK z^;aO|Q!;s1pV>j4 zIiTV>Ung_^2+HPq?x_y$e-W(A^kSqMtnCwAb^|ub3buV}Uqxph1?-Lyg(Nr&^H!xK zndpL(LQ+sapNKkSIj8o`e=gw!{Rno{qZC!K2N}(Rpj4zKw4qzSl1l!Zqn9F zrI^QHitYK2FBj2Y2*twM`_cy_^j)sf18c)TLC(XdE-w|s-?E3#a=L`iW~5AIu&TN& zsY5dpX;4;(($O0-&8y%lSY2_=C~(Ui3!`ap%IisN9U?{U*rq z?^g9aDQ4{->Ww*aUo6{K zbKL8EKB_o@P1ffUadw&ogne_&Wr_DKQc>Ge2|(x6D2&%C9E0ZCpq<$_`9YP@wKSq(0nSS zE^SouyV(`!N0R8kI7qlH6H%+2uL6!vFCDnGKT1yjRhUl7?u>(xag65NtL{w5lW~O> zPBY`o!Jauo7#>BFNw4UFXqHKvQbEySfV^1oF6GTD8|l3|S26a=A_A)X*(~nHN;zsb zHKE8ix0Pzt*}~FQ;0TP5ic6 zkEBLFC0g<}`Vb+{gd|V7p+*rLa~c%GfW}19{efvO@AfJW5?D)Qmk+F3Q5$%_>hu<< zXYt2~vvI9!!1oagiBpd)06xmdqCvdSef>1+wE}!qL+aI&Apw<;uzg789cL7}S`2qW zoRn1p$SMh32$n)ib>&H?x6U-P&XxkoM@9Kkn2-geqK2Zev7)*2qVijfiiLonJ)~+d ze=P{7zNomd2)B8^xQ)0ZQL?1ltc2R91f{BEaKB__5FVIE>O~6n?F0KmN_R0*mcT;Q z{X**iu)Px6T1ffnK$Jw73g%2zyed0eXjSk1d}Rj8L4}HbodqF=rI`|lA!(B?&^fA# zJb6#j{>+^WV+;Y)t(}m;*{!ynm^X~v{Rg46evo*^3&jlT`>;2S65(ALQLF~0J+He~s;-C%(!j zbxp5tZh0D-weIeiZ)pcRg1^5#E37GXs zB|fol>lIAv)9=}XirBM;>OuSUVR#J?-Ue%x27MQ3gHwFNPEA9_WJA(vLppBbFZRY@ zmBvoH#@mF(hR~wsgT^GJrny&5ofw*0oW;6HO=smzLyJwtznjJmim{oREoe(-NS@6# zK3gEcTPiMDJt*1G8e!rnm3(bCS53H6Vn#RI0& zU+L)g_qF%XcHp~pkhyidWstnrFqn}De{iW_BCB9=pG-$YAZVU^*7QW6DdHz#7jH>~ znD&$y-&eI~GG8|;<=G>}w5op3b&XtfId@bkT0m))hiFw9=+slY`)j+?C%SbpJ-%qq zxEaCeru3LK&sZ$a^i}j&$atc##n_Z6*tySAxqPx}eDB=Ut6^5_QBvzI6YFo$2UJr- zQoa3(`@+KOBKTOb>govk>O_CmCA-gqhx${rRWg?5Em#IJWe5BX27>(t3QGo3I|o>I z2b_@xU8n|Q1P7J$25Z9x{qhFeI|r-R1|yJ$TFV=oNCLXUS&X9XBgS!1#fGw?4^QPQFQ#A?M{|freBO6 zEe2omt}e5+{?u&UbuHTmwce6^zSkOq(}jM<;v>bDNz139e0RI;yWbvh^_^yw`#=(WRNVN@_uSG-T4xGl`!QoHrvA zRkxQ5NuS^SPB7VSNnoE>insYdpA~vP=$%h1dt5WMazglgOp9_#>HNUuA**|<<;!?`Fv$B>R zTuGO5e%Ny1aUA?HM0z&m*0S|a)9T?sYdYcDMY;(3(f2FewUL{#yW=r53sGY=(6i<5 zGs*DA{+p=Qp%|xdge#{`P7`G06E7B>UNxnk5^Yd=Y|xB^UGHtMVNEiTZZZf>vg)2K z1!tmVoYn14vfXt)m8yIvKPAF{&KlWOm)OO5GWEG*Yj|r*p1fNP3rR5oQEPZwr?gwE z->X5}7WXEWBiq{uJGw7Fx$^C(qJMCasm1c!G5Nm3 zCOM~1ziV|;>-)AYta;b|rA4#Ye0*4(lb5n2*Pdr2TRi!-zTY0ODCTW&?Krs?c)pi~ z-H_A5m1nhI0I1?EYQ^ss%O3X2t6+Ypi(du$LP7ms%bUQePYn4A~6b+l>5K z8cRDYsXiQcTOQ%p8nbGicvxQ3IdXPB%1%D&_*}Z{QF=&v+-I$`*>eBuPwDQ%{oOsm z?NCZ%z3|Td=*OwmqubTrD}OX-PJvqt1cA1%7otcfC(t52`ql>l0@D2&wvUj{{U}p+FVE*FQJ_6!I=KJS-$EFdPIR+n5Nje?nS%#$RHa%|`86 z^mlmd$G;rg=9bpSd~IiUcUN!U;6Tst$XIXx=;QF%`~vU?0ubA7q=n5@wBenFz0rf+ zW0X@EvHg822UBdX4IZG-OjJ@JiXcddibt;#%6UO94hVP_wV7cCm1ax9oFkuL3oQQVa`7`J3u%bfxNKcu>_W& zwkD!qKSwe-La~qPFLoy(O2xW=hsO-8Jx{@xri+z!L7Cxhe}~6jzPso6wb|o>qt=pg zWBU^)Q~Y1UW6gJt+&FEaIP#uNH)p$}#q#n6&39J-vCRM!Tld%Yr?8Bz7ZiGjMBDW@ zV~ebx1?-NoL-g?fvpcpP@B$$dwmY`_ItbqXad*rlJ47`XvH<|wzKv%<#TEdzGZHz^ z9)T^V+&Zv3hP;=9^tWP5zSjvv5uh-~mOrE?PFb$7H(p&or0uU`tBdgZad>Py*$6)i zh$7U~8xa5*+k#Zbss6vjHr<7J4VJN`hh!Q*H#5oNqx|dGn&jw<&==-9DDQXYB^iO~ zUZgq#8QWC;*D%GFejf*t4~rty4A4J)B(^_bA}|m|I4Hw=j3OWd#I|MR3qWj%N!lM3 z+Y0f=jIGq$?nh!<{oMZG=rLnkw-q?p{-52kgLjRx|68%$F1BvQJ$-B4`U_!6q!kgz z;zK(w<$vvtJ(t%O?H~|_MgbXH^TS`=ue|QRy`W6AIP0hVJ3MxHHu%9GfSv0l#^Ly!=aTL0O^Uhzz)@hY`>9qat?ih^NZahX2!f+Jpwqo#fZ(jR-wgMDe zg9xsl8OHBicXR!$Zg&GoZEq=yYFp3_B1F#m4$E50`VZ@rIzo<<)<*h|^B)ykg7;FG zPS8@=?iirh)*cEDv-Zop!D5-y0;ui0INr$BTF`qyvGsx~jW8WqOv>F3l)o3`-m5hj zy}#(~9Q|_(m)rXB9C+H|kJ&K*UZi6D)-Oj55L-NLPE)Ba(DdxR+~SoFBG3c24*T4jvNeeTd_WEGhAtb2kdJBMR6ZlR)>_jgCTW z3!#?m$E)9sNs@^U2P(G2zjkA}pFv}2ed2&BLX5;GsXY2DMiQk=POeXjUW60Ei;=2_jcUxL)ME3MU#7+ph!c?hd<@Y4v%{`X`e;wO3p3iKop&Hh8I3&L@Ecs5w zHUGfpdO?sf%~1L@pES&%qAv9z7~i!m%&_}1xb!1A4KA*1Q2K=&iQ+0qENu{9!HBJG zVq@G3ZZ!teZ=sq-w4M8kiGf^0WsbGQI^^3_!TgBUxO8~BZ@^c<>!KTmQwLpC=|&;P zd5^%B{!)xh{kg2?c`*soty9heYIHxIVx&2xn0Bq;D9ZPcj-?&42`82OP z+%F7Xu??*Y0e~qO^V=J7nGHGqi>csydo${dJ=Y8;X7cfERTiFX zRWir?_?n|d@04&9tYJxG1gp5&;|x72VZN=2nO?ecTzp3u)ZHa0r@v(+^1$ewJo!MR1J9U3%q z@Ex0euY|*?Yhy9T{%Vszwrhvd@#2Bs%ss&)JG}0Xgqy%5GGg_;5+j@jPunch4tK1nKdMN@pc@!#)Vn_ z^%|wQqo3_S#g;rnaAEnF_@R77IIQp4U2_*L_B{y2T9SZ-AKDXqwG}3yvH5A^`WOD( zk1dUP1J-+WX`vDKXpTr}${of2Cc}!@G}50Fccufu6&3rh1Aa=Fx(tH%&)8Z^WSJHp zQobVZB##djv)$>YS@O@MtkM~~Ow^}4%RQvs47u~8+}@1UCVs>SR}g-AF@|bT1tYfN zpPx^VUrpTH5Hq%i+F^5O5PLN; zhpiGv!=+afKF5KK4oHmvG{@9d-d)iNlDYgEi~e8z_u)tAEAGMmK` zxWipe@U3D|`}Wo9U6PfX15euf#JtPLj7GwW zRl&MthdH)#64)}k{29|W7~%ol<=D??fTZa+d=6xQ(h~RLlF|s0s|mg`MyBAfrK%02 z^3l@twtY(wWNU)Qh~n=FXUCBkiV2~Mt8U)-G}ywt+No;%Zu0d6Kmpp$dRRoI6L=df94 zAp{prc9*$6%6Ma!!~&G$0+&>R2>lJ03>2uVy*^FOtYN;IE5r%8_$mT4;aX-)S6)k3 zfkI!EC|g?_Ss3Hi;Pe)l8EfT;YJCO+xTA{hzwF&Fa^0~*6K>#b8PXNc1G8TJPP z;uCoNFnIvfte$(p1(bBQS$?k)FaGvnt}#OvEW_v;&H7OTzELCDQPUk! zi)T^H-0z-geDpqZV9(F>Cg0|k!^a@r zUbA2zFh2N+Wv;O5=ife*5KH}JZeOVcdWdg%r*C~{LgHA0lY^h@PY63<;el#moMxi! zSll-N3W7O=cCE$gFg-%7(;N7FO_TCnflF2!%mV(SSevp2{%ITRP&&=gm8Dy_%2WeP6WC=F0gnFE*d<)*~c zr7UuX$f$+1p+OzGlSR@9KX>(q^w*ai-iq{n0%`e!&NS1$6Y9;od|#{wEup2~(}!-} ze7AB+M=*c6xAzk1t;Eq@`bo0H*?jpkp^Rw5jKSax#{7)Yz6_p?jE@MJ@bsCn;+f0N znW*5*)Y{C(sZ1LRS6pJ5XXsy_Yi1QYWf2u+k>1jg-)6mXb)%q{gVV^S24y1_W*>EB zpKfJOBIGPE=SbZ#vM*Ha$K)tzDfp^-pndh2L&+5e1COcPRgRdA+FStGzOD3RxbaNi z_WZyV%N&x&wwGshP{X5j(X0#9!ua}% z)3Kp0ECuT0QB>f%?^DQ<;7woeW#${l12L+v4*(}Ha~3vkLXyWIxr=J?t_=`rv_#js zlEsE98|xJ%{|u0ZcyLjTTcg6RO>t4%LIo_CYBtkxfCV5WqYceVi_I&GAIFP?#;1j5G+W;1mhKh@uS^Hm-w;Fw>-sa5 zZ4?nHJC!98IvjypZ{0{#FH(nz(zFms&$-(!q#O;@$QJ6!e$0KxToQx3Yja>Nf5!U~ zrTFEG)R$<|5*UN!*azjf7?RJ5!=9%|;-@$hl1LHXy&*N1BES0)ua-%{BTcDQL48L} zy9h<1Z>(^esOY_@_+b8(Svrzn-0wr65Tay;PN`dDXaY)n!$c z^g)&85d5dbZcoQ(qMIC&!fHd_T9ody>QpPhM-#OoH#UzI59L1sd#v+{f4lm2DRzBDAN9M_I};|f`mh^L|)%`X$UQ( zo@%Z>&@~|g!-|E_FP+3HZA>jcrJ-bKfK9M2oOCc~vCx+en0jlJ2ySd>8f>z_3Z8FN zamMP<66i|7sda5aiEhIB(S$eNG=gC}cK39Gr$OEhcEt6m%sDYW~!QV3}4D z{2j&J@ou3FeOV88Y3v(EJMJ<$K~uU{T)SUYJH|vi*?oKD^A3NGjwI!dV5bhQm=3_B zm7M5^L8(Y2=&WGvOi}A(53ArR>6Gv3^xNnZaQ}M7S@~PNE6uh`BDG7urVH?B>(9EL z&{Zi8F(_Lwstz%#msDvTR_VG=PjFOUFng%-^gL1O(OZr-#`M%p`DEcf^K&-F(7Z;8 zThSE5OCl!^GE?KJJzIib%R?9EAk8k|;O!_~%Olx`!O7wFwyvCEFgQH1j~dz^#@O%N zz^OA|khByJW=QyK+Mm9pn%Y?Z^`@Sw4-$HtaA?$!l`@duG*Ftl(BX$3vb>N?&lgVB z_-DJ&YtK4wVX)4!sHj1sB@9bxw^5Zgpp<^7lUJa738yD?NFj4*aA;`ce(1-G;c=ef zT9x5h_vPnt!+dqaYXBhnvkajd*&xC9<XxU3$nOCu|>tAvE)zZ>$e?~g`dr2hY zOX^+f>iuEs@LuXze=7W8>JvuCnfkPAv$ji68(Q-i<^$Q*-q;KLaa@n~Cqm=+7UQo1 z$JH~($%n?tH^%)?CK4$pn8YUd^e2?OC+JEixO*l9wkLidPKr`bn%P1-Im05@OKCWD zWVo9r2cLIMuy%=HPAR{dDiE6bVl-7QlucDM)!I8HO9n5m)BTAN2>`e%mO1LpKedK) zrkzZPLp;9lZHKYXn99VMq-`^7_E=!|DlE*{-_NLOn%S22+F8yzujF~^usidx1@iU< zFYP!Mvm?~?m3iz6CLx43?}k~;dxHC8bmmPQ>NA%5^&}xF%k@7heKXw_T#*usQXv^- z3%R<9eSW);hq#V5>mfnRiX-)^aIET-#j1BUjf~hq8cA)^0f1uL>oL?fv?S3sG<-NT ziqSk}sWlb4JoKQ|kG?WSel+1}w}GX@V@$9^mf{atS&9%oyo0W+poeT=mqjzRUg(tl zwp`8ml9~otJw6UWz-$AQ{wEI(7vMD{kF@2GF|3snE5vmi^7d!^?Rc{5gb}ZZTh>Y6 zWspCtzZ%h}SfQZAHlQv;q)p$TPd8u~F?df}@!^4rSgABDJ6bm70;h6;Gdc!Kh=k)Z_aYmQalV>E?$}DifYc7 zm24||nVQS?nvm=`xcAyO|8`mV%@Hu`#<*L7f2q%s&!24Wv&h=QzH0zxWwe&W$yg_BKE+%;eRXyk|NPf8fnUtX zs8X;ff|L?0iV%zsD7Mit(fsiVi9i$~*(5DJ%{41K8#OP#08nfNOG?YWm;Wdig+&pn zbs8F*njBkY9(Tt&F(0D{L&l?H&{4ie$98U3e{pHaVO1A!Y&Vs+cXs!-Y+9Q0`+92t-W%OipK^n)NRq2~87|vRSQKGpsQxjE z5Y+Ozfn{&vC2zrqd&95&$?q(=y5U@G7PA%5Z`bpGhsR)5gr>S*k5z<`Ccv>BB&fO; zY;O4d7)2QQ>)0AQeMxI_I-ed-QOjs?ciTT$AIx|O6$Uc4KQ~9^TLhrc2PD)rZ}^6> zRi8_=;7lJh_P#YgZ2r1TpXXvpnf@=N2ww*P#P&ZK+XNGeV5TIv<$o!*joq)j;ohw| zZ$@zK*X2YCAfx3*aa?jzK1LB9Gq$k`Vz7)Yx`KBM+F{bqa4jpM+(Z$_{w?@_q6m`t zcosE46u~0m^-ijt(BtlyDa|wYOQ2%wuKOBLZ1L$KPhpB}HZ%mhzMB(44P@>3lb3h^@o(S=|B6GeC=w)-~fINgD!z%xOC^ zO_&WT#>=7dmM1I>zdE18JllU|Y=iE9J)w}6sp!XyEwM#?n=^Da__i1Ge294#h$668 z-nWf#cQ#cH2*7~t$0s@$;}SHbkHEHS(w-Oh_mrZV?C)u)Dln`xqdB?$dsZ)q@iAk2 zIVUt0eYs#(3lLkIO2%4T`&rAYW#`rK?#C#?iU#7}D8lu6FbQ_sUt$}M@}DR|qSj*+ z;n-zI`k&!3*S)}8In*~LZ<+fK%6TgK539`2`e|~u$_9>`5-A2x+IoElPiq0i_Fe1T zm!Y#EmhqwUF&aEs)_G-XKK5lps4Ur*{rd>+wVWrT*T-uH4>woWIi3P=FShtUVt2o9 z6~>zu5Er}td@=q&9=`>Zcn^yrKw?q}PrXq~BtPNzwIOql(FsUODZN5%FJS#jr_-N_ z%+c45Ef>IG1VwwTF(D*Wor(1RF=NY_*oJEK-rHsUGd2q$G4pmHs1VbTy0ddYJwGT9 zEgLsTqKm>TpG~4m7Fp9Td8R9nT`F$)nYmrcu;3>U_@>RWED4@?Xg^dBGl#HOLTpt+ zoY&+Z#kPS)VBrgn;}+*j&W>*a5A|<6E+M_w*WUyY(Q|!Kb2Ei>fhdC1md^*nENq=! z;Yi+b3Mxq;V|x}8C-aGjqyJH{?U?t8_GFb(Jll;ErBI}cuNt7QKZ`F9%VWr~&!e24 zkgAM(mgG-K{cc%8whhxLc}+xyV|*{kRf;+tu3JWcXg}FsKaQ0EiB3Xe9~^fU2W79_ zD^v*CS6Ra>;Os>kQTI6$r4CNup6wrbbZo;4cy}b_`SoDL7QecoTHfyFTpNlBOpHm5 z`4V4b?hmLnJSYC(f^?V#cb?cm-S7c~Uh)M$c24wl&v=XrKy0x9p%ToTSbdmF%tIt) z-J=MuugYWilRRof&kCNnFcEPB1H^VR{W#8Ca2l-OhdxzF^cy0DDzOlt(vmz7@4a*JUV3m}CRcz&c1+&ht;x}G*-&aRRip}RJ z)+kC8H~osX1$M^(#a6L_D#7_CN9SFC-xpBKhs4x;s6O{ilD%SnT#DpZ6HOPeI=c|t z%Yfl`cIShiFR3A7q9d>|l9g*#ph6Xrv9#_x zcgi;dK(QT_vK%Y@y1X{v2z;@J5!+6x51#$?Sk{o`V`ge* zLCo8){^Tp?#D8|Tzh=9U#Omhv&hDKx%S^tnB)&Eh3sui;n5iZ2rgHr@tcTM$r*pB2 zkn-oyL|~M(UFjtcds2t>?B?Pd2B-V`Pf^aT<*ylevxGdaPr`;2C`DPXTVvI`gXNnx z4D|edz%sUK5wt2qxx^{V@k#PA(e{{IBW@4pnHhPBQ4HSWH1mm{Z=c4h3CPgk;SD&% z*fJL`$-EV28Jt|Q&24a({czWk0@bHx0SC#u+ZJ)1wMiDFC63;2^FVLLyzJ7?OBngw ziZeV%_%mxocaPnmcY(TU!kgW@zI3Hxpy=E;lkquk*%)ur}rcN}qQtyU+7r_O2Oa0#1$|Ba1#Gm7zp#fYP*rUB0_-Oo{K#qn=ib297%oPy4fbpR8az-(_(t^c+nvF; zhuCi>w1T9yfvAYKR;WlW-7@gb(V6L&=pW@mk23^kPRC}ToouH^27~GdR@z|T+2C-D>&S$P-tte zWa?;S8;p@*gf=lUnZii(m3#M9BwQhVFG~0Tfd{fn6l!u5IvTJtChvy)Zh;_r@d^fP zeR~v66rr9wwb6)nCcCws`vfsZ;-3T+CMmUfGT;wQ9<%mEL5SmwxDv3kF)co zh4^X{aWl;MzNBr^_fOkK)Za>~#zdAVoj}TtrIbP8^b#aKlRG+{8nzcM3 z_9xl^rE6?elK}Ny9Q4`%g!KTB3$C8TQ~ltlhSyJx)SsEECo{GOCWYWx*CmtFe5B}o z-uyMFBQGdd1FY5_^!2G-5uKgy9N1SPc-kR&ku8P2E4YTvUIaxXQaz+;J|*K@h$4!E z_!g9C4+*5cC32YOklN=^=|l3FAbgA{?Q8CnGWE0>B0aPoM~4eg1)-Bet$5>g+D3h7 z{amPP?-%#0P&eZ+pIN6jiq1oX8E1vgBeZFkE*bi{@N>Z~DM3=g9WJah;RxKB{FmWU z6owLF5#sq&^4XcK_7O4(5jGVOfFSL17I8`#8NeJFrWko;LU&7;4M1CXjcoWrxXbz| z`i5+Vh3t1l3|NvLvjy@qG|}wz@9>jzxWUmIwF=KfJs%W3?_~O=oe?SU@o(#Y`UN<#|2eU zxZzMDDhO7J9|??iEQ+6=iPyP_55P^(=SnD7N?>+Q;D98U_a_`|Cv-naY{0d)tLJqn zRCfwVyvpz27Z=IRLt6* zT-BiU@mF$|hHZ{1xXBC**|YT|v@7E(8AnQa=Wq9;Ft}>ouGTbVH9jQ@Rkww!w7Jl} z9gSF9gjmT*G&89*olq3q=OCpFy4EP$MkiyoN!xD#7Ox$xuF9%tLouko1F4GN++Ug` z(r?Vt@6lhsb_^rWm*{W~>v47_R4qSGE=Rw6&EQyueOEs81CE*9Ai35+aRQow2>wBQ z;DT(HDYWrJW+O9ymQoBk>nVL!PgMlIYZl?Y3^B1RX%Q{JYUiJ4-*9GAgDYvk+3y!B z`R^(P-J+OWt+Ub?6 zYNh~UR?)0cZHTQ1%tH*WF~!KYI><91u6^p9Z|}x#e#`EJp<=n8Z|$mLdt2)#T=4m8 zfqF>6RDOYWe?jqPK?oeghaR#n2H7@(H2Xn9iXioE5S=whq$XxGF<-1yVbs?`xw%B$ zsKSlP!lSXm^xHxxZc(;WQQkrl1PpMhrzPlu-*1a578*$virciH&uwXKpBsMcDSqAz zZpynUep3ae7AYA!&@ML(uF%jK1P9Mm2Lon$16t`65Jeayn&Bq?Y$+JFqGW# zsVY?m@y97iYum@PL(SI9L9%(t?uKowGa79cKfvIWuX+oOHq60y%LOQU54#Vwj zqYUFB&3lYWrchcI>B>a?%GRJt?z_&;pzMiygpXQXV(wiMhjM`J%n7QJORbV2>3&Y+ zNw^m+I1s%(YjUDiE#jIhb=yrlU#-7XeZx`1M3?u4q(;viT4UiJ`@}iVVlkHQrpEq0 z*4C|8Sf$oghTWx+-J^uv?X8N(L9I7No$rB)zgv8un`&^eFNg;fh*L!Hphc0?Zv`gA z4e}%uTP3B`hYi%HrKo2tVrIQPeR z@J_r)hiQv!oJ0P2NOhLT68DID+(=b4@s?}*sdm|(YwLyf=uK$rWl`%=f9sW*6MRYN zs!Q8m@)yMAFG!5e2s~jvy>0M!-|_CpaKkC+pN&30f|gTz8_W<=k>9sdERB<6xnhGm zUWdCD*1ln2ka@R6{hYYdiMf+iyEDkPle5H)o0pDvsk0rWi`&vjh%`+os!Nb;N{DZ2 zqM~a?(Sv0{UcPAxm#$mx$RiNn6YWK{dQ-Fp@3b~%%#ra2J#8kUoa(16J^H0FU&FlK zyYxIb)tIHR6a~g=-_D>WnMttpI%v;w2lP5yvbidW^@H`WUg4s?AO7*!g`*XGL|7F@m!ThlVV* zhYp*(2!|&;2o~9be`qYvxDRt8+Aommt{e=nS%zf7r?wTg^zPY9BBpj|h;BDIjB1RZ zVufF5jb46{O1A!- zcl?*m`dBgok&erY;`WlQjK_?vA^oAtn{Y!KG8sBD8v4Nrg|!JEgh{nmlPt|&*_t~! z$c(s}C%MVxKIvuH3r-1=ZwWnAig_?@+U7{SQ;=`o@}ZvQH|v&@o)&hUR!X1N;f;w$ zo-qJ`t=5bYW9-c=vl4xcC8@VHskd1QblZxr7nrxQ@-#OD&x-ZWy50BMpU--d&H<~o z>I!p#?sJi`bCh*+U#I8hF6V-9=VN8(<8^ovOL>yh&{K}o()iTD7z5cyytzl1SB?vj z@e9Sn3&r;f^0rKAv z%Wvs_%oXTq8B9K}RK9CBy<2&{>-u8PgKe)>X)hyuFS{A|IG~>HIdGpa0G(L?)aCpY z4G4B)P4j;4^nUf-J`kFyNDr)vNUq@@`eyRHuW6}8_m=2lsiQ@^yXAH&l%UU5hbO2x zu>EkpDW&H9QJuW*erf7-8MO4k%|S-_^I_?TMnMRM;AtO@!B5ZQp;6FPGua{b_e;&t zo5SOomuu&`CkxgmH&$z)+>=;kXAEq8xX%x0Z%_L(9vG=nNZqBl6T&%aPO$}`87RM0 ze1E-3hhl&!wGdEIV8k{s$X5;&8Ws*Rh>DI@01Vs2I08qMPSj#gg%YV5soD1@FcB=H_^<0(MJ5Ym(#|aCRrV)}Re>l%QT4%-GQIDf)$}u_ z^FKaM7QJZvUt(*e#f@{iKRoF4eYM3KijFN)Q2w9Yv0wVH?O#bp$hcJC4#u-cw>%Qt z^dG^nD8eqo|0uSl@O|mP?wI8QyzK!jV{5&t>I(z5oWH1G8QYO2E;}k%6am`<1Ov8O zwQY~Uw)Kwi@9x-Wj>f2GbNbck`kSQ3itVM(Kf7blhZnEc0LPY7j{wNnX8Jm^_I3F^ zI<`-l_10m-V_AX5_Pbw#`2KNh^+WV?fzx=0s@?9;4?To$UOZ-OS^2YIQ3S{)jvz7} zkg>&=qLgbD1z$9I*_q-CHkAOO%l(A?T!`Ebw6foQ=U(m?!b1( zcGBIq``clPEsWTj(Pqj1qu2sb1TjFd#bwYm#fvurnP!6>(cAy4Vq0WZq~g9nkNCZ3 zpT4B3#>~95S~csxfvvO!auY=(w78;wA9PqbBBq5@H6>?mSxv-Sd{n(?#8XY6mE`q$~s6cbFHWA~=@zMuYNnkZiRCv{UE$=Hy3B4Z!b(D zo13~sYoq@lHHxBO-XUao*V&vI3) z{KMiZG)AZmffyjRBIwFZ%<;&~xC}U9uMlZW@M}_k`kIV`keEyoA2YV@gL-0wNwAD< z#NUkVP+b%=I3(+8SM7=FOkr|3e5U%h3KdR1xA*uyjyL1YOAdQsLpd!*B0@9(<-5t{1-CaX> zcQbT%cXx+$!+aagIro0|Pt5GS_IlS7&TRR4>-! zTIb)ESK)D)Nhk7HXgrICjG&+u5r zT{?n4r^;HS5!=9rsr-K(+X6;L>xd2`Irts+V#X3{4Q{yo?g9>xs^g+Ev4g{DqlOv+ zXuIOsWED3dc`(8VZW~*Q+I9boZc=NWrSZEf1hLr{#a5z7Yo@%Z`-z_f!Qt?Rl90zY z?{5W=vAyLxYmWBUai!2iHjuFVb`PqlVlPLAoZ+^@fv>8|LW-qu@UQ`NT*H>024^SM zwtO~C-}+-fjt#Hgs5OwoYar1uA$~~s^ZU|fRp>uZC!eoj=O;@OmYZj z52xCPgljfQ@jqCZy=t^z+@O=U7`QtPKR#9<2A`5;x}JM=Kc!fNKrwm}E+GkV5Y+M6 zi<|pi?2>)sm<@ARi6BK)6c$jjkHB-y@+G0^L&x%njIGL|1Qc6IU*u@&ciDkq8vQt> zXI-DJu;}&0Hx%a2y4iAc8Exvd)$Yc7QfPC+{lqsl-ktYWYUM;)eI26YyzOf**sjR3 z8KSkDNRU6)W2+68w6bMaS?Al~>=EB)DwR&T+T3YmS{-rB7E?FXvufGo(&t!l*Ra0Q zZ+(R@%X1GXwk6$sAG`GeAOz1Q(pe&Ll13@d9EJFDFoNoopQI6mV zIWZ+MArzK)xuHqrFJC35^d?fkcT;8Cds46fv0VV?aVn@tztyi(`(idDhgS2PvF+Am zEa;g|l!wLzmzYUfq@Wg7Nw7{&#Mr#i*Hu;0teu{#pRzS~@lmmnpRt7fTjFq32%agP zX;}tq28Gl_>t%y&}HzJ)bX%cLPzbxl{GpAkeq!}d6 z5P6}G0bn~)*X^OTP_$U%p>TWC<058>_H^ahwx!YUm1wyML=iszVYJd`Jl~yv*bc~N z)YIv;I=p*;_|A8w+xZ&1)BT-cLqA+aF4k^5!Hmm%XP`Nlhu5|$0cp$>WZq>&%6Y0dYy zqhUN92*tbm%8FN-?k$ z)I+ihA)(bz*CUXMDc(CMJa?FQw9mY32)#05@a)aoKz+@m>&pE#9PTQJlhnvpVn5K-HR-BtwW0~oFGTYQMqqj%3%ZA_UHe+J*>LZ1L^+yvk|HDz| z#r2}t-r{(}t#Kos{t?{$1M}Tnw9b30L-9b{9LK}_n8F8L-sk#@#g_=5H#16vGd^lJ zKEKv@>%aOE*Yf`SWoaOc)A&J!no7lJ*VpRT_fM>T)=0Qtg{=mp0)@zwnj6y`cQUd)Z~_|c8tI6zF69^McM^++BM?6cfGcgdSmY?WZ!B3 z0Z?oG?I;7OM1$o;!>)t#-#d)oh{no?#MWvj=8A!?wUc+m(yv2Sg~c=dbj0LBi|j&o zXX(4v9c8W@r(m2`vBQ*c^e*xkF7uq4+4rI8l57c=L_j-P3AxIz0xY8iIsd+^j zOc>qHxG}LuF&nbboP@K1qTF+!Lt#x&^JL!QMf0&o|Ni0e(??bq*;G`7Js}g~G2ZPF zy6QoK+-*L%p{{ zLc8`7p3WLu8k`dC1{+;&Tv}dS=qs?}Z-lT?AzgWdFh$BR9MQ0PL_K_P7}0z>46+o& zKHLl;!`j!mM?btXF5}*s(Q(^Z|2E?j2kWGM1hZ0RV7CjN?3cGbzoK$7N!VSN5wqUY zM5f6_{y;IJuaCSzWcjQsEqdo#j1Z+uk^NOMTP}fx6+cr6oNZMJg^0(7e#53I8m*(0 zqesg=R1+PVDLb&unr7vZu@S8S9}_|v19;JL_?!wNoJs*GKzg|GJcb@GR!1>U8yWU9 z80}AeUhsTgD2lg5A9wiIeAr)cu||rHpnUs1Z)ZjGU%lpMl@N0|wgSKUcqM}Z*v)w0 z@V@#3w%)Eq%pPw%dm$*`dol>8R_Qyq-#25f(8?eoTQMP@y@+Ab%FUq2<0c^uGqFM> zakzk>hDM;S&mU~4)`%R?%ud`2B5r3->I|^y-U|R`#s=_hhx!CZ0!a0#k}U<2k@b>i zknQH`lNa}rSz%JvXi}VoQlhYfcLGxO6@w4=M2_)APwFYpXs9mh%j`T;(dnq~@yj`` zsGpG25~2`lzzLkBZ-u?d`TX~Xc8BnkQ}u6ENu5mw%HN}g3Y zKg~*Zvu40XL6fy+1HcvqD*}%qf<>uH5S57y{Fz`5Vu0Hh5iRJ-N5ITUQO&PZEoAgt zQakdzCrboeEzw`C2OA|O3TT`)dSWc3P*uP)3t|+^D8R(vpaX!1`|t;Tx&3rtz&LXcrK8u$R5otd~N1Vkmspn=53T0+hB(BI@9wqFKMAZ z<-UFrEC0znKg&2y1W=Y5yj?^v-R8jVit%N}@p+B~inCb7T|Pw#4Z#7*;d2eKG@wY4 zLaa_uQx{G>7?eum*9>k1rj%OeRXPcp0>=`3zBl!wBn~+%hWJaU|WFhrj~^V_54Y_Hd=AcN*tPL5q9vR|V2V31 zum$)2>8=zQ7&}yauGbnymgRPqy}B>M8-#w-&=wUL5??FUgxwyWQT|>$ji^u@WnP@T zp!-2#pn-fh##kIX8V^G-VhK@V7%GRE+UaF5LZ^BJ#q&OQgEcHG@UqUnX z*GLX#>zY^n=ITPrb`cgc}eatxLpm<7dQVQ)Bkf zZCnW}#nmHe0>kUj6LOwy-_Qdnwg&U8hV$&^cWhqD96rW%@BHfm3hPo^>p~9d{=nBq zD5FM+)$iKY#}CRQzs^L30;fDc`qGH{cSymO?D>(p;Jl>Q`3?QhJ^2`GinwcFhR*}# z$^**w7LQ*VzzqYTa~2VbZ_8*4n>j739W4#;a2RR}6K`?)2O5V>a7PXrnW>s4o$;of zhGy>Z=Qs%#2AYvI`-_O?Lc^VXga0){M@K6FC{*eN)SQ9zqJ#BK{<^5aa|in zs*g3JSAIi)yOYP|BTGp*YoY#0#;M zt}}5RFmZ61@hoC<<>qidg7Yiv^$CFsedrA>oQ)WmwUMolc-$Qv?PLSR#;fkdy6$o0 z&4vAl`=I~r4i+JhQ3$rgdi z%aF=qGfzS<@u5Td;=s~kqUK@5>0&zO(!^2Glqum%2vD*mT1Zw~Du!D@TV7*O-%wRQ zqAS^PA=z6}KVZrC66*?OtGnHRKw_Uj{UV&X&kvds{dbbM87!1#2kBB~oGOYFL zc=Zx_4U=aLVP)*?vKUE7IUz8M;+uwOG)_yjj{R2$OKF`xWSvRXiFs)KU1`UscV|t0 zdi&lRUqU-S5d5^vIor~jGMyym}|^K=8JtKA%)_d6Nx z=Pl)z747FgeXC6x0MdVDYPTX}2Q~2DJGl<@XBSe!2HPJ&9lDJzYIl7fhT4yDI~kh> zLx%c?@y8gJhIkT3)CkAa)FwjJriKM(QjQjekCsy2Z4nEu4XbaM32rSf@1n093?IMR zK8DcSL95!`53M|!{w4DLiz>c)&!hE--Ub<7MPob}6+XE(JRuATiG~@+KR!9e5GQ7Y zoQlewUO>bd4;}F#63mUKbm&Ot7q5SI$NnL<6R8-ODNT0Q$73CC zQf{#K_g8xxE2*h1kSC~R+;&$u6yY=%7;?7fD8laQKfo4S&S1?4jproI7u6Ea(~lUv zH{F-Qm3lqkeM0#LimkH53CqV z-)5AgAo5o9Z#j_<#0q-OPt_7Vh8QVPRtY^hG$EfX} zjBUl8#zFB*6ak#E2JDXQlO2|IkZZhTY)vY7ng7`xGp+g|^PI6&TIi}-v|T7BUS%RX zeg?LT^{=vC6x)Sk{F83fKNuI&#(#m`v7l1ChpUA@#86ITC#`T;;$3Y>5P;aWNiiRu zbi8JL=;*|jH#zMBGPa%FM0SUtdmLVucLBuK1laufH;Q1{Z`BD9+s{H8=R<5eCg+%3 z*N5jL++t)GqXM`L%<%s?wm`<#iu7_)M&9%i$k@8rV5!(0{f}a+$^xgBxdbd~JHT6hVI%jCNY>%s?s%(4A1|b{ zem=d@6u{(rGVgtQVvT$uw&EJlVx&#a8Qa&vq#tocv62zD3u@!F5 zQ0bzkiWWhEFXO`*e(xi1NT#4C+)*6A<*V~62z{-czjk)Z&w4HB^(A>cIYRd*U(Mh* zZ}~x#91%=$ZQ_PG!d` ziwIyr&X6=>5=@I83*tlWCs^B!reo5jb=u6t|FHMs*hcAOEB)S!ttrxtw*@k`$CeVU zT+)fYpd5Dm^LV5FD5k&6d3qe@Ah+Mq%(=)=B8uk;k^RvuwIcaH9nKTeIAYkurV1=e z0_AqacM9#hhHZ~g6k5q+x#E6|I1(5u0U6t>iY_S=hlA8bm^k9$AETa3ZK_BTdEm_t zA6VQEzdH0x~?qMcr*KCjAet9?uh$1+FMCI?866&qdIf7`0 z-32F7@sDx@yj~RBY{R2mV0Ub4P;fGX;4<$IY~uVPBz7{ZeaO`0JW(cBbgDop#>|H^ zNe(r)u7r`%;@Pq75tS?VHM7bTE8G*Povto9F3$H#-q)d$2X~{}*$)+}{jm#_+C|55 z`;np{3(eIcN{-!#RYYIaJKN21Ro;^J?rX`;tA5)TVyidQGiTh&@4UmGdNUo@Y!_cc zauk$mwAC|zQ!eNJh=ufYL4^r5eN_V|lV2FAeE|XQ) z-TZZP)@NReC^EP&ch@aY=r4*b1ZIaa1j$vBD2}2Bo^>|FA-K$&N~Py!vM0=`XoTc* zqb9#&eE6ecI0YGq6!Y6zXRLU6p!}egSgb)*Qt)Yz2u(l1gncx}Z{1Lv2MYNs`&eG| zig0a^m)m}?53w+rB z7^rrUK@egsL`6I<>KC0APw6T0EAV%$>E+>cnpn=-j+xAc{czH5~x9{67kc z^i3zTnWm;CeT+&rY^T)jA$K#ic7C zX3PX?Fw1AmobDI;7M5u5Xagjo*B48mew+eJbE_bomXpxh#;8*$0|nd4o8j8#FUFxG zuCXpq7{x8nlJlOa(=OSn#qH`1C%2D($g7f%_{o_t{X4EmFy{Ort^=o`PRrn^goo^}lDTVxI%2FqkQGyVtM z;!ZJ0D>?kXnlHLaCv(kK;G&7}zJDs4t{uKCae6#}lPsG}@93^@>S;4@Gbf@MysBw< zYD6&HIGd2_YHg^h1-;!j6jn9{%7IgeZ0Mw&f<0O0>}rha>}k;pUWe_!o_8 zerEre7Jtywr;QC`Daez1vI0?TW(|@q3fN+bi8+ z7q$`lVdliBq1M{gL_f$dTc+l4S4HL7`QU@g87S5D2|yVPyL`&uRQ*!oGHP2s3Z4&) zg)u5*edX8-Rl0j1AG#1`9oma>xqDW197ped<={DPc31(F%1y{EG* zvIjhJ6F-D&ZJU!`SfM11Yk%95-`oZ;Gw)+yqGT2Cue^Biyf?hKA=7_$KA9uNc_YhX zAo*eBO(_94za?Ad6|&!8t-oQ|DPLw<)O@fYx%L4TTUoOCF;H1iT4UMT`_V>Y%dKHe+hB3lT5<1KePc!VPG!xnkNblP*fSIm(MJ&L zv6f^F2qRNhdTk>U7m&b4pbz{MLEEO`1!k}XW>E)fvD%_e3j&I*(Y0;KP2gL(cOF&m z2q=ZEa_#E;?Eotir6R~#-o6ztxE)X1Ki8fi5~yjCN7M#KB08}7ibnTPfO;Gz6+-xN zAdYEqAtHi~i@iEIGn6X|;)Q-XomAwU4tJ?*{hYwKVTtWdO*>A-Z=6j8 zo$u`Fy6v2Ma}oP%orhS%ht8Zwaa~s4Fizqc%;>w!*&!_AMqIADtl)lH)Bm(l`)RA^ z*X~RNcBbnA71Pm<>xq0MErr{;kQ;}#8?%oaYqi^_dg&+DsP7-#S!mpAY~96W-NCW$ zKd0Pz@uTG~-8=M51Oq&TLD7*`a?ukWgg0yx+tH&qo-+AJWzwEnQ>wkO0%8Q4|i{JK53-9@~9tjgxXE!z;1Y#_QwaD|ez5xNmRxHAg=hI2 z9-|7%bu94g*oe`(&DCW`*=14aoG`mkaq?=&oICnMoDF+^v{9U0U);_) zw>X};`&_=zO}^Akz7MjGAG?nlu=yA7^ERRYD^8i9+#(vku)+w_vMe^pv9N9)mEgkn z-6R$rRRVB*KmH@Za@OycN5bq^tinFkVnv)%{KN|O#P2eR0@jd3_lQJrpFksfKr>C! zGD;Fv8VI8`X;Z0W+p#2bH!07axPUGBxSx0yzjUTP`Sf$pHgw9vSn^tZ>1KUUlfPDD zZwd@&*;`MMEv=tPwtPXd3+7QKZ95D)*gz_}~G@^U4e8f-^y3kh~ zROokUn2r@LOzD#{=|}eInz8Apb?G_d=|yMhz%*PZYX-z1gDNm%C^zG&Gh>0t<)i4& z&!PrjL^BulGuaX{ISW2In%Enri*{Y82>a;nQbU8XG9)j#1MhUf!3(+RB92T^Y7)zy?NlH&8hg_eATz_Lv z^;^!uPq6`)p5B*r?xJ~aV6$W(E0ItiWCUZOm=6%!lo&K%fpNPs&ZFMj4dgA!7N0S1 zj<*BG?D+=B&v48QI6XcE{RNf4%kaYMS6TI~h4nPSPQw48Ca zTo4NG7YHsumrmZ6yrwLDx({3cCEszh-p*@2IJR!=l|s?kZ}+vr-M1bZmYo;|(`W^w zIkj-p;l0u!P_ew$HGo5d`S~`Bc>mNSZ=MJH zg-%RjlFWs)EQykAiIv?#8C=Fv06*s~WZ+wX7f`O+wyZ*lsS+(T5I2rs--nlK`1R}H zleAd1EGmF@(jDV!A^a#CiMlRd7fWk+V1<} z4PgxSyv9iLBT>M4^xg@MN^wSDhq<_XI;E5ZrNRSnjmfth0^S_a230oY;Jtz-!ol_j z%r^M`?j#VZMx$|W&qRkeWFB&tcuYv(as7kd=tw$Qj>?BKSGy|PiZ@pwB2e!g<@r14Uj z_V0otM^~ zgK?dr^i>jvon8oC$K+kojRx3rRk)xoq{=Rp#je<^E{)*o_g}g{^i}IQe=#6pHgaY* z5wH0ZTw|#+Baoe4e^rB2*W*kKiFP6Kuv?Jz@|7IAr9&#sq3{)FttbNizJ$> zhxO7BL5WuF^V{M~;;Iib=ZZN%sWczV2=R){M$1j=2Xd;Sd2x0D-g)=)2hsx-OW@3Y z^FVy%;=qEcsdzHY22$w44x&X8eb`LZMZI`mlN+qQ`@-SH#bIt$g*EI+)S+Ibrb%&r zK(YN6H#FZkv~)PMqSCxAHY}0byz9Iyqhpg$5BIpZylqqn+FPzX9T{pXF=igUAtpv_ zTEWuOgf1FICtgLMPr;PXa=R{VG0=hz8hcfu^@fOyxOgm-YMd;jjgV^`gRuM|f1F5C zhhb=Z0cnD&sGSTolvx!r!4d+`7E%Gk54aw6d5R@?RrUBnXa%_81zjeEkMu;j^~EKm zB$M@jsxpWTcA|((ZD~y*`AjJu{ghStB_G_SCIPR(@L5aMP^alLzi5^Lnj26J#vGkC ze3<_Idd8A_M%HM?XgG=!#A0@wtu{YniEiTd*drt|YwybLi&kg0U+d2m6Fk)G*=%at zWg6+S>s0Moqs@;4%->&AoRn$DQT8SCG7y($Jp~6jwZu?~1%o*py!-zEGR= zt&C8)Wzh$`H1IYT5JBV1=@zRbL9rrxb&QsrWsCTepguIe5#mFuo5m>ytj=M-UbUv_ zM5`GzoVg>ok$%Y1!r;)-!_aD@+PZV|=A*!N$nx@VKmrZ)8TWB-K1{9Xaqst);Zs4l z#4z!pIgRRxlBQ&x?p-=V3iU_yjnAPpUnKRumcX%wZm=)waiZ(i#N4Z%=O#?{Pnc5wl=*x@^Ucyme`#`l3c6Am{eCpY>ulHk z%)tH9hTCRmi{ccYGO$If>OmF>i23vD58rPJzNri*H?}|B4T~rAq$Ko*Vvis4<<1=r zr!0-73{8Z>t+>EXm#D2J9WA_5-+nmiCm~n^4+9z7G(5OO)W_oV<5xJzvm=7X%g3k7 zkL7ivs~)8oLzK*IP( zu?3K|A>m<>5z$exG1f1;W6u@a6h7;$ob0^Z{KDK~J|K!vQCXqz3~Xx@A^#EE zHmDcJwio(&cx-HZTyAQ5W_E5?>>tN=RrJ}h-IRWIZ1-_qGPdVD&%bNHJztzilpo=7xj#8x>j+EraDBYLIX_q#X=#B#pb)4@U0LB2G+am)<4D~Q zr)O4OQOWZ(5YXP$t$Ly{uJ$}%|q{K7c*K1#~9Y%}`TZyMbg1vQbaSOv{ty~8ohX>(7i3t?+k|=RFj-N zy+rehdc6e8ZV~-ti}ideNXnmMpo;LHW4oK~mIJks@h`EZ-3z3t18NMhT8=;z!N}1t zC)tr2L#<2hqXX?%z`$g)6> zJt|0dR5ePj`8+&keDrqF7RcBx61)&w&Jz6HoFKC|hcySs4Too>KosGb*j^i@|84$s zvG%tG3XvWlwzwuIfMR=CiWJ2XoPpvjK!5r#u+=X*eFnCtJ)|#+?RkV(2X&$WUmtz# zU-YKf_}xerdMzhIU6+vu2gWSN}M+|7C2iSM0vMW?S+cQLUTzp?c@J9z=0m zw;Im+?shX$o`-!iTA%TjH1Q*2?{>VMr2kH8TuCpmJ63YHUxZ=VcM#Kwet(cL2@uLF~i`XuNai-{Y<*N2l7 zPd6tQKosEt4*Tc#!!Mgp_lUpVLmsdUb=(9=wpM-#+oo+oAma7`P>6Mrph2DI-7!hm z_SUq?HtN^!At=(6dD!_1uW6NlDncbpEV}CtdVS<{#Z|ucH|^Ps)JYv`a`ADkb+149 z1!!uL1CH%{_~*pFbO8Q=CT>prcwc20$W4HzTepEBAv6Y)e=> zdWZ4oyoWdOy;-7P%Fkl7EI%amPf~r!-;1q^mS#AZ%;mftmvrEZ{^Tbzs6~MFD_#o= z3G%LQ@R`_#Fn`bG{UISOdoG;_GgVmAH)Q5`p12C958ZA^r(zl?zrBfFKHWF0PIHjl zYZ=Rx|3k{q@E~OtCXS~`x5PD8Om*Kgj(5qY)RO>P{eC^J9j6~~Y?(Dbx$AWVuT}&q zU1Z=5MV?qAJpF@H`6hYR^G-_cfxj0t$!=g(o+p~>{`ZgzPsIRkU+^NzJUSP zd_af}fYC4HMR@A;zzimZw{vP+Han>$yht+-fa1dp9QE#%Fhe{4pMm@DM_$?GfaqVTc;=QOT%3I_72I4jFi%K@EITY89rE zc+S|4zZH9*h5Hsx+=)P&676zO>2CaY$K)h`!*j-VAEbqr$1y}8Rg1t<`u1{~f2evc zl!LXr%hXi*MX@!>Wdbrv4YU<){U)UxPK9w;ONt{#ay3f#^Rtq~Dz(HjrZbldtH<7I zPON6jm(`_i@P`^R3<@1!&hnF#ciKCTvyOj0LMj#$>2K%<{-Ekyt?Vt(6L1*69wl(D zLMlx)Jo1}=$d9cqaw+bVeWRQ(dbQ3~ZYpJ-sGNBi>)F&qYA!U~wq{#a*Zo7xQr@+F zYdE`}-uoCen~wirz7ae>RBzifaGrwk>+1%*ghP+A+9eQ05H4M}h)(IsX{l}g83vvl zs8eS;yWTf|E1O;rPG##JYdu#io9&Ujy65Ws=E~gQHQjtwY0MUmF^BLH-6Yh1fL|OzZ2ixOy+(fa3K7>$(ZAkZ5^ziy_Md%xDs=Q&3 z7e$x(=u-_eS*Er71@xkypo3TH%7=auD>!y*)>K{U=;@} zTO5x!Y##l-ti5_{Z{ubArcH>bO-Hvqbl^EADdn_vIp%DEJ9>`A8qXz4&b2Gg6*;p4 zQm+;(GoXk7ZZ+eG=Q`F?IKA>3`Sj;P?~gz)+D+`AyKVGGJw>P)?;BEcSRr#q4FKVq z%k4fF5zr9dkV9J(ezkZb53$g9x6m=bBB-_C8?z8PwGhXXJGS9nWlXQ>@wN!w#- zUx&kZZTYDdmuZKO8JC}x)&Fajm2VwC50J677x>oWFXAl_9&a7V79csPCXT2cFH9s| z8<4~%sFJ0wv#Ad85rjt2P^Hqyiw{(nw*{gIFyk6VJ+|fXLYQ*G*pxx$eiZobu!l22 z%{Sr{Ki|9AX?g0~ciRWkP1}Fjwh!;IA4K{P8K*s7Ct55JBGvvOE-vIxq(gEXRVJ&> za<5n-t`2xI#5mG%H$HT~m-4qBjR`qo3trgStaxn??M#(!BcRyUg(a;!Woqd??Mk%D zOB%|BS6b3_>pS-q$c$dfQ;>2ZN#~yfl@2La3jeLKT&-O zBZ-9l3q%p>BXPEVQR0(Zw?@X|xG^gl-P%Rn+)p8?Z8$16zv%eOc*=33{5W?O^ezTd|ud(w<#yLO7#b*KMQ7A}dbGW840Z-gnh300hPQ@{ zxS)uW_6Xkn2vYV)V0Vl-EgiKCh6#uw%x8hR(+StJC}g83r@k=yL@7ABao1<7+(mug zf@H%|M^_0(^XNwF?Hf1v=KPtEK}Yg1xr;U@$d!H@BOf3u3yQH%U?<*&SCrGk z&+{}wGE~f4nvV6SMX>g$3@j%}M%@0HVm;W3|aD0pCa zYys*Tk5*kUgTyg|#i_FBO?X^JWg(0+Y@c3M1|9DL-A5Gt&k6KjlrmWyGjF3aAF47p z$1{0EfAWGO_>{5~l(SIE(#c4()$XhJgmejM4K)&f$tY#BNV_S5Yd%e7n+;@_3c5pP zn6(IUbR47g`;Eosj79sRfhdCeJ?k$KHd_LA0{c3rgxtV;k0};Y-__hOCnRn5yyze~ zU&nezAa=ls64K9^e1H;)!WC}B6{Q4@ndgeT^8y)hCmQ`p-sesQqo;E~crrx`U~1!Y zQNHCD6cmCni|64>Q3|QZ3gH9_t3{P-6MWP5;K54Y8}G22?||VkoOX`q;juDM5x{L- z#)`hc6_0WhuMa>28QZLg;&piIFomR*`Q~W65>eI?d7Y9Ar;_RPk_nLDjDyWwKr)q6-TSqj_n3bkO^X$UzMhJ6{*%i#cTR7ifub=l{R;~Hspaag2uK4Z~I4NhsRs{ z35D`;gS3*Wa?J_{8m`cWi}KZ*H1`Uf?4C4Qfbevn2jB$im;jF8Dz9hY@D3} zjZR#sk_K0myWWyOyjIAGUZk*Uti4L&plS`KdWX;DnbrnDT;vn0HHab!!A!cq@EHAX zTHZ2hhwisFHD9%}flpNIeKq-4HMWCM7N|Kk4LxPPwXR9-!c(UCm77wT1pANFN zU+QAK>hOhggBt3_a&l9o`r;r36AAkh%JMAm!Pe~HhM!>Iq-Zb- zd|CsZngCy3fwx{aRB$$2{%nBA6~M(c{H<(2nrUcWC}^W=EdJ5>QM0i}Sy|t|&}g<% z4@i{^uH7wPbpgYZ`Gi#9lmx1EO5H3fp>hv)l?#WtHyOsr3g ze@F_ITsnuHpRxL=lYa8fWft zYZYLltvPdSm7{?`f?H#)e{!^MaBuL^Y*0~e7|~orQe7}=><0s2{4Fo-JXf`^FQwSi z2!Gy(wm(a?KgYDc(*1dT%)YOGV731Q0WvU2F%b4+U{7N}+I^tDXdu38AbD%x7jD;MR!OgJ)tmvh`wiNi3oaSv1yGS zenWhCYcO%QaXExKY5#%XkZ|NIMD6@g?eZ|`CTV34ymGJ~u=6X~xT*z0qyZspMR;e6 zki2TI(~2-ovK7!u=-Y}>Vv99g@!e%D5hobukb-b&?A>r%NSr-6&w6_2`!82x5kl=_ z@#XLdl7FwG&(=6-V*n_#XY@^y_5rDg`mbT4Y zKd;rMA75{iNzY`~{I)NtacJ7%?3i(FHY$znQRkQ~@9wGAo7KBBHtCNxoyZA1nhk&F z5xgiH>Re|hI_Ch+jUtNG{$ZNHrT;cBN&9%l$`|H!yeGnvMsy1_D3&Y@QE)l`RdX@gn41B3pQ?XTts_b{Ph zn$HcJyy~6eOL~jZojF<;>A$z+T(^D&PpO2$sVq$?5N#`SZTnnx8KhjIR8|8sBi2us zrcY4tsGl|deztYpv6JX=E{SqmzGC{Y>&alOE4u5ib`5+c3Vh6oXuj@Z+50ULBdxd> z&vO%*)R!@_m-G%;w3AC+yvcFh&qt4o_!w7+j#>}`U$Q)3HvFoBk-I7dt)_&#uH>L` z`Jj0jqj`y^{hd-LwzdRf)vKU^pm{eVwb~$Q`IhtBnS`1ZLE@@g- zTi)hA_EtDSM9MG^Y2;WkIUxAtKpT&`j*vit0#eha1x`iZcj)n ztEO>JC@m>iPqygo@a*3pgV-X3YNsB#r+1LG0VE_65=Ku?Z(koDZ$JOQ&@jJN+s^53v2G zV*Bsz*dPncM$hIZ99uzZIAUBq|21C%%iVNe zQWUav|M#&5TEJ!6GqKHye~u!&437bhE!1Y-GqJ7HhWb~rRm^((5=9Vatnd6cV=I~8 z8S|{z#zfsCykc^VK!xZ2ZC<%RnvieQlb z<0XnfJKy!9*b+xGX#$F^UI9(cE9+;))|X%(KPy($=zn&{3h>Ih35k!ed zmyB(R6x?&h7U8}FAhv~v6@!doos|HwWvF^~U|)vE;9iLBsxO^ctyQ$~as8HH+H=OX z@EG%?8_3w6ifTSPw#FafAFdAmCALsj8qdV`C5q5!j`dpTe~B&8XSg?3!R0+fev96{ z@A)0wF4VSNOMGHWR^w^5WwRG4@(qF#aN%Ld8+s%qIyW7i?A4b|Mq~Z%WC{x!G z`A{W&20p6ZX-1|_IAKJgZs~z>rt6&e-N;b4m=Sa~IB^zq)+O)~Mff)Od3Q3BZ*$S^ z@8k8VdiF5KMy+%+`_6gh)7@e1UsoRZMyzjK=OfbL?AHqvKc60hCq^Mq0=)tVco9K( zWfZ_%lrRonWHj5!`;P%>VtPzbNeU;F-vMCj#TT6+{*Pk&-QM%W;SV%jE3iA(+l~W1 z@u8LRKK}zH0WlWs5ExF&3CQ=zFv$^4 zr2ReiwH`SX$6+JsKgTveI{83Fh|_>8(_z~F9SgWT*A8ub}0wKzMN0YbAlcw@bkA*x+Wcb7!9pk;$(%PL+1g6>5R36oy1|IY3{FZAA-} z<^%O>x&g&D6jk*m$*bY2kJ0hgO6?AXx)})~_*_L$M;FWE!!7s}@-jST(8Y!DIXvVr z1LwnBuTJ;a%kbC_#bH~)@ub_stZxU36LS6IvET~>8Et}@GQF?Gx<@(k=LwQ+EG$*G z%%=Lv3sOV2wa<>N@YnsdSBSOQC}yU94Jva8h;_BUzQQ^+?8EByPL()b7A_fh?6Bx_ zR78ILhuHQ{PZS^9hPZq06Ses-ObV zc5jp8Oa~R|P>CsOX#ByAtA+WrdJt)aCha=8k1%o!uuVha#BYqZf42JhMgGbzHd zXNQ2{v4N#xqBL;OfT&%M7!Gkl+($pMS2~`(YGgIIOv1sX&O6EiAB?sGiuy|5oEEM; zDV?^+zX~;}K}uRi@(WTT%Jjq?T-}lpV#637_L`zzLuol}H|;ccoaGl{GrQ@qJIwSK z64&BJ{~b=v^O+2@ZykrqG9uKwJotl%HkRyJcfw$KsKsXAy9429UW5u7zr**k1ne=z z;!N~$;scbq$Z0?-CiX_bX z`xDn*QL*nh4|9}4&W8`Ib5jDKq#S?-u{*jo&sf(89|Xvmyw1zO=-(B@4NeaawdVf- z43CLLXAllp|M*fo7U^>_k%n#~BqVB-oPIIM>-0=)jp8X8a`-am#p?x)Q;sjDbqEVe zdqiL9d3?ROJqZ;JObNB@A3uFZ3ThE4Itc zbZUmIW)@LSrMoFh$2@Ij4G33DZCjk8D#HO*%7_oW(zZedDDyr4!_>v#Q=}Wr?I8{*?{Jg;vg9wux=~6ZaNNe z)ZP`lEKpu*zC9|%%4X{-fxS6^?k4vv&m)A1Yicu)YM76~(%gtIZ#VRA@Z~-P)NDj< z`#22eE1uNmxSPN37|zZzN$c%c%g-5GAH6~0ZojW zxyFd-ZAEJCZH_CG_UDakMUVa5;?lgmR1S3kMyJI;QArQ#P@aSAR`Qus1BY7OViGms zci47}hBu4O*-!r;Rd?A|<=VDw80i-25&>xe5s(Iv?vf6bl193_ySux)#-O_!>F(|> z8SjP8IiLIe4SX02`?a0xG2~)*T%YQCeNhK3{o5IRUekA*Itx;0=*e~e5E@r=OKAoS zw(eQ47a*5iT+Mqj!S}yU!`;Pg*&s3Vkjc`K)~B13{p9;k`5e9P)!c6q|nl zb*%>~*h9*f-AvcCS6Rsi#uH@+r%!h))$b8qiQyq|{b#MXhwdTT%O4 zz0I^j@3MNeY4roj`UAVQTOZa?E*x9DwU26mg1n6?BHB!@O~`CO*evenh=Az`fp8AU zS80QK!FPR_{ukd8397qzP93Bwzv9(m6^8M2zK8L?7$!Fx?cnvfb42igTG;G z8?e5%0tMT!+na0#yV%=1#Ml!}YhS<8@d6lI!#Dm04kKWlAiPk9ZLtp`p-g~3OYIn= z=(w059>1fTgcl~z;h1{kxP42JN$r%4N0qmuS9lX>e(wgP6J?VlONI#0;I!*5SOU0FNk735&b#8}o zVMlfePi|Eu3htvDO}*R>D2m=ues?E|z*nA`78q=!NtBGQ{EfLBSsrJi`P3j^Dsf|8 z+`0oW0t}4@T!6_ZeGfrj5941Ras;vVZ#`|Sm8=9~l|L#C)|q1W!A0H1en&!&-r%HB zRi@qbGE9s!Lh?54=lrQ;&SGe8VQbD6z|FI3o_OkgT8Hf7hzvT7_tN(XjOF?LLvQ2V9KC8mh`okJzvR9hNzpy%wVpSAhD z+3~}A;crRfPyE^6*3h5E)Bk;@ze@s^J2=^sBf#%Axh)VIRxWXH)jIZhuuTyXO&R{4 z(x0dm9}p-LADG$~D2Ep`o0yvLIY_cAHO?|f3YO@pHfVD$sOmNd4jw{W2TnVzPg`ye z#>Ta8<47mK4RON@=_#;x1BE=!rQeN*K;4Hxk%z(#=uFRwAqztt0gS5sI1$p#Rr{)6Z@5)Xagw#|BRts(AS<6d+(8k*bXD)oY+JHRhvjdq*#%x#JsE&-Fum&_ws~wPXf7m$xJFvbr{0(3Da)-y>4l^ zc@_`3x)SdCPVPodpi+1f5f&4EHIttb9v+P*)`V;_f%$&U;PxIx)jLIeF;lEQPn++> zQ4g_#6$N^81=Iyzbohk;ijem!F6$zWb(Yhr&^xiAkhiZevAu*!%8&KyxJSnYSwdTu^d*&G zRF(`Cy&AbM87sn^K*nNJDV=sIWsZlGE+n=1;KTXtr|jIfoDK^3N~Ek1w$jIxO^D-r zXSN>B19#iYp&kQOLEofn2(B6k3-N{T27>kyza#dPzaVPIJS48aO+z5EM^0`(8Lwy! zNbl@xC-V!rBJ04`=y0~Fq@fohZ0x{XuOwLSz=y7iq^NqUQAO!ol^RpE2CmARtV+MB zD#Nb+%3NKoSk2bx^fsxwt)`l1p*rlmS_`8_pqN%jQd-2h#x$-5B{2JITg}#HO$T(X z{JYvofm$W!TGikjjlo(il=t7b<#gWF>2voI18)diKA036?cqgh5rW)Iqpi8!ZJiYy zH2N57^H{f7S#iF&E%aF+gRPPv9?i<&0F8dM-TZ{6e8&OL6nf90IM0!5u>TkM4vhhk z87RHI`l6 zKDKNYV{JRPe9UjT46&x{N?F%$y>A*dd=*$%1pU|~aC?CFNfG~Ozx6YA8?viyns$(8 zeo#$jIZ8?!ER|i$SsTK18$4S(ajG4bGVz zC8da+Wgfdez3cv>`9q1G4j66C;vyslBfbv3`%c`W6JnsJ*`pN9U|15V*4T3}(Q|d) z^MKi_E!nH@-0LF!0e36PZMe?7QQlp1_5`nw%GTY^q%R~D6s#HZlhEVq+qrOhaFmpy zw@H6e^IWn^Y?wwY4viA~spqKX{5TuuY+gZf^n7yhJaykd#p?y@y@9NE4J?M<)!u~# z!3{;pgN=`c?JSKQ3<(jnMMX|S-NQu#O^ZXrDDlF@d9Rly>Yz|n_@>QXHcJf8zb={9 z^m~-UsOtW-hRVMo1$nh)IwI#WvR5*4*n~NGKXOJt`g$|@N^^y@3;IYh@I~{=V=2y{ zTJiD1iphsD*dv>yfH8#Mttic_qO5I8b7R*@Z3?X8*d*Uu&)TYH#|e+q7G6wPP)sy} zD=3$Otz#za71QsLe$hSIvn;K%{a$CHC+Ga#!EL6?8w&Tywe$1RTftOEVQC3bS3U7z zN=aTg>7z+mG<|t3{Vzw7O3nHzsWfuL-4O6p;>6U%<<$33Y4t~Gpm5fghBGjuH*z&F z`AsjtmGe`})skW675|L6>5PKMjAQAH;{1%mQd|U^m;k^F%vi?lef}ZOa?@5=kTGZa2&gYdCBoZwY zwd}vA8MKBQJP;WK^B#Z>k-(1&{JRaFv_1iF30+I^SwRW4!HvUOhXWzJEx{=LO#4I2 zYLs$KJqH&3jZ2eXkB+gH7fW8wj#zH|{~aJbHtee`9s%Oh2`b5HmTFMe+Ssc!TLk)XWcP85khJQ)Q;eoH z%uga__QZIaB8czS3BRqs8nh=douF-5C;zDfJ-<%(xK1DP>%-R#9@h;{nJVs)4PHjQ zPa_nc&GiJ!Ah5#bo1#y8;*9!YA=T2y)Usvz@=yA5B~!{I(yDxPEubxv>8)?*+xooQ zvU1x$+_sIvB28pm%@}7a(hRL+cI1tB?9+B!e$QwW8F~M%^LV-@rUbq??fQSck;n## z-OUOS%y}-{)Z5KT6YNFv-NvUVDvB#9-mxcqWxH574139`>9Jo(e;4!3D}Q7^Av`XF zXwZVQ!6MK*b)c|uX~Dzy0PI%O`ZU-hJyg(8RCjP+`tz{r8*hIaZ>@#e@Z)X68$ND} zrs=1LwiWgJ)u#MAARm96T|{46##kXaUf@37a)Ucs8tJ|oIW0LR>^eSf`7QSu+8=rB zj^t_e9{rU2LzQp6`x5J-&cO2JVh!eD+qx z{Bw7#lkzWPOD;@_51RCub7D&)d#?%%wuA9Z-?9?Lt@F~7IV{Ql4z_%r zh<{N8kzg8Nu-$`9FanEhtZ_bFG|<=@FD1o#&Xfa-Esk?u$y^ohKaFjj&iX*CMt)g5 z(AaM0c7TA!)+HU01ZZqm-#nuTL*Ng(SCTzgcj*c&_5^w4~PH1cgL)^rL!c{W&XK4R*wGJ>4s`0+y2e_7M{B^ zjEUlJqbVqe>9X!_v6nYwn=9epS|JZmPdDFiU~vssJpsk`9~41J&mzMIPQg&y z7hj}c&6m)QX3d|-4{_a}LWDynkRT#pJqSWu2Q;?-F18z?Y|CR=VYKG~8(}PNV;dn{ z$cgP}B7}~cQ3N%sz5gt>%KtL9ns(2NtsgB_JQe9(dm;g%BUO?~S>lgm;||)L6r1V) z7~5;{d=xWis_RKIk8D5`TRD$eWKFDj_0x-a^RBK*(Yv2{9+N=8kO*k z8;+fli;+Jl0zU$<*z#2~9gXX3xAjg)u^$16tti8PC_?Ggw5ENt4Z4^=Lmu+ic(dy{ z+2YJUi*4OJQNgR5Mbn@BH%nGKp*PFVjO~&K!hd(io*7#rA1LsKuOMUnQZ&2F-By@N zS^ZX`HE?$1N#ktBFuSj@UpM_oS<=S#zR86cdNZefyGvK z^wVkY%eK##Gwu#+(!jCuKUWr0Y28h8UM#TV!$0z~=q45x-lO`#sF<^sWsliw| zs;6F}mO=2qsUCEZTspheAVkqVpUQ+&pKqLlYRetKVyn-{R3iEMQb4c?YTM84LkK$3 zMgqxw#fKQAbv^p(L~>(4Rxv4ZBZbZ`&Zh0a(!x+|qv~Y3?K}?Ep)6d_i$81yOD<;l$J{~ba@%9bnUNox$CVE%Tz%yf8 zf&B$#(I%h0wm+^$FFM6yFaPWPc|34vtO2PCMns7=upp7iqUP`bd4X z4CbB(=}$iK{0Pr?#}qTJB@DrbR}8*A@3by;c54r}%7fHdzrhX`v|;qf`#Z*HW1|#y zv5F{!cpm1wc}vi**rO2Bf0)Y@t2S&ZQj;`)na44_2X%f2ks!DikSwBS?G%!_Wg<}c-|1 zwdtyLmh>Nkku4()C)F9l{*NM!FCP-8YwjhF1Rs0npWsewVM7>z#1<2N-p&&}2MN|% zpnVx0&bzI772aP1_N5bs4~3Muid^4fMZp+7V@Mf_HU}QTbcG+s&@npbq4W4jE?|`s z`c(ND`f#0Jg_IY$bCz9?rLKO=pPLdpNfDFl-7Xzivm#^5OnrY{?Nh&8tMo6s6DYOM*0?8^xexxGI10pI}M{4bW= zxnV1beTC%vJcohI3Kb0ozogK2CAl)74^=#Gww+ zLvb+o!PZcNsebv@oT;y!rsz(?gwg`WuNJnipy4C4g);l()l~4!0C#H=QN=DBz4ps@ zJR3OSI5nyzO*_AN`uMJwuk%V;ZeF7ec?r5et(3Hl&Zu4bUaw|SmUhSvo<0;_ua$=0 zLcXH3&0;e*=D*q7TDv$R26XQh4KlIN(HD&9Ruq*k%Ti`xy0??#1#Z4A)y_ItV; zW~L^(RKJd%MA@}rPe^&~Z0`p@f29#gzb{~R9k<~mOe>mQonPP`n?`LSP0 zKTKypFqk@@$JThK&$y5_q*aG=)E@GnQG0jO_L7fltMJ|WDA#$PEZ=4^B_r>F+Spil z%jF&M?oTE63{2tOj9<08$GSD+1g~1=l5FEAra-_ zI?o9zv+-+)XTcY{A z5DJlww{PU&VV)0Sf1-nsZysHgl2$37iU95&O>GE^tu)Gdsy|Qsltlw^-J@^ z%I&3(@MW~8^+6zgL#iM3)bDC^!aG3WkF(+XLN4_Jvf~^Pu!XWOrWi(NWRW>tQRgDi z>ka0pp@3F%%gQidn&Fi#!}5;nDxTXqJN%}K+qUS3T~UR7dxb*-_~RS5vzaIcEMs+k z_ZxPAvHilW6rrZzfdG!?nT!5X4gJwCTD`-V&&UJ0z{IB7L;lJ`ionzAizhJHezo<) zqv05_izPtxQs46=GxVaM@$!!_E6VyJKInIbV)^3Jk5M~P4(KrcY0;6DDRHj0Y)FwVe`XGUp6xsP?mTrwT zd{NPvMk0%r>qo0j_>XDlC;V(?Li!WMY>T*eT{kjTb{RbL+3H>f%jYf!r5N-3Jb0QHCK8m72>HM5W5f#CrR(!$I87Dq@;wMS{l0JpddH@*C~MZozA^OD z;w4v$C)eHKffJJ(kZhVbg`Sso+LR!%6dAn~d7qT(%#?=ll+$~nG0yUV z52@G2A`siubo}qy2qa5)GAy?Cc zT*C18rt+YK%6s&h`KCI;Phe!z=oK^>0QU`yb z!)+(s*C2$oBb}K?;>}p)+XHgNU@%XJ%dgoCequcV`f4G~u6CQuO#f;&4JWRJYWBv= zPY;=yazVu0Dr2R;j-pKY(Lkn$!PYITNL!3^gu%pun;gKoJJZ zh#D&z2dftb6P=LLoV?2|;#)KzLtOYxeVV9UjYFdzO(Q8yI~7d_V@)FuO%RM`H1_7Z zFU_y)n+YPD=Np@8$D4@^N=Wfquvl9tR9dzVO7@Cd2D@8y*IG`vwHy*komE?1En9Ds zTbFBFA0^8Y&sqZm%Akh`VNHqPhlmhS%Tc7t(TT^WwweK22R0o1ghx7QFqFjynm$lO;rpc@YwH1A1S9E%dT9-R(asoc}6x(HMW~HcIiLw6Kfup zU<0PGIpU}~*(jCJ=+%(G8Mh!{3g1h?J-XmOEowob5wzST!-m?xyNeF+z$YDOR13M!8f$VcOvY>cASDc+b0$ z1lviZ@is$I;zLRZhgJw<2b>we*v3`GBTUjYN{XaW3x`fhEjt$YXKwfDZOwM&?{q1M z&?%U9D@xaBmSw4=PN^JCi8p3RaZdvyqPgAl2aFhj1J~aS z9%k}hytC^nvwp6#fu*y-p?!gh8D`)yjoo28XgzwHwIh3c!NlWdZmZDTowm@ zA2hcuy4^v%M|hh?h?o30mp0{q@^dL9ap|dIX>n-@?QE$8XIX-2c~fh-)^-_u)!f^# z{Aql-?P|H(w&g@>g;H-t@0Io4YpsW+m8a6t7f-M-GOKWItNsbAqM%iTqtz3*HO%D{ z?5}HhZm0NZYiTs?W}9p1Z$wEM*NHXPv0sY4EmQ*iTrphsp^MQ>b4Pu&)-iR)y)MV0WM)@D-ud{w>oKeu%C3Lt zY+y5FHl)-jth6tH=Y=V!CGQ6j4(2>4>n1MLJnpBYd(|*DwqPyR9+=l3AM}JCbfX;>o$z#o4Ry;j zjr|@PXgQoZIvhnmf+9P*7Cf3VKPtmno(Ck`%hvY2ceDt-Iw`#F3NjtrKX}Qw)+dm~Vk_kQBuC<7wdX>A7+=$mzN4n^%x= ztZ!$xtreCA>pMt*VypD5*arA{1qX!&hX+LvL`D0=#6|yyB4lOf5U@iM^P>y%ic;Q` zB$j7Zl@t?{=Yv7fZ{7Zfu?0%`zm095VELQrscF#6{OsJ!^2*x6`u`jr+hd$QdvkHI za(#JozIA=|0C_q`y2OiE~@F(nZfG0}) zeK!Lu(T+@Ws%Wa3{{t?kxk1@%qQ)$iBmq!tml_>*xaNSwcBNSt8U+_M_xbJ^%3HN( z6ro!MNNgceoK=y3R0Pw!>YWjB0YF9IVh#WG=kQokZQM+S_GRM#k0QJdL59?ShfDu= zvHf2ZA#n$PK_zgz6htHhwh-HW~8C(pT+jLsOt}kQ2qtm1V9mRP1^r1wj=kX zM>Uhm0Ao9ym3dS*zrS__S|KO>v)G!~^Z#XR56l~dyMV;@a$unwNNkhKUq3ScMG=_V zP_h4@2q~uosO&=)FaJqwr7H394N@#$6FaW~D1x`tU&XdhHmBr#fIk1R6BultQG`(` zNEg7^mavRGSH7dqi!JQGjjheNH7l^#N{jwsY#FXzsTu%_t(xT8Gh=)75l-)UvHf#+ z%+PxEzs8o=9_#;51P_D}c34NOWuG+%tTKo7koRRAu>Tw$0~p%`gR;BrB$XHSI~X2} z_dA*K$9H>q$$WkLC7|Q`zl$xv*gBK@ZMyXx*KedDzHQ^i45aM(rXWt${Y7Em{Lf%J zyfA^pP!GmLp^qNRLPB4%eNJrsS3;0hEU?1vmQvoMv+ssqj69t7zK1*>ufmLexw_~GJwC`dgsL|HN0k&`w(Y3fO(+4|c593I0C zlrcVkl`_fiLL-$4G`6X56qIxlo@*$&yRn4xr@-b0pa=;-%j(O(V>74$8xc=V7|G}^ zuJaAPv#X2aj43=&N0&~pyWey>DCusL%>6*c}2>>5c zd7c;B9kE_6W@=b7#Wm}3~#BAiD?T*`VAUcNz6 zV-~>f*z{qm=|{KRjZQ<|3KSC>K+i=KW+2QBFzxy~*iOnve80?AA2}BlFpgr3hja~U z;TB4?u};L42<7S+?@8!Oy(z(E#>_e{ zsI7a<8c1x{o#KV4_sg8rfUDF4G%dIK{+^DP*-~-|Vxq=O{+vTPG}1=htUU^0Q)GHf zzi0b@s8_|!+30^9ER->-t4`Z5F%Up89*YAQTShcvu~hG=IEjyCoVF%9!F02;B7kCh zWokEAqzs~CZ+E;Z{towU9UYIOlQXQuU@Jv^W?;Im!PYAKU8<(2e*>f;@7Shpu=x4# zSWDfAeF==|3E_v?RRT80PVTgGjAGSY&g;qutz|l@U}R}SS*(czAv)${-b34KY?Qui zLs3a}oVpC6`B~w+X@sz;q-@vA;8IfqNe!!6S@${|1U@?=^oKKL54abk7FXJBFV0_* zAxV|NaFTxx5j(9XXc7}w6==s$ziD_*Y*m;$Qk#Tea?#2idKX@ES_u0wqh>kH3@%?c z%ryTv%T#ouiGMqP!zeNI9t+{3>q+9QRSA^|7r_*k!6`2o5k1=rho@(zPbBntupMBPCQ}s^Z~9gPdaqxmPXB%W;h?rcV!U$RL~KCf76Vyz z;xmenN;}Lf`)lY&PhQeY$go+%-0(7XehPuo2v_mNhy#2q_YFOrSq-!PA ziax~mu;#IbUP&7?|587h%m-6J%K@2t_Wk{gxG&)s|KF23Z$20GwG>swFR_(zJd)>$St+9`=#2 z6?h?!yNh%PKi^^$0(*V8@Uc~FBgPKnm=}Y=s(40nRCrg@_W1CsI6ZhN?cs5UVO-ok zTL&{UnF5~50Xz{uVu3Msx~C?7;+!u7B(}cvGVKjcYaQ74BX|to;s;!N!@3@+EL(l{ z%CR8tx}j7e+f-SZ3^9hf;TE()(A-XaZboieh&=W_sR;x=qX_;6aHQ~$vLU*+J=_T0 z5uYf?z8$U)Z20#ij5ck5+#{9VSMBAlgJ49sOF5w<)yI$v=+j9SI#B^CLdCa8`kyv~ z^MahhybV^d_U>Es)@p<8kLU5dQjhC+kfAPvHZd-1UvC>*6`lZ<132XCur5JZ}mcm-^Ea~r`8Is%ZhQwidEE_OkV3(w>7?y z7XM5@*loaEE*1@`UyN$tk~XvqnXR<8ZOZKP>8g(uxL-waEXjhzKilaU*ctfS>1NoO z^xB25*(t)>t5Deg;J3H6w{Hj_M9YJ7nz08MTf-QexB}GfHHW^0kTB5e?pf5IIly4+ z7&$`{eM1sw9~uL4oCk-7=;=mxIU=q*uB$q2ayVrO>E#>X^KcmPeAlL4O{>ZbtuLKw$No_(*<$PWh|Zs( zU>xA#XQN+vdmznzK%rqqb6|dH_ysc|hDp#9XO{&pz>^R^R;1JO^{%HfjF$|hm%Ngf zrkWDXZLCJOmrlQzuCJMMv~p;*89Nx@AC))aym|5C`S5*g)Z&H3xJ47<8#@uj!10m} zKYM=pB#&-Y;tYb=_5$Z=KoTPxS832l~7pU%Ut4=MXW{>+lALlGKRbL*bfWxln77rNV%L4E# z@Pn(w2x`CtbpgS-mBFWT!L2kQmul(tuZa6OQK_IpfyCAg8}`l-)n+xlk0zAbFBDP2 zk)bCPXgFU8h_g+XNSa90eQVa)=ff|e1~&8 zo|I-)c<&}9geHPjA{)*z8$OW=sXp6`%{5>>d;T)Q3O6!VAW~$X7PsDjpgxC)*6>-k z<%9q^RuqM}9JONI1U+DFy?kLt8+T8;(AFmXZZ?7DLW?{>X>FT7^`;=+N& z)~PV&B5vb{d5Up-nsL0~ta;UjIq-9JmFMGm=L6gwlXFNYGfoH;SJR-eNW(}}2BU!I zk*i2i9I!K5j05#65|_X8B^g;7Ih14oPw(k8tOGQfg*7`Utr~DjU*z~Z&id0)2h0a0 zBMBwHR|%kv4ERW0#t|PdoSWR5Shin;+3u*tW+~80SRP&YBDo+?aV=#$vHboX5;!#{ z$fX#hbCY_FljimTsBY7CIED9&gbxx4j`q^N!lpOSq+dTXwnXxz<*lb7u=AB9&aaz` zDqAbk-)K0%bA?7Dyg^RN@Y~E_T*!EpB+iZ-#-W^mN>+RMWBP+;%Ccft&r2uvX!Ll0&_Apf_7JS(;yh2CctV09i&zf>xBPE-5PK zxF&~SF30ma=QTlY2Xk(pLawq??s0tXyZ&6Q{oEUbJbcQ$n+bRQeR%^3W22%x_&(qa zS)Qdav$aINEuE+R{TG?SeCPRmU{;sFDUkkHp#G&m+q)pcge{n>!EysqkoQh`hN{pY z(Tv4`BjLUwp{S6HCZ6}UuVbM>YyP__Qgeop%c!b2~B(#_p zP6eKvs2N?hwqYC=dHkd zrPw|JSgd7)lbD+gW%rG(6qBzy#ckfafS%xPlk^W%)-HcYYC|r;`Q2d4?~|&H*RIuz z4G_bygLuFVGQY?Q0IY}`uSg-Y#~`Z2G_l8auB6dShs9`qt6atS*fF3D7l_x458p{) zSLIcs<6Be3qv`nmp%e8!^rb{*hCyZug%f9Trhqbe_GIRJ9f+O)QMZDWWSzY;Sg%`R zFiR;foDn&jabEumQO^sbT0NHtHRm3OiCXunTJ*cxaLl@Gp*kzmx+9-D{KC5HuDZ>g zx+hpr4><@%7-Wm$t{w!!$OSnMg09y=T2NrmcTC=r3cx9{B0sReUEbFU@W&}I-32&; zsGf(VKE|Xz{vki9u|6gEV;Z+oCQ(Dq!vL{GL)D>D08C+UwpmP&GO*a1(l&DT71la8 zc9f`O0@?F}xsbz9(?g>lB~mAMLWz14@Djc^*jFjRH>FLjh93rYad`a-+O(j#ObLDA zz^`Y&d3UH8^fAe9c4R}t$~htFOv-9+@Y4ZG@&X~`)!segd7O%@wRaT&*V70kYEo9DzK;uR87Y!|U<#~%s;pbBDC z0+PpeQqAw=JRN!R9aJgyw3@%#`$SkxJGqW3=}yN88%4Q?wK-BcrySn!x=b>lbV*3- zF4I(hKq18{A`^9~=1T6$tI0e>1SH$3&qU#80TjZ{H6qSgV#(o;1r(Zx-Qqg>eXQAP z%6--%)zw$b0o9dk^(`SNwaga(XvUf`$DQo&BkY{dMpInNs!qf&=n__4zy> z3l~2Y^RShoHdIJ8R4*>L!W1&$7e*(=#SRSipqaNcdADh*bS^Gt6b+rR{mk8uFW5(H zU+{Tg8=jZ;1*sPgHYUU=`Nr2GH#!yPpF+J#U4AFTx2M~@g^FI`Ynhrja;del_At^U z%s;YkITh4$>xeq4bzLnR%uZhOxC#ExAd23=~*~@O!nnevEvx73&z9He(q-O_UZ2 zN5!+8;P)ExVw=iLDyi0b4o5rYP^uZ(#9QeJnTU4k)Cs!g2?ke!mngrOd4K7$rn4<= zVAw&AH$r*gO$vpDyyFjnS?mx#78Oi|kX%PriM`&subfn5)Rol|7fRV;dk7WRoRT`M zR&VZN!ra!>+7@u`7CP4hgSPckyPIdGr4RJqaqaXd?pV6+0A-ES2$j9-jN@?6*TI>H z^%+&DSx<)9T!GnTgV{@;S>L?bu8!F+tFz%~b753-(IRu``g4hXb7viWp{CI(ubI*q z6f$1V)9ClV_w7$KomcdjXUv|j?U`qf&UZpyAf#ESe*L1hbO6Kv2j~cm%>^x5hlRm| zZY+!SE{j7?X8qFUHG_aAe3ZSfGVU7Rl6*9DI5hrf8SgdDC?m9E38K zymq+EOZmNdjb{YUzPX2M<=Pc;QrkUZGdlv_(tw)uU*{fuI`ZFNXn}XPX2)xN5xRPP zuzE?KADi6>Ew z)v%?ww3S1>tsN!-sJ5CbVbv;GMo(A9jFM(wuWt}t)YfaPmMP6ccg$sfI0Gluj(0rF zX>8x`dLPgD@zn*S?FOM6hRD1NlQE1agN@?bi&-{|LpSnq0VSC;ri2-#EgOY2&1I7) zR zs7H1}PFBlHvgTHfiCa$TN1@Z7b{_m8OGyZ$r7P;mNTd9#MW^I1TG@71Fx$167=7hr5lO3VH*w$FFRKycv3GNh*57U=fE&W>D! zzCVL)pUm^!u`%80nHjlx;O^MG*y`H)#;VHp&hFl}$l=lP$Z!jfeO+PKE!7fp(67yV=ML{6G;rcYqbOAGxEw3x%s(!gQQ=$9c-LaXx3lGrAa+^EKOBomN*}Bc2yJPjwgDp3nfPcf) z{w$>2V8yMuG2#SRY~Q>m3I4O#j&}Up*uHt=@rSYPeUtH*vCZ&M#{SdT2CQQKgCZbi zV*WWihAor11~9e-nQ)|jGysYaw%hp+V_O!`6U@|7&>O-!5zrROu??UIT+nO(+#M6Z z)dud4Q90`2NwMwaMB54Vcf}|^C$>t=8C!8cVw)Rp-~%wWyfH@GiH3QFKazB6fSu5` zYp)wfY}Kf79JUL0(j55Ko)z2uotHkif9{S2(Y*Sj*oJO@?!x_ZcMMDK?_j%^pEN=S zD7Ha_?S%!9yrTU=(VG4J;)({k?vk2mFg zvA>ILH3n<4SzT<4>IbWo%0- zItUOKD>|V*5r61{`DA+5rNmld*+cyE(6WcnnV7kc!r;4A|J&r}#rAJv`@GoB5MQ9t zZKQaPFm4Q055B1&z8nxdF|`^e8_K!-o7iU2TL_N5QIxKoB2aa;ol>&~R$Eo~*L5>` z!T%1ne^G?aBd=*|h=$e;g8hn??ULg{^UaC_gqMBA1Iye2xCqVnyx1N)Y)W zCUIQ%Q7pULOtC-a+)i{Z6WdDt=~hqvm$Ci3*d9BP*Wg9jyXm3d~F|6y$9*?W<6 zEqiEsm?U<9#r7>>W9RGRinGu;vT))Z8rZAZSGo@7uF*DEtUg1Wr;og7XNt zs0eaA0y0$22?3HI3V#WqehIGv;e;WIU>)piLdPi44AiaA002cm7Z)#(nuu1O%b}Tj zAz2YZiPa)BsBUf~rK=vzXkVDee#b0hTM^B)*OjlcFD};y8dKQTONGB?kN zRt~s3mO&TGwo_4Lo=2y=>N8c^qgMPq@gik+bE*nZZ0$%6)Pcd4XJ-#m>SQOWdAk_L zcab>i0PI )SEzVBTLu)qD5C}_Q{t?=Wz%)|(#>BXd~4AeQ)#cEdVWxKBo%ahWh zfteGP|4|*4beTi*ac?vPo+Z5!`-iZ`+^BL=ZFVB6fxbtEj6LwKUO)gw{Xl)LjY_c^ zr?%jmpz&hdz+@iRRiP{;@%rxd$7Z#upI)7GO8InC#dbIrAtsv2-E^E)Nwp<$EUD@! zp7ph9GB!C_uQfigtIW+^l|A1byD{dT-7?2;uhl|xk(liu#C6~n6Fw8GRNa0aY(q=* zG~`3H6yvbtyM^_G*HDff>j+j*%x)__w@jp+)a*-|Jt&*_+(3o}-70F+P4$C6c@b~A zgNIAa@9ZNxugg4eP|JYBW110dU7)tX&zA9$pHaC$)I=fXa{RaL`wBNS)I$J@VA6q| zH%7-`nu#(j@Rcx0#c#J(`C7@7a4-#RzWZ&wuW3@8EVm0;kVbfcD8ud>4I7rZ~)VXx#Ax|Bl3Y< zrHNFe!67m{q>{qGw4X3pESh74f?9jCpD^&emzOy=LNalH9M3bh#3q+MK7~?)t6ma} zjrBf%Nb*|?QbH$j-Um?15F`7=;IL0#LLjNMu>uw(*-++!O>%3P&HrLplr%r(m-r4B z%3!L)$OZRa{|;a8McPfwG+%GGtQFejSb)ssCzOF*7uw5lNK`=%z}WgLUrt~T0*h_Y zUYHeY&RgEZ0#UU6n56s30=|#ZKb@-Mx+e`;^b;kW{T9_1?x$l_p{9JCCNu7nW{hC$ zDl-2hwzG!6l4o;}l`Fp1&V4~MS;3eA8MrHzOpaWyj|`aArr3VsD*KEgfZKG*nw9jF9cMa8uENgd{64*{ zStc@Lli+UomG-`NU)StGQ{&}q&(AtiNb5JVpN$Jq$&Z_^h@>sC@S58Vk6TRd17TE_ zS&@1kw;3GEMoLk%(!R~?$gh=+`SV?#ROvT;qy4G23>|-#ceA(STaNa#@9XXS&A#gB zy-q;i6*;4P;QdvDdoTKGm7wKErI;+w(%Dtu@YqpZq=nB8qdf}1*#4TUAi6qEMYjj& z3*yREQPcH~{M%Dsy~_1(L$@M5vym)uIib`)J&85kqPax`!_8nfM_%4tya7DASs(8R7^1O{u)MZhW$o2T{&DP;(3NW_V zs-DAnroVcWe6h@C;>_mjJV^>T)O?kfsLYcEm4D)x@8o&y!gFols#sB~&?9;uD|@p! zc$a?RF1O~sz=c7v@Br?PwS0jo9#buo;}PMo0JKvm1YWqCpNX*+zr1{~ZOQEYe#>d7^IOr(_?d%0HBq)I3kl6x@ zZIGpq2IyO~e2|!sU4fxpQGswtfSu`1P(|c-3-;g|F(O-0doYK#11J~=UX)-v7=PQ| z4Z*>V)u9J0>T94A01AO*It0%+jP;R*BREFxki{720*oz9lw%Ue(P_*v4Z&%B_iYxt zQw{>9f|ZkG-t%Z{aO!kwNL5MgY$f1qujB0E<=j`}{HRI;oFR*bc4=pKfvuBT|o~Z}IV!m|{zv zhYpq}+H4FiN30^J=W7SHUwNh@@Ln3-rZaVB-)PO=+q9v;k019n5~(mU@BtJq*^NfynlL!P(tDhxmx=q7|5BW)vZcY(mBNVc48FJ70 zre9TO=r(<%PiGuI^j84clws(Mq4<13=;ChZ3S!tNwy+J=FbS)$-CK!$8p*?3y<`0F zGmdZ_Cg*Do>f40ydwiPTv*8d#+E(g_7=;L?Bw7R`I;2866oPkXj_)w)vs;-X`HJXq z336QF4GH(?UkAEwKu1Y5`QRWOT&Dn`g|9O*r7TlEu;c`a4ZQv z#7lL`GyH9w{}-tY(j_3>A`Mc~Al=>F-ObQl zLw6(H-3`*|ycgW}bIx<#KVW{CHEY(I+1Ka0cl4cVEGJrgP*PH1(q326;bzhaRB{$4 ze~y!XUQ#k}evivk1gkGle^>Gw4DHlk0t;JOk(7ehjU%HIxMZT)c~`n-k}8Uz)vsD6 zjUY6fR5qe&$HAKB{wH;Yp!}RxSc}SDr$Bf$seDaUyG$%yRiAL5paR;3@JO}779j(X zj^whC1cgWx7((9$i9T>vo{VRBUS`Yd2H$*s8~ysz8N9Me(tHa6)5!%`K2Mp_W5T)%T8>N3mY1KoZEdvWJuhY z0h>pWm)du8BK-LH;zn&wrL;v*=sn1AI(~z#(BdaJk&7!;$R`?HSoQ#Rd82aS&+R7% z?c>q}H>V;#_p7P6sP&<#ro9N6-LKjNrGwP3JQ$_+K(!v3PZd-rdandHT_v+#l>Qza* znbdR=v`tm?O%x1^aKI2+nYp?S5F|+cY)z;zz0ZLPR4Z36R1XmZBQT zp_S2@wfO^~`& zk$#Iq`AppWEL>*0#s2W-`j6jP+#l+TDPay>2KYXFb_O>{6#{8E#VDe|>_;|b<3>Ek z#_wMnN%!K4QyYW1ywi!mnN8qT`}mJy76m9iR-A=JHiZ=rL+!-B{4;&rJ`dM4CHRa% zB{mQHf9CN+Y6j+=jie)O6^W?z%?p#wtW=u=JTGcGN}2`x7jElb?it4*U8 zpw@;a*b}1PpAuS!j}Tp{f7>Cp@n@BK&z1gdF1;lh6IM>u(<%D|+aA@B`l@*>9x=^l zz3fz?9hqnR>Z@>m;t!0awEV!d*Jk!_P(#YFCMq56&1O3&kL^iQCpwrq=}RHRRKpHe zNu67jox9_mA0Ip2ak>K8y8;xuLLIu^M0asDcYT=XiZ`qRzN}fS-5JW=B1cu?CEe1! z-9I+EWi@_YBvxOm^f+1fsHFC2*Y#*f)x@3mzy{UmhSKWO(;0-)8KKsiO4VBM%uY>w z#3x{|lIqh0qzEH!PW0}2DRS;SbJ%eGhwS~ZLj7qwc??O+R>jQ0kNwf59*)H^^lwa~ z%;w#O6!=wsr$2FjsxZ~>8j#!v2G0XdT!Td|3+5MQzJr5lrXXFKMODuD_Z&l%h!(Y> z;O3|JD6WLoM{je2;cm^P!`_4p3B<6o`QeWO+>yQo5+f75%Myvry`~V$IbOdG&ymHP zk?FJMWmLFT)KLHrZXK!Zl(g(gsUHlFo@iRH)3u_ULEUPscGSYAY5qPoU1coz{ii7f zLc9jeyA~pr`oLZGq+TW!P=@lc9osF)o2mWJ*KwS(cJ$Qof`)PI=5pduLQ~O>cYG5c z+$Jc(iD=z6KBjF@J(4h*cQPOAu!h009d~k+zT6V{v(3DXl> z){{V!kmA*sF{cm>?cS%JRuY`9(Vtc>m6Ruz0zASR(r{Y5)Y?x!bw{W_9%LKvx*Da; zU{%cgT$)iho3SLB<(HVXw#c2do^|3iTAZDA4ma{>>H8o)=NS%R^bgAmaLY3*o(mYA z`*AR5)71a|^L(Vcf)OE$`%r!f+ki(C3)34`^0B4#6;^O>Loi)jNQk22eQZhELB!Bt zA^jq8;9&mag2uqXkE_PY(8b6F(664w7HMUh9`7Pk#8T6xZg=3AKOuOmaG(`&@Ns|i zg!MjOC4b@9l;*KNO>^!V&)jHY&thUVtzV=#%2L|M%E$J^)_4pBXV`PMC0zS_1|Tii4SL2>SuFb*ARaQ-WLnPo0o|>jG?ub{U%65 zG{ZkrTgQh4p%4GKjTWWg-tFrL_j7gIjpIT{2u*s$r=>8sSoQ8$jOJLr-L>J{eW-~V^WN1^?{m?*fu7#=lCJY= zy@~aoqfgokaqAB~*^6A>i*mm$ijRqGj$zT;Pg-H-_ksD%cSpbkt!dMcCw*XMv!LE} zSM>Mp4Jb~n@Vh7BVX5nV$Y5jnBf!OnvL%P2)xhoUV1SETsvb3DJPfTQbT%XUF{;GA zdt}0b`D<|8`{Q_#0cB?CczCm@knv=6ZCOV9WGn=7a^McPv#hqAx^gjbB9xPrmRD8QR@K)vHZ(PX>q^@z zJ209%yL-F;XJR`sIfY?6GdKGzMOay0TeaQ%&&2jX(Dvl)^!$(D<;Bg})w2}gQ3VPH znHZ5Vq~oPK)?cwM2=yXGkk|DDx?_OFHYz9X*&gYH%VnxU{il&t=Dk%I`fSCQfv8DY^`Yc6w-q^keqzEKLbs>Ppc6>o~ zC>IEiS#Gxe6nNR#{z;!7a`+X|<_UxHR?4v=u`3X3R`n%VvTCOp`#P&Z@gjFE{{5BR{La6eo$wL`>RW`$zc0k!-1bZ(V z+xg8%VO-;9Vq3TsEyXslg(f6em>Vn4#rYFn!Ch_(+Wkdi`?9f(|A*NAtFg88o^MC6 zH4xZMQ`;~$Omn&6_ zOL8YX$j^>m*axL16VieT>Ht@NMJugoaa!+zU}=4_+F^dvjt$n$&i#)R;SWBs!x9tDOL&Zw{2wX8`I{GFOHV}hOl*0o z2{?8`ZLnXY2s{_0|7vVSO|vd1fVkQJCq=NErUD&a&1&vcK)?IniS2(hw)IPN#8B7E zKi)Ckthn9){WKHU7b(KqTX=7B_uCBj(VVdX5L<*#&D3Q${3!G_Q`tNpTUbv+F8TyM z4PTDKu!LT1Vln_J0vBg6JiAeB9{n~AX$?SZ z@!ymKQUp!15ad1}v6BAtqkUuus$sux^W2%g-M-`xWB}M=Q!)u?NRf~V3HPb&1jeq1 zVt*D&rsT3>Eeg^#QF)z0+bO~hND(aDyLvc*1DP(>aQwK}Y0P|v+(uG4gr(oo*}#9o z)`I|G3jsE^JBGYh^AT_Fy88Z7??rf`=8_^HWg<%NMPgM&zW=0{h0O_UY(pu6)TXj< zRjZ;uSw~Si`R2&L7m8#&jz`)HOUSG3$AYBtXqA&FXywJl)uORuGjl)CUx~$w1^+}j z>mB+>iZF@zx4YmA!8ci_g&1bI>4Gm<7jmPav8)B+BPMFq^6BSOAh8~4$t#-gD?D%5 zJCJAMT)>ytiG(K zBv^b^j1PMO09%l7&rctRo@_P%IrwLhjHOL#YUsL=G{ zjctxq>rDJ;{b_x>TOd>b5f%*LYy+~Cg*b8l61>P+ zBTgs-d;tm$x|)N}TSa8V48hJ5EjYh5-gV?Ybyz$w1k;~Y>QuwBf2Cd;14zZxO!sIjNz4`lD6V#(;P9WOBCU}1DkT^z@i%- zn=U|V>;0$wxH{jwr~t(wHEd&egRrXD0*x|Grs^cW;GHi^&v2 zB}4WhaT?nq)o*3a)g==Hqg;J4=@r>=ynjlHc~OdgyHVm+L79vR65T%oTfyopI*ZTu z>Rp{m4In9?JEkU$5~(c4KC&<4lAHq}f2xsCCsc?XrOOAU<4Y@>e~Z|@oaPC;k~RD| zrAFih;^ZzWOBgiOV*hR|ol{g1AZ@0*x<1j4+M$*(a%6CN{7OU6p3!IR$V7e7%wptv z?QI`N@ATE8{geHVKIs$di&|Tc5n>%pu=!#+#CN)uaYf(xMvHfX7KR|t{MLj@=1*|f^+wqUhdKMGmCf4B+jEpV3sLvB zm5omg)EEp_%I-_?@8lX8f0YftyVXDxN${Q;X@n~qxLN)O$tYl9PE6;iGwgmsdUTVM0>Wc&qp$^e$njP;2mmPptN&Km=R!S_ z#r|_%_@6YANcy8T?gN<^Ptj4STN5nv@wxTi;uKfOsql>B2}p};3}szPCZObsJa(AN zm$vop2X2B7n3DozA2);shb=`eIG3Ac*b`WktixM5%wEUk|x*Y!9kyiK){*}{KCJk2a0x--u z_$dtef$kWMa=>G?b@#Tlb0QWao(;=Q0HwSQn}ZEUmd(_(O&~Q6KZ5O-0t6vZTM@h< z6)#)y0$Y;~TZ6C)*U?i-g)ne2F!+z-ip%YJ2J3^VL$`w z^RQ@E@}!!uxCFh0e(|+E@vJSUd>s93hwwcP{lWxiVL{1bBZ|X*=XU}yw1EFqg@Nnr zr@DxgTAhmquIq!5D>Nq{MUXbgcioM3-O4rCtBKsXbS=h?I$|}PbugS`r&~jiI|p*y z^HC4B^jEoVZwcIYl%oM+y8>+-kslr28{MDn&XD=)h9icRhJkR6f$*~jN0J91Mc|`> zdf1i!E2@C(^9icoOT1IU#26lSB` zM(%skYZ2JUbzYZPU};dkh+Z+rhP*SnpZ$qZ9w~cz#v?pCv_n6mq0(G zK>XOipoYM(y}*b$&1mYNSTWpq#~`NIAl90o!1{e2)jb{}4EOL4SEQ7i0RVMy_b zG=Z5bM^g}{DZ!<^@0sVeC*-t=MhXz-b{j^H-bf=3L>j?Ip$-^W8yMQoxV|CCE4PkX zVvqj55VaT}OB$3naqdP9Xlx1d5%QwzJKb5G^H~?5E}~=j=bxvW0!g2;aAQUGKM6H{ z`dAwaI~PlM5ev92$XVhPRpUO{#IeQ1sUxv!HG;Hh;(r1f+vLykW9~*^N)!Qe`=mk! zeArmELUUc{WWu6fJ_$~oJ}mvfHZ8%sv8d#LlXp*j-oB>o&Ve$l*RjF#J5q`?t0$(jB#;^X;dU5_n zPRwS`GNknsXxLO2>ePX+sUAkDOkSz%S*b$1XKpW(;IyjE!fIs*^x*Rjn~) zQqqa`8)aTrh7NH!qTN@a-e(5kWrd1n0o}1B6{jT*@`Rf(l4K`-k#KS@iTq0^D(4!p zCg*bH4`sU)xwF~43h?P%wWkRYTK-c0*wT$RQW{M;T(r5`M0HcPkjOx2nLO`Yv7%fP zq9`MjsMj=kmZomY^@b0^Mhk}YHj>f5H}Z5B>fJ-45o@0}(sQ~WnZ;`Z>Adl4V=NZ{ z6xCp>7EAM?@n%9Hmo3&g*~B%O$sHNwMGNBn3KIAUV)X$91uKRu#Dx(SmMnt5!@vX; zQ&LuZ&jx-aB`no(6sk2lOc(X1G?%_E_I%?zit?+{r+5M- zDS|U8g)!*?zGUIBxN`xihqffCv1EX&HEY{%K8AOerSyQ?e`cYzBChl-1bz7ceGxfe z^#EhNh<^**wnHeeR}^qiByhxKb3*&&Ozri#^OsAta{e1g>aB#}J-GZ)4fpQ?9AFx@ zVyfU!tbnKcfhZZgwGW4qB8-*-3<)c-nh0M5xYnievaph9sIqUp(h#SLOtOk&_!U)C z*B|*zIyzml_)JFb?%&kafuhyHzSR=MdU(lMG4=2H7R3{Hvy!PKgi^?N5^K~@oy&4- zsEhPzf+b56vP&GC2{N0Eq<+>XNcC?;{GF?Ph191)S7)oyH{ES8V3<2pZy>!8=}zxv zMr1fSD`TBvNW_`vX^>|hlINOI-^HBgk>BsZJrGN5%#aj~RBIG!Fz|Ds(D-q{;Dd)5 zxFJG)FyD0$CFWBO8>1a9R8ojZiuyO%{YEZ0FcmojoFfTl)&mz1u@;7S6(52-d4?&V z2KB3;FxHv|kJwX9h7GgXhmM-s)r%4~6J}g}22)17#1jK(ihr9Hj}0Ym@ce2{E|yAc zSxgx{7)Dx^v`n(|Q>Jb`e^mXU(weWD{9_Mw9NhXyk9P9#d+&7{v^4s~13H{r+gfrP zTxHwVLL1a&8v|ZD5^FoNa{DK%cEr?n{>pY9!}2dT?c_KeU)eiwj>_>uI}YQ^zft8H(#LUCQtn?&os8yU&RXnLveRB@)lrr6> zs;<9uD`+~3q>6wHTXlDPp?Gc}-k>sWzUmLb0 zkrEQ1?nIDQS#;s&>Vp{dxtjOsA5uBF)=4pLWlMy5)r&(b+xp zI~V80xy~n=M}OpONDccKKs1|4B1J0jDW}98G!Os57k5?qswd!O-s6+-oMS8CN(&^ ziaC7snwLm87ao^A_kH~CM)(^n0*#9|=|?ZGRqAX;r$T-m60b&0w?G?~q!Ik?=K6h) z#*59amb!kL?v$hU12LCr1=HnQgCZug8cnktOBWfQ*J08P%HU5!m98q|DhhPKo| zxzsAP)M~KQ|8x}L9Pj2{IIVfCUk&|b?BIuY;Y?ZKY}m5R^zz2Z@|xy}&wTUpBWE?? zXmHX>!@|lm%IP`pX}tJqy0+?fqt(08lE+rRf_*>8)9HfH8mufDg8LZ~-xxy68TzO? zCd2xs#QGbH^?tu~@~rjYo^^?}^>^qS(;qhGrrU2!HokjptmSQNfA64r+W3sK=}czF z`t}F#sFjmplIJfh-``CEhOJ7mEhED%{$B)I^av8cT z+*evB+dA%7v zhqdbddm-sJ0)%tEEqzfIbzaAjQ8N4ST5gFaG6X?}#Pj>1s0YsR^bT|bxqNpz&Ifx4 z#wjBoneMMsF{tvS4>RB0L(hFGeq4wt9+a3r#JM<>0XlEeM`B}(txt>1OGCperX8rq z;8U-dg#$`b*yXn)W4(8ogpVtKkMjwYXPX~ECMTmF7P&$zyJ*Ebye(gExi0Nn&Yo6c z#ZOmGxqE_DZ+QPIHmq(CCC|nDMK@I2YvP52{QYftR+i+Clu?Q@dWKex0az0-F%VT> zEVimpLBW8`36HfJ zb#`?+_xAN6zDN;91b~h0)bz~s*XQuqg68Vl`nvs=)bqynU=J18*q;6QV|aOW$@?50 z1Bk6IFtIHW8ha+TSPH7o6I(yo_Y$dMOdApZ5L+wqsApmen-tI=|4eLC+y9j!m~j>W z#P&1!-Vy+8N67_zkVyy?gU5mH7-3%fzumDk|D(#_;K@-vO;^4VEw%Xi*T(HaGkMi0$vz^^`m7wNXD0$1>O3 zFkJU4)78QClv-ex|GE60j_W&jM>1eyYn1Iv79Y3~NLL2{TWT;hc?feIzFsKa#-4XL z_m0?R823RUdE}R8U@QFo1=#Ly{bR9(K2q6^R#t-$=*Np0?Ej2pq90pH)c=>*8aRAF zT+2tXP$DQuwd&;DO?%nc0^zaejqP)I46N#ziG;&tm>tXvrcOtAks>IW80X5oY-|m< zdI8lfat|ms-sAuzmRodCRFd!9Q~WGNC>EJA0m5SoCcS0NC&~Xx5qMst2$aPoRcfq< z^r&vabpJ{b<_wCD>wxZ9=_^w}W9!HXYVZ5+iS2WD?2_Qd%S+COh*Ifo zh8Y92Sw>iPLoY_TZiuUgIbqzY$M{jqFUG~FO8?#1{-d$w_pF&#dY5K5!}hE6YE~rx z^LkD?RwF+Px@y0zoZB-GJP;Ucrv%^{#4<&8^P?O93=lG zMNnseB}s7@z1vMk!Q$G>bzlIxV+Cc-2P!qsQiOW<{v$w&@IV&6RmKe!e|ggMAr1Bu z4`m+CFCLm=iVO+*;WqD~i?QF(!?=G+R5+lqB_;@h{;Gf-$HDl4B`6ct z&^rcsw1WzN3rU`h11HZBlSUCK3sLkI=b6}2PX((fJ%`5_8FZo~H4Vh@n&$i%U!(~A zLM`<90I@~Y_s37_bKMCPlgh^C{6;ti+6j`g4Z|_L=$?}M6I?YfZC(RPS-KQqpGL|7 zG`79W$x&Q4e@1MX*NAsZ{=nS_KT8orIng`#VHYCaK71p+!wHN)hNkd^7w>=Wj$tmy z`Ew~|i7=lFe_)oU_zEj79=sRL=&c{D5j#NOG$G379Tn-^P5#!aDpm+QP7{Lz$^9;~ zA6F5YM{g)Tq-rfLsdAtY)tU=*f}S5+A| z_YEpxFrV$ibfJX>t>PL_9Eap|k#(7g(q8EIvY8-&HJPZKq0Ut8i2we{d8oQFSipBP z@Y{Xo0=5%4TEfNjeS>%eP-c+eU8XlN;$_x$RJ$OR#CUKWoeq8vs0*>KBIx^34ju}P z7?D!d%fwciW{|D7D!eh&fYGgRNNcb<;qEB^a|_Lwd+%hAZGA)Ih=m4Ps!E^4Ocf-0+REr>s@i1m%y8pX zsiocF-p+mF#QbO5VnB-U6|bqa^~By2jb7V9bWZf~q@s-|U6Dj@X4372pk<>PI?=)(KdQ`ddd43l}RwwX>n_p62sv(p5AucO}{e^D|m zkowhO?{U3QP#LfQsEQzS*3e%|D#P5bfzEY<_%4(IsX%hMDEACJ_kA4&=#JqIV)`?g zg`k~UcfAEPwtFM%7_&q8@4?Ed@B8|Ko1az66ttU@lG_f59$LbB2cO_Sb11i zlvyk)!j&RGEB8HtY*lY^_n%;+<^h@e+n8LOZ5m}7eTC$zxUYoKbYT>OW~qcO zAYK>~g=b*PodVJbIhc(vQmo$8e#yggHpv6T{r~WePu0 zXAo~wy_@f^P-Z@gqHv*G{CnNd#v5O_wEgiIln{W?dgg&tz%nT=+iO^Tp78sTzp?QS zy5b^jhv!N6;O>5D%ZB}lo>m~_+t?0;Ef>bfsPKcy_?d0Z{V|fU_>Y(FSe**v;}84f z>084qkff%^4`eb36u#%~xd|*j6LB76t%xbIBNKSW6aChcu#365SD_vE8>5~VR-hNl zcQaxmv%y{#zR#?}}f?%Z)JgxMzU-5jvalQ)Vk=qHHCw0dVh(}g5+hQ`d9caH3&b&;#~kK0yKf-kL;hy3Xy6`u1I$u zbeO}??;;P$5L}{N$AFEkQfmQKDH1b5bjYUHA zQs9hhnlZ({H6>K}#_hw>Hxt)$?e(6+TPNvRWBZf9T)fMB64!j@+S`K0$5Pyf6JKeo z&c_DHf z)}e;@>*4bn82KB4{7w7))35x0;Rh@;2H1l5?C1C#_tcz$w{;t!yJqcegb7sS{Kc?> zfJiY1HrH+-6;@E^0Cr5`>$ths31T=&Ae_{>RE0l5WAksaInpM@gOv=0Kpc1_&l+32 zqiMTJ{E%9X^sOWUQ>w4>xj!l@LsX{H+c+F-M2Wf_pQQ+Gl@8qo3}1O)%5c(49n6$u!E9A;X{CIrbA!^l>{56q02JcBueXH+;rQG#3$z?Vxs zr7Y!;PZf?GJ6cxq8rbnnK$Nb&F(^W^&e{W5tv5 zk0<0F4f9RBO-u+2kZWVhl$a0@;~cq66@iWIJ=5#Gf;ZG=%A71d3ts*QUYuXOg}$-& zD|s6L#CFh3<_b8_Qj8-^NDMaT+++K^XU?XQpi`TW%~b?wY(2y|ypxKoekR)W6y^IQ z0vg+j$;6sq?ubI}s35cdgo8I~%kv!V3g^kx8 zGob@aj?*2)<_GztO~$MhnG1W4l!rRb-I>wsS@erlzTHl*tHh%9^*+Pv9aB4>AV$2C zc>f+*pO?;sA~~D7C|h_)qL4jDETu-GDNU{HFZYyR!L=Id zQQ_yVqH1pMXbj&4QHdi*OC=l14ARKa=6#dM+ttrI@Xf2w&QqtA)#Qr#!S!shT@v*8 z?m`J0XJVZkE4U`-)kKLQ*APm?Xge6|V8ZCc)mS%E5HAUdYo_$VGh+7QGV=v{X%T=m zki7Zx%tT%nf>OYue(`Z?=JB-Vr7nf6pu+V!^At57n>+Iy;LmW1MS)3?FsP`LPFYGN zvBxE`0?bv#Rb0E!>}^@xkX#H?U)(iWjCfN#^tz;sv1II9Nw0(zpsrZ1E*V}ZSvf1w z#4MdCLZ2e!2RdZcaiv}=DO&BN&|9V0ugcbG%P78-Z9A9ksiguM+hb&$Q)Iz&+VU%K zJF#audMfVBK>7Mtt@%6LS1ujJ92I3M6*>VGZ+SutckNLZ?GN`WFi{+!L@GNtv~d?Z z9r`i|nj9cV#HOrW#M~sTkqum-I&fUN2+38Xy^wckMOCwjq6{wGVvo8gRas2-)lsa~ zGQ>S$K!hy6`r=ma#)w>XNnEH{;v+bM@gTcoDne4d*Wj^6#``B?P_IcdId?^uC8~j2 zbgia(pFKUbwmP+bv6K#x+iYx|NmE_&M4g2sttC;twIrQwG2MgiVLw!%#**g2gonXz^9mjdjj9A@b@ad* z7aURq5|{=xYp@m(4O0ci8>_cDIvCxA$x1>>qtaQA?LU+dQl)m%nK{rNbqYvp-zJ5k z`-k?w63tGXvQ-SD2?>*4o9&hW)itC=6VnexLwhg556_IzK`Q+}+zbga>8 z*1rQ~^G`TSysx3V&o(5UWdXY&1ohgtNXn{5q83iMK1pIbQQ5lo0X9{u>?nf$C{IDR z(WySW87j|aX>XqX532qCu8{t+=>Fj5{=k|3a4Gso;(=r3foxuYpU>{=K&KlFX4JuQ zo>k_XzqKp^7@<5Ubr8XEF=}y87HOz?*|XX;E;S|2o7Su`bV%E2seo>Huw{wC@w4eZ zSk7*^x@maQ&Bp<0ge#CeQ*C6)++y}|*|c_K<0I#)#>!d=*Txaomd5DL65<}cB@n_o zT2eU~Mn2<#JLma*>8g4?ta{tbdrztjKZr=5d9w@wZRo<1`brS`!akb^tY8D4bxn(4v2`V?g`C zl(w19G?`sl@m>n@_2{nRv1ihXJ>!epmY_K?BPxl<4Y7Hw_Rq5gg>*`^wXSQjZW-yS zWl$z5d={q3wD#K_St)VW`0#z|9%69y+retRu$~JJ2}87ADnbL%dv z^Q=_J>=#{_Z+v^E=Q+M^dx2VW4#RWq^mQaiG!bdiQO7hf((`iK^9f<|$(nTbi}M+1 z3pcR&Kzor33C0(Fk+c0%wVNERfJs5wTS)yuRX9WK6Jt>-6H?-#G>ReZTggbud-X) zmu>d(gVX4)?Qa)Zg;@uTJ!I8L>#wl z9>}K;>pT>aQoLGmm)g+5o#sdF9!ohxL!(-coh9+KiNn28$CJyCVAH0>@Z*WoM^!Ghc&pC`7NviSh8&FB9|iclf^ z3~Xzigw>l{TH9WCbar+3^!9by0Kj$->o*`p_$@j;Gdnk<07wy579lu*72#!LyG?xf zY()UVV`tJ=&r*b!@YoIJHC#8IrFMri0*au@|4I=mvwMQS;~Mx@ROX0;ld=S(5>y5M zv$6eGV+$VEjy8Cc@>zZ%cYtMAI)m5eFV0}~-bkhh3y$=lBA~Gax?}&5B8aqP#T^8I zex&(-zXzWGRvS$gX%5xBOl$|!{?XW899&JV9U`<5KtY~}92s@G{Lmi0^KdY2_Cyeg zK2L17pDng4CG%hPe@A@rz(h;FH0sJnDA0PUw>_LK&}mA4O0L^oEU-Ep9Z|nIS!D3u zh3C_7gjjC$Mp6CXyLUX_X-}j3g{}#{I-INiA7a~tiJ9tpceK;@4#( zwZ2FZM4JRWA&{+C_?gcd+y4%aVT!1s)O!o62uArF&&oi%VkDo2JAM55IO0h3igs^Mue>b*h_1Lzv<~Pf>vRTg?+tPZtf5KxJ zCtd4-&*8DqPvO15#`}RK?TbT8KH@4Y$I?u$`-5C$i*n$u3yGOfUi0yIh zyX=P(ANs0(3SeS8@S)pKA%LpiMsV;v8??bgTP6I-jlMzABZQ$%{}hFJ$st0DW$ic9 z$nChk9v|Ck?y5A`QT-_&=S4T5u|0j%gFM~tuKIpKM4Ivtd_c(*WB?|%glC?J`hlVX zodOY|TV51cK~j`r9mr}G-W;6b@a&*3nOnJ3`~<;>LDsR@%ssx6U&xS~AkX2kGe5QU zU^P2lW5ic z1gi||8sd{D|F&deE&3vjulJg0_ELn+XbJ7t45)WC^$)v+@22HWVCsrg0B5gP_}iQq zk^|cUt_>t$V*5;Nt9Vy+BAl11`$gil10zFoDX5$h2!;RcjtvY*%7_VM9OZfm`id*q zBMQ(;>DYlzYIvU=SC;^i%Wg-6PL1nvDgk9 zP_n#=4b4vja4V+vLGr9d2aI(El(Dl-GHrW4N1ym8#2WhG+n$sm@O!dIy7C~cESQSN z0npe!hsQ$SR0Q_O{@gZE`Kvfn8QD{6BtMjicsx^!dtYkC6s!5Xu?2{2&?ueeO|Wtc z8+hEsPEq?6Kx{?tKlu?H<)TX(cfQT9j0a!lF^27T%ZN-y&)4L$#w9&V5z?+h4S4`! zYa>#VP52#ALXvg@)C))v-k7L|6e+%9tSeHpGcy4+wnLQlWzL^198rpwA4QZ}-<*^f z!D(#H3@Y`0Ww4G5q1)Y&m>r5bDRU%AJGf2;&)(JARaV2Cz)Px7o}E+#o{^CI_RXzf zonrS&YMm#F&hM()J13^4U$IHT9vMSqT~<&^jk;!0&y%iQLA>7gN)N3wU?q}gjqPDU z+rq+i-K(PvC_9(PWpqZbcC<1}q=xnlcUbTKj{|TCLrXhl6h35A;s^zY9au^UzH=ml zNcAa#c_2*xwP%g(P*>@kB`tTe4mJyE#xL+q%h|{fbSS9%{%urnWRmV{z)nnipd12) zUg3$rlf;l61r(;p3BJLkzCVQYr^;UNa1js#ic{KOD(1Lk+HrSz-;jqUIbTX7)_cQ}j2 zB?YWa^0yT1hRW2Nqj-e5yWgJZmzfjddkVD|iWjj3*{^wvT)FPYBU^X*U})())d*E# zdoKBs;`V)XpAQpiF^WIx81^N;2P^o+ z#pW@i)l~$9F{Q3t&h?HO%O;GNWkB13eurPn7x1#?sXY|VjoMG=4;~k5UM;S!6gA9V zPg}cuFWF-#22T!Jbk$xho4L_#ZKySZ7n*FGM%cCP22bBVUX^=&ENQn1nDb^4s0=YL z=_LE3B4s34m7WQqzo36;9#%_rPAyG0wrQS*p$yGh#XUcO)Q zswg1AUnL?7eW0_elE?42Hiir4H&5ZgSj`}LGhN-m@Kp%*?XhLV!y;NJ0hqs`1IM1x zbjDE|`9bp(7yZ%i0#Ot#hNGJ(T*gi~wC@n=yeq=6a*Im#P5|7{8#e43W*pj&6ZmwI z`D+Rt^K$dmo4ZSpY|8=B)|PxQ^_N`XDvxX_7bTg-xbJ1-aX*uOs#|a-XzhGR%%L#Q zj=#I@<*`YIECU)_?sqa&h`e)GHC~p;3vzUrf|#je()%9nXtNk?w*#ts=S?i%cMYj> z@J8H)MFCViioP3SFY2yw6 zZ2^I;7nBea28>yEycZ#eX~5s??VQ&LuJ?NmmI++N4|^(HG0-mwkn&TVGGs^j6}u&jp(R{^ zrD27o${r$`GEx+rRR*b5u7K63jg|f!GC_e=Q@a((jg=V(DjAhEIXl`1Lq4hmK3a!> z<4K6MGY3D@YycxWW+Pl68(tuLy^X(PAmWrwZ=6P`ku9LHortrI4z!iR6O=Rznwhp$ z=+pdGAEa~>lu50n+GnQ}rKP}xYq0JH5L=r{D0YD#-s|}HJ@&@+Ka8nDp8P_r>qCI> zn4Yf#rhy1{zP1BGC_21j!z)Ka9GyCOB5y;{-$ssa;lo<39D~_)C-)qObaWT7oZ@c6 z))IBkyu^}sNnT;=C9#JyjJcJ}0UBFeN&(Wmdgn`EV%q?0aGeDyT@a$lYL#8;16&%} z;hXwgS`aAO0wg=?CA$pa0YO4PUX-e}fm(&@Z-*%SJ6HMk@Y6&+&PbRqq_D2o5FjY%%O73F%|6}fY|OEr5Mm9_fT!1*k*`8eNw{%qvKahqV4(~wp0vMQA+evZSd0t1PKjDfUQ_J5&5TzzhNK>QGtK+n12NU z>aRUiD{3^GL^QiwG{=UN-HL!#8Vq;*)I0J(ZxF^Kj6i=-;9z6w>nup%J1pBV8rw*Y zw5fUQSbWWd23ykHv?LBe*Zoggh4o#5R(EjcV)4hkXeZa7-bjG}%x z8QUKf9A8cGzSgLGt=)Avz~3caUHY zCY7XoPj((rgBQuj90{u$$!Q&lm=yW7DpG1962tfdHbEYaaTI}Sp3;HTSWPx}9n?Dl z*lAxDI&EtHE+(z}DChh1fukDT#cWLMPRtk1 z*zs%+ZMbJTa^An1hObtYuigo* zaUZR@v261!<>Uaplc2o*YbvB#oxPra7|_@r*gPHxj1zpBCa4fX&>Z(mi*nR_?;EsS z7_^C$p57m{OHjF8n7;kBQua%wmO~|hWxmlu<)5!Ga{7=T52_)uxfzdfKc0Su)KX^x z#5PGjGng!t>ESCvur_LNC=!@e1BIU-`FwMwNXLu+l)JoX62g<37ih({F(?qIS6*j#za+)skfy*M#vNr@s!sUixQ z``k{PJS@&U<>Y$jVkvsdTHxq@Wy{cltHB4QV6R4I&(O#Y+z=XH5dP3`6+p-DWE@M> z=*tCqqB237jukI#%&h}urhuxhO^{WZ z?#rNtU!8Nc|CLK^v}^YaOl_?#M-2@e-M0zFw}s~J82wry?vREU5`=n~M!6M~Hdi4@ zR{8!hh+Dr>E=r3vwvws@hZU-Ufk&JJDkSPl$Wvj+2bU_^!z$nmKUK$}?Y4`VF0|y2 z!(d`H`-1~&awsODC^j&8mk_nht$E`dwq%sGG8ZP3(xa9dK5ON)@v8Q{^V_XTm`@tL zvAM6HI%|J4^_ubMvjyicF6dVq))o6g>dILoO(iAG7s-F2)LVs60Ld|B-TMB3dKZ`e zz-CHV?cUI({u?Y&ry>ITyqC^bC-Iv zf?cz7QnPw(Gsj%B-c_^9>lUNWEmM-d9nLLwanI?o;>i}xvz9d%?u{nyE%nw;o7TRV zRshfDjkOk^wI;o3JAWu`k!v&KD7!^LyDvt2L_z=CRQBqz47PcU)ez%R$Og)`9F1q3 z`=Z^Fux_C6EKB{NJ&wOQ650!Wd5iJRo4eK6l=;k}DR&bq; z?8|yX*fU|(qy9Lp{iLfQ6|N8>_DwSUyUV1BIThMiuf@|$Dvrdj;T%pAGRu+(F2eV` z!4kG5681~)O;Y-}tNOl7^ogGLdGfe=^L+5t=pRhzk0hCQ!-S)#n2C3rH;#gdZl3=r zK9K%CW-p*2lzZW{W+4Cnk#*K>QTBV^MY=^r8U#T~Kt;NgZloJTK)SoTyBUV=p*x4} zmhJ{=5D;mY=LD~7?|mQ7pYsCd7+Am0cP&!S*z^80H_yyPM7XZK&p4!;v&Vzq0tiN?iA*U@S)bCA=S1a zz@jRLH2jfvSY3FS-Dud}cX+ON*uQg_U$t2Tb;Rz?h=kb4&&B4Qlo7Fg_BeNC_ zu@Y^uAAih#T&DcEUR3+N55B*(h9ez)_I~t6V^rR16g73UwSN>(+xF^sw3luScWJHt z``D+zv4NT~D(!X@)AHA;<%|90D`*wuQfc(08%+8gj4XI8rMRcTb6nc^)NKU(;SM}Y z4wtzO9A=Xu9-BBKgwj}DQqp0riH={wtA;qHlo&HVK}DyXoa9ofTll-@gPhb-Gr#d} z#cp@c%T53CjtK2?KCIcW(8j;Ztl>k3&DbsX*lLkG%FO6P$-ga-yC2SY9wGt)TR*MY z0HBbCWf02S7jAA4$v79)QisqMZK=JhVhaClU=Hlzo~G5$9NeG5l%LPLca<|=Z0`BF zf4=wmLa{cap41CUx?i-ofQrggMlx72?bXTXT|D@{XE?sTX|Y4bY((o|%>7_0^&FI?LofMnOpG8g^*xnEfp#`~D$v`f$F-2mkI%==3Y@x7SHFK!ZVvr_iTNgkwLo)Z<#^|YGjC4rD{maVAT6xaGtH0d=Eh~#w7J3xw1@z-K|w)6U%cpwezQ;wAQ@#cUJlTwEnr$XKkh|PL$ z$T`-aAN0u;nUubob}U^`i$p0{(MTazDq28^{tw+$kzA4X64<_IrtE(*2iU?^eg0}}xgb4$e>Jui zQJF+U>X5ZSk^t28pw|gv>%qi1koAy9V*58dHb4L$%AN<(i}-j1*+Ax7-l2^8gf5=* zH#{cByh{}&AVS#jS7ZARvEBWds1p$U6G0({&?o78p79pguyBq#$*P6UFvV^J@FCdo zWo#!|o%e62yI#+2XSn>;*#0X;h!{Wd%88RPG0p{P7aHfKSV;8dX9PTU$4vGLa?$w% z3yVwlOo{~BuJ?+Idme#p$XmRo^F6?aU_f#3uf^7t0q(C9fs459p*sdUteMp{?S9zU z9@Z^0QT(+cG;Gml9yK1+79HUpKWuD|)pdRW;jtpi7QVAbDFTC4n-Q*=Rl5rnps__| zIe3sFV1B^)huDT$KYQHRk~&hH_EE)}_4Z5sCALk>2!F$46K*{Kv0dyOd6Xi2hB5Sv z3cb+k9n+=)Cbp6ak5Yugvlogg=6|LXVHtm>H5~zBtNnuFd{#e^*MUsPEc1Nctd6&R z!K#<>V$p5}>w*NB*s?D_J3G8s@w#yDTJ^)X;8>HVdH}XGGVL4xnb>ZU=mXuczfuHO zK3LyQPNK!*#bWM%NQ z6-Qy{cLxC_FY};~UKq=O&MPdAMMpr2u$U6-eYxrQ?w)lw$hH#|uJ+gc&G8K@f&j{Q z#ZPxnfBuNN!xhgNyT|Six)=F}*h-O0-~y6bP?tAbunwXlJU_a8IW5nexNKNQd;a^M z)XGmNPzA-}pC(w*%lAttia2!?+I9P>^Jl6Xh;=@6$BZjNH5@L1UzMMMJZ6K+voSuG zgeSnn_BGGva)Jhep5V0LEZlstZhG}G=4^2(JV8Nlr0^(mxX6P!i`N#(r8Pa=b-JprT$ z0I}T-#Q6`g73b60iB0Dj^W&o$kO%L?DsAh?YN$8TK z{&SkB;4>cMBQ8b9PbbmAu=Sz4Ysi4>chczQ^W@n{YWnU1uv23!TNNFx#d1Ni*K0)% zjBXmS2aT;%KG(CU0tbt|)FU&RLSSO+GNPb-Y4@_^9POPs@{R;YSr1QYYvOds*+WEP3oGH?6JKi_gAocl{;CFN=L-L)@5qdHHh>=-0ntZUs1?Fo796eWywN-a4zFp!1crjz!Lc~EUzIMQXJ zD(yUje||g!?@@}N5*q$HoRWBNum^`$d;tKqq%5d9_e}7gVTTEx_xmLRi1ivsL>Kja z(nliN^06pfi8PpIM~I|-nmg*FFq+9jag;h}+>ypmbn zcG0Xewx+iEwyP2GgvmO%9o}Ma#TvM1i<^!`)7y$6Z z*4UPjBM8#60}lJvcwA;tUE?BNi8Ay(PXtA6e0WN!GPI5d<=}HXE(MVJDe+uNK9h4GNrwk0^i$z1Z1UOg#YEiJ0=4d-kI-z>T!6+dWfXOYgAD!C7Ix21o%+{oZw z;H9-tm;&7~VrP)M_FI<0xlw^K=S-wSqawq3;}kZ+;_&*eb`?H*)kUIhvA}NDh?5iP z>?f?)4Sfg`aJMJFJT4|mgxxSSR{)FcKzPHDp-daHL|p?z#TD|~%f)@|na0_rj8R`1 zyI(|0ey1@d-tBZaX>f^emq4&hF%f27algiW#OgiR<%{=Z?p_~v-g_RN4k(Tp|+wCKS z#v4EE)=Oc3Bej#?x1lngpNSbq#h{(?vV1pX_cv|KGi_G(e*fE)i_(mUmZgi0rN_ZcD%MQC#!Ts_ z88t*{tX644#N5KxoJm!AE`fa^PkDJ-c@r2r5C0@nuv-7)hI4qrtb6y*?1RYOcw5u|Z-tm{IGXJH{B?K+4e zj*%aTDhWi;so~sb96eE-yxEa`MV z?Po|g-$Q0W;kV!6-+p#kz6@XGAkTAjA&zk&?Qq$FxKz|d9Mnrl<4IQGQ_AH@)`~_p z_qtxrN_Mcj_0L4!Uq)*9P#gBR>1|ODqqw8exvwb7Oslwi3%G~+xG%6rN8%1Wwg}fjmAFjw z;zX0$QT@_qso(^X4^n#)=&y9ChH?Q?CrHYk^2Z9~)pJS$sbS-9tFI^oOhsWIWQS+X zeZ|nRdEsqi7Zlhk{ETti=GjSrD?xIlxUD;C&<}fCpFZ2q7q)(4xbv)bqWCE*@phDm z!I3+5j8uXkP)Zyv-tcblC}Ap#&{zIV!7NmV?{$I(DqqRj!OOc}X){7ffr+hJnzCYO zErejFAPpxW^m%P))mUiDWoXm0unvx}KDn?T)?xi1(g%wzDlB}GBLi_j7tJbsB`E`a z{uRb(_}XO#4p?sk=#8mn7K-X0f-;HFDeKQ(H>gC`t9(~*h@=94@3*76t&eQScY~YD zVk$Jyl8<6`i9#ueVl&CMLYs1;!r;V?XXPu^Pv+)5&uc#PaOMenN{YVT%(~izBy<6KhbA*j134 zGnFBXm*b2FUImnsSX7hZ)tyiIpX0FNEQtS@ zn1Id&ND(~$aQO=RiOeQ?6BcH2fi9InHvu3>NZ}I{7-liORamf98Bx;A24)J`l z38?**%>A^T{gb>-pR#FUw`Gs}^Lxs+dWsy1z4kZzZ%@j`Im^ztgfs#LGlEi`PVnC7 z6yFyLN$ICOw5^as<0}Y}iyYCD9i!!lcKgephK3#yemkZkJ{3>@W1Md1m+qL8KHQ#u zcO?pI2z#QQLG4-@VwVAHtYj#9ije{TjHrrP!{x=b9zUKwv2G^UAO-P!716vt>2(Ad zz3cg$;n%gMlIjEL$NtN|o4fTvUcV)l{wc=gF$IPR%IYY4Q#A|9;-Fa^p)$~H~Kt1F0b!< zu}0uLlL0R?69o%;=H~=JLn*&WIp3kt+o|xOKqmJ)--`%B!vWEHnGoOt306-C4N(qn zRE|{Vh#ugGBZ5ZT7E}*%f?c2oJq1-0iRtu(Ey;d4E|z)dJb)D8uC@>w)l^^Jq=uSQ z-snI1F)7}-XricSS~39KuWqD@wWom0c+-3ntpNz4H!zal_7;z#Ki|?QIap{RiY|eo z@h{GoEPzV_#ab^haMvVCLpfeb)4;T0$))|`+R>1dUwfsf#ihW;7Sjw*%Q1EO%Km9e zsy@4eStkB!a{KiYo!}?J@FL~pBpp_DX_aE3Skx6STt!|EiZlmRSm#u zq$nb##BhESTFJB6d1C#Fh@|T+6z<9UDiOCXUgfIK)cQGgncNx@e8k;{wAD zjgHlC)U&81+`1>J-Zp-hm)^Q zQABS>9Aj1V)<#m+p1aQxD(ei5ag~&FPxka2l=CKj=S%$19YZq83*MIx9jp&0W{zAy zihkR`DA*wIy&>_fS&~M)>mCd#g1Fh76 zwhcY0=N>AYC~!jKhAu!`p+mp%np&$Y^G%w@iwlPq3X$-OMw6|^Ws9&?nrCi?zx5Su zws_+VF7iCEsZx|`iaq_RO?}`oLnEbHr}+D~TUULaY5fv6WaBsT$vqb1 zJ!VbP*qrWGw+6c0y>_YY4sJ8YalJ02^sY_x?svV`#C`3|efAoC==ObQiG43>`Yvbs z_D}nOHSG;^KfF^tic>#hd_P8gf68rrI_3bBdVp1MAeYBXp`byzVc^TeKSuGq4e?=WxKIHw0xx6EYRXPPP?7sYGG$2pBrReI@FuLZ|0r-|@ZMO-Zigakj5i*o?FdZVkC!P2xJ;CZe!9l9a72e6?uFFR{$#Fj+ zShB{Wt(TB9`PrgN%AJBL#zp3?OK!MIv3XORT2j%hS~;wna(+tje(KwBRrACQh8 zC@h{=Y@1ixfXxphFX$>j0wfmR87t`!}?v7CGN-hsIj|W%InMN-oUfd)H!KaPhORnw_jUn*`!z|k3j8dMO zw*fb0$$j>JSW|J+QuPcG*0oRk$J*Dg)`-5QyN@ZbM_#$q}9+6reedcXV&=_m;G>oGd!m?p)T2}K#ECyd>0 z>;)NY4f`o7lMlR)FO#2tkT0#r-;FIGMMy||lp;K6Y{QA*0gdg06yd+bwgw(87pb(q zu&Jb_4w{ehu(9py?~)lB9{Dk(H$E{T`#@}`#U6<5qRPX>c3lLJBJA%P9Q`^HKLv>G zDbL@D?VUOtLdT9^dB(pQ+rQm0eKGR5?!Qumifqwvip!w??T+OF8rv_0N#a$26yYN~ zWGpE*ZzP@D7yc30W(%;>Y7P7=MUbc|oWhZ;5SSWJGFBu-bVFRKcd|lJyJ$DUSf<4&aUQ#4Jm-CS z&psp5ZAS4sJaorkuZ??Sq*xxU2v<}HkKr*@UFV(zO^dlsfY{P)f%GHjdXkK?)Ox|% z)w^5Cmhu$aKzNL9`^Dez*!}81QUssp-ySr!E=B;ITmv+=B3$i%H?|-HiCvNuhdsLd zXMPXFHo&E;0FqZoUnu|B9jldSf9#GuPHam^&H!TDhWr*Fw&)9858bhUHMUF`Pbw$q zxy@^4*{n-y7qv0k|L?@sqEX3hfeG-%n zo60(_nVW!#txD$m4qTX|nRPdTq|}EVV$%a_WOC2N4}DaLW~cqM`TvH;2p3l?hZsC@ zZ2Q?(G?|A9LC0f%H?|qoI=@lG486|Aq~5t#kIQ~Kw3|?Tn|e0+xUp5X{JXJzAhzag z<4jViZ1ZNGsenx-QzS@X0lxf&X4`jOj53mJDcXDYTMLy-}^+Dz!Hk6$2MG0W=y*QFX z$R*JoJbnbWeX&`RrA-`M8vj8aqKEm*y5!vi!wnaUJk&9&*h?0-dx>KvBtAp?^=h0zqjf;`SbB{c=5 zih->nhwfnumkH%=^n8w9!eXOGVry8F(>-F=P^GaS0))o^VjCc-eKwHabkzODZEjHK zp*x1+^4|Bu&^J_n)o$QHAXw`llW+sn$HZ0{uB52{eh?zU4rpxm!t{9r)kb94Dop>itv4Z zUp+slVV>z(9HpN&)(Iz8`B|A4mKil(6#Ck3yz>LG#UE6aheL2F^D3qzBj%L{qzL_O zX$Cc-;eZsuErT@OXjoL8GUFHNzU1MJGIaj(i9Y!iFtIh1TnIk+QvT2#Q{noIbbVge zhGij1B(@0td|c02K#r7Hw3u#n+%Otmiu{Qq{u%f^gT7j(gF>Gc?pC+|YICTzDuFh^ z@^RCS^e-J?>PC7L)qHffrWYdCb1p)}F;M){-_4*R`V9i$un1t?TUs@$iO zL*ygdWjo9y%*t_I>>DRwMfg>b9k7wzi|sfYNzN2SE=tlT049j0HOL9!N9@P@Bp*Yc zwHf+ee1q8fv?uvCCnA(wLN4Zc{O2@4W9#-t#YQ|qEa45~g#MuBR!pMoeQsQ!_|I=d zzXyaq=P}3c4l%iMg446|KxN`vlt#aYR-~%H&cY*XK>c_(tSV(Yh0)@}e(J(NRqX-L z9lLQ(yTm+ex)$GYd-l*Bt8OFNEA!)H&H2oGqdC=ZhmBgI!~S^I;ur-}wJK>Y^WHxTtJrn*z3$Ma)2ULYH%ppV14nk9 zGG(kfHBH;nES+rU%a5r9(-knqc;sE%E5m z5yuwWy?`i&sqWHINwKpdB6p~j_cv!X$Z{U{-L6dfJ8bqU{8#HUEvXIH#^>B%DjTgf zou|-QEn6LgaE!1ZqWO3&Jp(s+a@Y_$eEsSPEs7ZIVr&{kD8lMMs_PV z&QtB@^otjR-IJ#YZ+`xq|MX%g_4!BELAT+LrnbXvD!-EhVOyL4vE9p=uBiQPxV3-v zV>GhmY&-YM-mi)DSy+Bn-H$tOE{1Q<^o%ZPq>WEStH*I_&V&R-D*tFqP8>(J-b&M( zL`AD-vl06YT>OAZj;@+$z3_r_GF7)#;Hxo33Nl3$V{LnsA{go^iu)^e7?^cUD-P6} z5rNE9g_TCny~pu$ zGxZSeE_^@JqS@%6pXXVMIQap@wq1wkNg{fEh823R71p+u9-Q?v8tc{1*6VuKKYgtY zGOUSbtaU+8OLLLPMQw~g0Vef0)cAfDmjU;kHt*R3?NkHbe6a08!sT6i!9Ekn(QE5P z5cES>i?0`V+CGTNPD`sINOUI1{+YJHiNNNY;Pvm?vW~%^S-Yc};KMgxqcZJPQ9}49 z?Iq8I?*7;pd~g6Jwq@Q9h8H2IwGNdK9fM7snpqudd`H_}5r>&jYd=TgTE`C1EB9?j zFUK(C*G>S!C9rV<6t<(Zuft}XBJxq9@SS55!#U)g6C9l-I;g-XF#XhC=X6J8Kx3;T z;F8-*osUmbU`SK6Em_JQ=?U*zF+*D=>RMYD8SmrTknft?;X1wPI*03qJSW|i7`5T& zhB+5C>}c5UW4Oc|Jpo7&(2S-Nqvz_P=VuLqv27Z;gKZCj+?d}pF-%v+ ze=g+Si+^O%`^aj{j0G3S#c7FkY{H!DRl{bAj2c(23|J7@P*J@l8seG^6m@OQoDt$j zddz;*dMg^okKp-e*ej{;a!eQ~Ywr5!=lXo8_c2KF`JR-(TAyIXY2g^}o35Z@?QFpT z@%>q=;wKBw-H>?3hA!-+DnS7930A#D#<+K|s*trp41}R08KTRAtmIL#6jl9|L0GCF ze|1%C%|2{x)PVE%0U2rmhV=nCYGA6F0JkJ?AtAbrQ6R9)?C=j{4#ed<39MD)_W>n0 z62A1G<)^^4n|YbyXA~s19Yi-N5MOVXRG%_b5X^g~t%M?!ewh+Yk(xyiGQ0a#bK4%c zd?-H=Dkew+)U}&vp>-cZcan7KR7Lj1MH(O?P%*L=j`YJPVMJ_Umug`Yz=1F%?0HAn z@J?75Zul5S_(OM0Oz)vPCPoFI_gvfv2up;Ja>Pzh#2zhj-b{q~X~Z!>q^m&WnNeiO zYuBqC+FMXo?0RGdd{oZss3L)=3Y#bvFzhY5b9UEy6qk$JzM|nEd-T&QH+)V&iooQf z>`u}jP2P}0e&tR{=kc1;7~`ce`uE3vT%a+-RgC6*?z_&98Pu^~C73bF!3K@;PoqpL z*}OhAunLNsii>-pUgk-u+ys zKrfSiyay0qQX(N=k~m*-0e0$c(g6ZkmlmAIS=^XgI z0w)JFq0S|l-cbk`U&Sa%dYHG zmkLtvzYAT_r`^t%ZK(kQi!}H_l0$J)Bv+ANXz3@rB4=~uJKxeB{L(ui>Eu1>y*ug8 z;4|=FXCO#qgcxQ_fgZwRu`?MNXBi?f&d*IGaJlsHTr#r~Gl>T>$<%4ciLzerxlp-C zT{=DJ5N`Xj#y7L35VH$jXP3)oOK801n6GZD%$9YP+1EE5c^&Cl}!Vh6I2cjO-!dU`PsO!n8<2)O>@X zzfXcoBV?beaKYkWy1=2o!12n$2M*p{0}4gp$p=FlxiJbtREy>@g8D)2Md;-&YL#GK zMb)BZ+oGkYqQ=IeozbEem#1y>)*b4_K-K3D0z&OVvui`~2vN&A^!X@JNsV($T~f=_ zxRL|nAifL!&onQCAVH*lDeEq+{hZoYMWu)Ht@j#&zXk-S(8|uhsaZRzUk!;CIf-ue z%CJcs;BLywIm&TUNKi0H@o!1cl0`5E%dz*%aWq7qzYW9P7sbPHA}|#r(x4y#zFjvJ zVU8KELtziGF=`De+65#aHYPV-S$tOcK3Si6FoI+ciFHAeJ(-5HsEQj(%e!ConYfxk zqFUIrI^U;yp}JafzglzXiQG-M4O@-!O}0Q`je%ygW^%N4virA%o`vlkS(Dmz$65u6 z7!%hRRTtwVygD}?&x;E=&mrba>W@!Xn**AjeJ{^bn8>Tjs}IGD<9t((PS9`B=oRkT z4=QHES2c?qRKz1N>rF80#Dfg7K@y?yVB*HfJV=HHC(RBdD>NaOc(6cYu-0wR(z(Dj zw;)&+f#?|Mjtv18+b+$a9=D;sl%av9p`pd0k=r4lJ2uXPo}**w*#MnQ87>-y7PP^J zJGh%V;6_$7o2G1=hCde#K(U61u}567M~RyW*qeXLHc#JJ&%6G(yv12`?Yk|u!GLSo zARdKheE!q*#du-h6nJ!Ez6Ep1R^_AwN4ixwF=!*C^&Hw7YgEc~)=J_o$c6iLOuX&M zK`@e8*_lL$nqygBJ<;k_8xybaGm;5)#da2H62e=DqlWh7vG%o-_E#hwb}SvPDjn{2 z9iE9DPb)hZ7CT;@b_AnTMzD7#Dt5*=c5;MOau0P1Y;~%^ckvhN?{QQeI(6B`bV)RI zDNT3D98^U<@4lg}R%D=89->!ec&lDqt#weX(=?+rDD&xh2A6QwkY{#0v1h6d*5kL; z6GB=mx0j$b@n3zj2)eAa|@ph|YRq*7rMbI4mk#&b=j9wo?Vj8#D7wP5| zyfAMK?k{)mm*E_6-OE>a)8JIcZ^18>~cTos%R{Jc8qCx>;MUt3eR9aMQ2a# zzL8`tL|-Bl&mZ#cZbO%5LZF41Rcn(lg_I+_os0JyPdE}E7NDzmB~aohG%PA2tt-Y$ zA;F6zwKOTSq$|s)CvPsU7_O&`Ma5a%xeA$*?U*Xuocf9-Dd;9CY}TbOjbyMyVK4UUqmP-RA~~CIWEkM?9%OD5y0nY1 zF^k078$oRx>E277)O%Fdo7B8V%3A0AHt)>Q(;kDFlWwh68;vQqukJjS{bhbkSiR=P zd_2iQ7uiBpIO}txg%}J-3In8RiQON4vA_*d?3R!Wg_PYkRJ*~r22&R^elMy0 zj%y{ZxfeLGF0VHq?P(7mFhT38mQF^N&hC#6BNF#ge;qXc+Fv?4A35^s|K-IAn!#K_ zjvOvfUx{V4>dZdI{81QDurkoLBI7l(OR_39I&yS7GS1zMHljYWzxq1;2Rd9~oyRF% zE<8cYDSXKqYoO-4Uu$G!>nyGOoeeLk(|#LMjM24dt@w}KxR!qY(fUsNOcuW_g|>{N z)E?zvCjeG_tSH+S>i$yzPWMkdtSk<9Ij&LxoE z6!YC^(|`1Cnj`l;ZG@q69q;Fp9&o>`kK(x%;;gqZx$RE7l}b8z3Gwcj&aajp7fm>c+JZ=Q)!p!4!*^Xp(~kwro5;KZTD5--;nDRh$Y*D=#Cs1)q% z=-1`bWB69s9X2XFlaHUjZvec1Frcvw2@H)2^9_s-PKb#BCx=9*{M#MNha@8v6o;Zk zl$C^4pa4>Y`i90D89<8A)~wgr)g=o6+W}aw7(i@ChgBXnwi63jG8+1NgW$Hb1ceULn!(`)`8DZ;<||4(f7PUQq2h%JYyg=|$7 z&6o7g&gfVYc95|w;u!k>A-47=s1Ox){TeV!(M+jMyEbW24a3|6vE?09-k-&>TpIBI zSBmhj#+GlEn?q==-G7aYt+<|Py(g0LV}g`(<=Oy3L3+;~r3kzZ4^o8Z#=X%} zRF4|l1}X$u5jsGMAn)80uc|%QnV{+LFtPQZ>jCMKr8TRbi!*u#|cAw0&_4iMW%D+2m13CN(3F7KJ$-fn(|gG<+g z#+JT7{;$SXqWw{0`$%kyNj3}jOCLA3ZP)W%|88s_h%Fw5cU33ff?stPpQ(BEgn=m| z;^V~jzfy!P<@S1YXqo&gVjqZnu?SF}_6*BC3SXukUYfb-l%y+=V7V8B= zMdu5Zrt&TVg%oRK0?UIBy?-^f{{UN?0d}uN=H7RPIKTToPB45N;;364`)6W{Vm^lY z$}Nh2O!Spj^_UoYYW0MqXvrCDTtSkQbwW|Y{hy63U`2Q&w&$}<8F&2il2y$P3&K^0 z=ZkU^q!&w;t&Hr;uKVs6%f<*tj;nyi)@e16IHGEY<&l!*+L^N!I z1(zFs{x7kWX(R_%$)IhOLhoI+Drfj^4&z@4h#xdu9C7?At739HhT@mqob=E{-kuJy zM+W`w`REx;6Qmd!dlLu*SYi$QiMRUt~|5v zZ$&T%RR%hQsF|V}q%}i<_Hs9UPcEZXk|aQEg&C2zLUk|!jcrh3*KBuKWagkQOSTA` z!B)6M*oGkw0+?&QA|lT_oa_Q9L0wz3dmV(6BZ!O5lWzkP+f9nxPO)v-?dZ|52r3#v z(qq+e?!EpTYIftaOQ+LVxV}hQ(WF;!0IhG`ILCp4tHg(}u}D;J%>nL|0(EHd*VgnOy}0*cvN{j`#Ezta-t1XBqjb^fIhE@#=~SjKhBFUw+DLbYj2W||Oz zi7g;Sc&9YmiJkDyzaLi@ZIG_p!K5P1;z0NFPgPleiOI;41BjS(p?qTDBshG?NQO}j zRYq*8Q2kFKuLj(7;dymQz@f2Hr}{*fgmS3~W3htd{@nDyBd|5ICtj|lR%sY{Y2h}Q ztbIdW-*ocF(n(r#4O4Wsi%{7njyPqT$WXOMJpyK%0;C0=anB72E8E5?r5dmg&W*U7 zS0%@jp156b&kkcdrz4P^1hCJqHPlv@FfyKNb8GBOo!1V!rv0g&X_oPWf8KT|MBT<7 zd=jr)e;`?E14t3%i+wz@Ag^e0Owspx;61JeOPMZvwO}tPy;k33I6W29Mgq^EVj}h; z%y74#*Vg%*WQd|{ORikcJNn9TJW;*?Cbrj!g(yLpUJnynXjA}dOFy=2pUx|`OIqQu zaz7dpAu5p%44T$isw~Aq^e*)wucos!8tc33qE5OVqzFj1J!}G7-KLt^B!-y1M1#*F zvof=dd18Ao_d-KDK=!3Ga($Do*jUc*1Q>iAhxgG6qK*UkLxaAg^w5p_+Tc?h|4 z&|*ELw-X&;)~bm3;;$R*FipTd>_dFJ>QJ+ zzH|L}F5JVEaH4Al8*&{!ChN_d`*2L70Hy$lZ7+M}X>^!AH8OqsqcujU zRzIOG{X3H@Y;g5mE~xkG)@j}8P^nZE!`zSuM$^?DH0&eM*3fJ2g-<^&KT)Sg?{0sG zS04os1w87Tz`Qph4qmz)MtbW;kv-JW1~Rb;G6`(nM{&l#s*O{&Xwz%GuW(J0m`(2W zO`iChAa_y7GR*q)$H>k3FhCs`SvVNm9DF%IzSKzXxFPa4YEC@1Yp{~%G8`vgl^59@W0 z6pIB=G!=PY$ zn{Xr>Y8o37N6y4}wGbn&H`_KqmI?$?&!$vQ>9bAM%UcbZ>agj!J$+~z+p5TJ)>{4DQT-GaGJrf03Y`^BXzMm!tlY>RS zoO2~WBVsw%Yr}WT;TJ6#)9Yi8p$aA%bc`8F)E}*j8KH5XT#JdebB~L2pYL^ND-d7q z{k~Qg`{#qlrlH4YIpyC+I<*lTc{7)SQn^S7v{i_XI=S6-a*VU}x1B?j;1&E^HK z>SgHVrPKcgz23`c+{^sb%jUWFj*z!m0}Y;&cW{h1QJ=RRAsyMJH#q_QYgAb(4q2MZ zM3h_~pE+43RZsvL<4b$S4-gP5#5dv!)ZXLUdF~t6ATJ0^YzxeOIQWg``H2&JnCbD8 zhnRmM@XzJ+R{?Q_`livQ`c3 zQcLM+2(+iP?hjTOm=_lDeGh4j7%jl{`V{}@^oq@h@6 zw~(FD78Kfanb8GkYzz6c1H*P~!}Mt2dg{^sWQQ5`hPAJT{Xh*LAP=7q3!l~rU-Al{ zcfww}%vvFc_{ovYqMq%p1BWV?%+;73SO=#}9tm{E1n8gt5fkKZ7rX@JB+f)i&F6ga z7Q(B=&182Wtrg01j8YB3E31pru6EH>*Tn%Wwh|)7cG0+mdIlk|XciGSQ!Y^wXFZ@j z_J%XxZh(l^IiHS`n4uwGTG@SKEkBGZR$e4_)jBo+Ovc&pou>i9M`yrK7$>+(E^Hhp zYAh*H5GS=8_XRE9o-JNME&j7jyy}&dI-RtpnvphP!Z*$Y-8L_SBx<9i1QTZ(^SJ~| zV_E{*#1Q$!rfXWqemZ9~dRJ$9_c?km=i(Y>&;U9^;9M~-l5brAD7-e2 zbsCs0f|G!wd(pn6bqR&*(YwXgW6XU+7pk~f|~h)s7C%R#>;thVsvzZYqVZ53^K45IXdQRiL5s! zSxA0as5w~+ZCQ-y{O<w_gKHgSoPc0sog0R;u(}|ZoU;U1J>OM@2V2 z<@~~AH|LOin*RK9sF>F^$$N3A552hGHECcY^k*~-l2HxenS*>ghkPb1z+x_VAzzT- zQgEDDAk$xvx>s<8QaC_WC~)eTi!PlnVN_69h}u_JdR2s&tVMz{pT;4Y5Sr z?=V#@M;t8YNa?if4(z*1;bll2GiJxcukZq;;3ZcOL#>H1(iYX!D2daerz&KMgMNw! zzjf_aE#^9K=6X+KTl?EKeJA(|tx8X`s(K2>199r%OV;3hn}JAQ&A)Gl(il3X7y2d9 zPIw_BC#qVJy~g9VH($0Ul)TSpkuOvB(@|B;`9#gt@0z=fFx|JG_4hFiTx*Szu>jTW z&SXPl#TfE3}wSskZ!POPZ&l~_FxJ*-`fgxkec;L0Vb z{U#fi+ZHAq3ymsCjKU0V=p)Ii4HQWZ%}e8s&RWQ0rOqc+b0be`EJ_}x+y!h3F%>t% zU2@QY56}1rB&>j_40?x1>5-SX=; zYk4)#El@3(N-ym4rIBP?epNzuqw*7=yiMKaCd7Kr1j@|h&ng|-48 znj#!lVd~yRlpG{gtV*`uMX}H6co#&&Z9^ql83XF}BAo?u*nZ1Jmbq&^-0C6q^4k*Hy{1W!e=K|5|}%YB(Cui=Gp-a)f#=FPHAV{}WtUhcl$ z3`5L(%F5@S;agI%)!UVJijhHz)vYk-4hh-b5cJ?c{D{Qk*iGV8)8nj(95~>=Y@)cn z^%#-#yeE-@3-^TQ9i28EMd39<(|Ut3JQ~WDux6U@{Eiw|YYflam>_lR07^?Dop^jR zmiBxc!aQCoKYkfHehVEJS!Sp`AD1AT__(y$sysnc(?**+p@?1jj7I^N$9yZKG;_{e z)O}K%bW5D~l-Ybem@=#V9rK zW#aTp3~OPYR1e!7i_|X3;;yjxAo813%C~CE!8TDcyFTu_Aikb=Z@IF?Z0jh~53hDv zBzp|Zs`%OG;!^i4!|Wss?fAJfL|sEumU^o%Grj=-oLKGWHSepc)Id_v)fVRQ!1Lu+ z4rT72Di{~cMHgz!7wS_N8dLkhw+pV@{ax;dv&&D>qq0qx4|y8lDApF&`Hq+omwZA6 zIqZ(ArIu!vj&Kv|8+oEmJ#r(7huRs2;zNJ+khtzF{nF8Qb%`bz;W?$kUtwW;JhhMj-sWH2lfUFc!jD)Z zJTf5WGbF{9dX;8KF+vFdb~UwiDVz04V1!#LjZG?pLpt_O2I)f@%|~rxRwmkp!XnNQ zZ|;$eXR8~pu{Pz&Hw9%j2VFKbU$u>y$W1brujC?t1AEI-7K=b3`qJ- z(kxdpECifZRhE0Bvls%0emkR(VWGKSiQQ|Cxi4pU+vH^5(AV2Ub~pa1FZg(0H92$U z%fa{j%m}N4zO;jHg9o+l3-u)n&{XZ_=Ke`O{^_*CBiOzBF@L}(*e(cxUg+pD9kx}f zGmeF7LhR$`8{i)l7!n*t{J&BJ5JhxKL|R&MdNy%JP6{NupeVPbxU95-qAC|sT~}LE z1%1%iw*8~A?W=k^&@wngF){{t5eBD6XJ_W;78jP6=BA&nk8W-N$aZ~i`{2=H`zS@Q zdwO+qeRm7HhleMjjf(is#8xmsU`Hs0w&FERm;#^CBqiw4ittI7P`omyKUz(`Q1h?G zRtp~VxUpqLcnpvINdHuVN-9we5L?NAh;5!k7ND_Z-HUq&k2RZQK1vaM{_y_|k7WsW z)-r1FT5a?Qf37QCf;s^U^?$-+c!a>j_FIS6^S9bfvk`jKk5U9R=Kn|5Uq(gQ!29JmU8-B`UpmD`iA)zTPdN)JqIP}bqy#4{(KSEJ7 zKSnj22#D1)CDUZwy#BM;{(S(Qu6KEa^S=Pwt?>NUi7nO3#1=Kp3$WON|5*{-QC>H; zuNqqz)>mS?_p-4Ch%K_9T!t4WtI>v^v|j&)KiYpA+ZT=Pixi<$ML2+75N$JrVbEwZ zn0?hz7vq)KzHV%VUczJi24`7O+)NAE;ZoF8+tG?b_ggV4N(E$b^7aim@i?{!I|$o7VU#+>((#S%rIMX+U?3Yi{`R-^5l3%lt)STXHo9vkrn7lZC^# z8~RTF_k0>oujCcj+Re)NyZ~E&p56tcthYUY6yf-0QLOt#iqPi<)R1;dZdXKJr3jDa zz3V=xsok#@+YN4(lRH3)0H$l$Qd6+tKz92-E5iS?v8C(G0yMTjc&v}^@hBL!qYscG zl)i3kA5Q^|?bFM~miyd_bm*z z5DI_8iU@kiIvi2$3?R1a?C_leza7iHKe`40z*g{`!IlrkLI5KD`zXvtG!lwHZE+nz zU}9TN#y*gN@&+P?-~o+N6d@DM_acTEcY;b${EtFyXE*Rn7$|oXq?Rkz1Fo*`p|u&% z(W>niZiEJiE%dN!{UYR6JE2zH$VU9$0I@x1DIUl&Jzz-Y?ImaP zY#y9ZW- zs7>I`*6bhyF}0!@Kx5mucwOpft~ynkTV2>NTqgfmG<8Q^U50a0u11rr(-&9U+j?AK zUX-l2TU$4{Lu-`)qp^WlS3gQ_VUzy$cO)-JC{n3aL0|Ks>S;Z=_d4~3*dF_yx@>(Az8_~>QK>#{JTYCPIqK8A zzdmhx(by)RBZH42J)xw^AU@Rd--wjspZHpGl8Xr-a>{w%jg+}F!*`-S)U|#3{6cI6 z(Q)V7X?q?YWOgxGKQKDSLpxg*Bu!?XLdloz`yKI;(3?||1HJzDL$m1oWv$l zj$Dw0@V;MM?S3#0U6#CVcz}*@Bl;&ffajjl6q4?T3te-7?%1Hp>cxmfFBxdN`O}ZZ z`%%YLGKO1?ES(1@(P3n8bvj(jurcrDxI$rWM#aFMS=heh#_~>9o71R-`opB9jbYB0 zlH5LpS1+O6v_?hD_Dm& z70B06D`u%x6xOP*d|xS4`WC0?JjGS~L$gSAYH+r?H+GHFl%^d>2fH;XmU0dibz+SI zc{1}dlr_~E2&9@c>5;O4k@`8zq4VC{x0OU`#r?FB7sE-*@X2H#LuIN{8i(#uo4IUgL+-$#{o=Jq+T8{?Lc3BtT=U&f}(% z*L`1z7gUn`=WzaQ(_`~t(A~@_rlBksUGLCM?QJ-2uV<6<++&+@_wC7|Q5oB$cG&G| zeCr8+pF5naBQoS&TL2&TZ>%v#Um|uAnvf?i3e+yxK8DVOa0XvCkBw2NZ(Zr9<$IBL z8>D{qfuu4mFfzl=G`ZMsX;OoO4GA|FgCl!&t1EDc;C;KotFfOYXgTbLst-L!ppQjhsQME1QoEZJ{nKZGF&wwSFaKuce?STY+h<(Uu zv=;hX>aHvp{BWt7;KrK!94@~1{79HMra&5iDLtYmJsTq(3TwQEZX82yj7&+Mfcg79 z`)>#N-`ZXj_MI{Yf)ppvvi9<@d{}_S)+=xlG9FT{Vpg`O*CaQNx)heCI?k(s)tg1d z8@1*eVXQayj48nv`5sK#{~V)6p;J|gvIVwC3M0kl%s=F)d&Ec$fv3Ex?_>E@Mu z=V#5;>U}lx&39nw*LE1heJ!MV6tF+|9mZK0Q(7wb_+8p7-NPzr&RG5mu>6(J#JkDJ zO=6{+W2tm$2?ZDMjx7L4Rq;bv+X`DdXYT@a z^(E{^G0fK?Y_I-DP`u+2_RrAUFz6dcyiehug`DX1oZ{o19#p<2i)yFdhI7Ah2Dlw` zB6^OYb6y=rp{P#DT!j9)b2*laGlNUDp$ldMR(-rn;~aMQgbN3(Ya4~Dp`0rz2X3Fg zYgvYCb%$%ihO0Na8w1tHDN(m^ZMV62H}*jMr9QV6e}c6-@r_;aEw-3UTX&H_iNkns z%;Bzkb@rz-Wl6w34}`~BY&~3W3{~zu)EZ(%nWUk`$bLF`!qywXtHhz^d+OQ5p#vLR zDhiOjv86F&C40Orf(cT(SF)E0M2-oQqnCSNeEE*7+kJecfw!Mi0&Bf#$$PU#NHgyK zgyve)Zq~#;d!Ir3L`la)rTRpMouS2Q;?T`jGWG!LZKh@Q4~M>>2^M-&$?*yD1Cc1#EKi?T-JApZ~}} zxswrraaIYTBs+JGlb)Fl8BmW#c|zQuz>9thy4^ME%<91 zgK65`KpKmB73(7hK3XwnQ&m_cL~V3BFys_m;zBC49lrzzcfx1Pe$9~L%IHh58&gEU z;?%@J48cQOan96Os(B=Fm}y5^t`F6I%%od%K&p0NeQ>z=g6b8YWmOc$Gnf?w zmu+t<7{wOuq#iDU`(7+5TN1aPW+I#GDjNbP2ZuEWS~W+(I!7%sN3AiZWG?4DLN1_8 zs1?oC*UJs;a4~KaF&)$e@@YMAc{ZGRc0qU!L3vKNZZ3mjU-t7naPv7h^5YfqlWg;k zBJ(dh@>_!m!*QFThzq)t-H+j7WyKBgI}3)Fn(uC#yU+`Jg$k$DTYx{^=4s-B<2*|W z<4mZEVhoD@aJ4paQW!$Y?j*|)jze-UwVrTMlAwX9%Kf~k^GyaN+I}OHjNy7u0UO)L zwz)!Yo__Bz)%KYCl3vVGgy!}H6I;$=W;GND8h7flR0LUEgN8X+yy`0ixx2-u zD)_SkKCr2*Ii)O#s}L4hf0AS+0rt2ql`*lE@imnmQ4Wuq!4w{8a$I4Pgg!d6MIvNP<6>rt>pf7 z7>Dlk%+HINiz>D2@LBKCvrzTI%+!C}DuT1Dmj)h$>wYbTIdBak31q`+54yQzdj!At zS{n2z`s()>9>66O#N`~)Bor2m5rHHe#nn)@n-jMroRHj*6pRg8f=PXBhiRZ|;H^TF_&o~6+bf(0@N zlJSMjc00{C+_9-a9x4qUvrA*ohJ{)P(%Oke&?7CdZ;RFrJ=Y~$kz3*{6N}O+$x&0@ z*n0M2uCzv0#=|PM(TOF{*B9d*7e5TOL1;{pYkq4JX~*_0i9{%U?cW8>YUTHNE- z)uTDg{)0P6TdEfbj};|UVY$si98{S%&jZ1EOS9@$$7&ny1$&JJ#rVGIoRGb)kYcNv z-^ii8?wJLW7N=X!*-a1<3D< zq~4bt4VHy`s5o+}`YcrQ*}3jBMnmyX(`U?xJC z&|mGN@`|En%<$$yMi!3rmWIJ2l{ENkAXw`!~TA|va!7-gS!`J0x6s7H&3n= z|F(UCu;dRddNOf3<+tWg-c|Va_e^dEkfW~5b7$207)+EDG4_$3>%8>z(`jg7?svD@mKYqd( ztUnHG;u*|suDiTjYR6wzVOaK3U+#5V#)?}Os9wgOT~<0@{*JaX$+JSPv_fOQq8_ut zSi9nFJ>0(>xyFOD@mFM1deshn#Fb@a8nmiVzS=&qDt)s$Fp=lZxwfFZc7y-sPIL5u z7UpSX?fGy1o9A5=3%@w=zh_ z8{D!*A2eI*4rJbLCf=mV}Ef{W=_uRif4FozX?;k||^-ee!$#L8)Bf8K1v zoI*sV{W2o2J!XdLy2a`{m9KceoKM!g>9vgfQ3QmGi77vOo;L8b~MqxB( zau!DB7k>I5dP?=Ty7P5BKXsgh_Rtx3QeQ#9zpcMLO_2fiL=L`j&7YL6T`T6@f2L%Vi{|k@t z|C1sl3cpAZQZ=)(b8_tSrCy~7#mE(vRn;{$hV>2gJpYJoyH0mck6phO5FQ&=cny!q zzG!S`_+B-(>uW+U6WcAIQ}!~k{Qz{wUWo1aFQ7Yi|Lz$K0rkKo_##Ds$)S9i*a{+| zkw}2VfbLi@I)~B!Xl&ih1OZ?hP5J!=*y>BdlWVj77XL*)ki`D!KVZx6jR*i+$_Z-D zNI|(lmi@^*u`EGfwVcA47ht;r9;|sGwoL~4oV60FmC8efUxt7|Y=zZAZ;B~qsb+%% z^Zdw=a@ks&=YLX!u7D3~XH6=Wn{DCDLbH$BXMbSanM_xQ8>)84(!U1(BepLaTg}EE z|G_fmZa*MAX0}wWe^@H*Vt>5U>U~MDn(Sz`-Wv@N+vbML-SI5Rv=d^d>$$nI%UND- zuA9?UJ|9A`Cb#3|PD>Hrj~2Iw+mp?_aM>TOkB_&m4oIpj2%#XAtw<3R@vSKC2S?IqSrIDI7)d2n{U~wZGV8yM?W+{wh1hCh zdKx4kC@kbASiZ+G1W6M7+)a6vBG_|oyhsracCmdh)hN*e$N`OQ0P(97;b0HrH9QuB z``R6AEWk&N|>Jiml+09*53gQALl=y3v#YDFU)#$P2L@KJUXf{K(Wz94&Rx|0xDkIY9L< zJofo=m}SoFa)f>C31WoHfBe@V58T`8v9BM@SthtBLa!zz*ha3VWJCcU0`GV8YbYgU zAUyV}vHhQkZS8_Bcf`%2N!`fJl11O!+hv<6?b}yk3v|bhZ&wA!-`%ZyVae2Q1bis1 zM+;$lA+~&BJzFu#7WZ4K{|9VcP}=`V5pv+t0V%=@uq{*n^!U;pb2*mW`Uh-XP9>mU zfGr$f&v`#Z+0!{D%jwf4cw7{f=hL*Z<=<;xA{%&;W!XP}Z^O)ppYM`onHp#ESab(D z!9T8$upgrmn3B#zjHF0(QJ8TCuyYw>?}Mv%#QFeW8|J71VG&f7%tK7UQMXS*=;Zxz z9UGW>>5UTRb@hvYIWHn3Y{Ts9zbBu?7;?qiqB>ItieE+aMQ^L3QV17_-xv4AoQacB zzw0K1!0(TRB_98Mb_on5jpAy%BVLK^1JhTkhjAZn^h^w#?*iT36QK&-!+Nk&!sE@~ zf|DAC3C{PDz9Py;8^w$e;_N5OPUgnMpp(+-?}NSx=EYPBkx?X8rKqSyze*8ax?|ZN zQu?c9-(3BYwEYteND(LmaM0!aBq*~m3n|4p(B%_?@^iR_Cu9O86!Hi23x4)Ygms!I zRddFPiAqdHC0%7xuEau0dG@__$MoY6e5^{77O!&IM+#&df@mG?ukudi=bC*6%QA0< z!1-c|3G(rSFX6GDsE^7DWN{3IYBM^@Fo{Y$y^3K4X8N?c3(CJlW-F7fi;bjH>;(=@F$+|;zvq?-BHH7}COI@gbw zUzYbRts2O>7_AeKw2Nv;M4Z-da;4b>r}JJ{pt_Iy!u-vZM0(s7^q8L^1cz+2LBK|M zuJfcjVu`K7aGo^_d8R{?8Fkz=vUxwPr@Qirt&s$rwNeZNz_zpV`Jv9235;Cssjc!A z4-?y;Q^-ojtA8DqtKR=>Ncr~&G3`R`^G@v1Gv6_$9+WIHI*W!sm^BH)t&SD+x*xM} zUo^H^=ZxmIA^Ntu37Fkiy)PPD$t{Ar*#~J@k|67;)IMddh+|!1MP&&Ig0;Ize;wCG?Ui(1sgytzLR5LXC>6@V;;0(U* z_krdq*RtdtQl~QE#r97(KF1&LPHxX1{+4Zlxz-2OQ_0}y0;O2X)}c?&I?_>F_Q*84 z5h%{DB&N#`l*gQD)OxyzQ5XZ(nEovKTho!Zx}Dtq`Lp`?d~1m;^^xj3HoJr$%DPPJ zMSNQ^+!J=cn`>)SJhvXXI+%STk(VfI`0t5JTIBcH3)0Z3ZArhVpwlu)DJV8y8Ef^TrR>0U*lG)WN+BF-!QMnDC&a&(1 zv2#AN>mjr6H$u=;wl{DIMnudNM+5 z)<=CFaAjH774#EhNW^0)aFeum^Y(G$pT!foapS#@=2zA4e&-&StuLY)lbG$Ua3d}u zE^&4nqtEJL7AI-V8jEmYfFS7cRzCL4e5}@eEUMTis69iNdZ{s6sQ_5%cYB`3iNCpY zj4T>{$JqalB`1xKGfvqtPM$T+$_2}i70%_ zO9)Ep0VcMpr7E@+?CHhK!PQ2=@JU<%t#7R7Zc(vo$Ijp-3h7n}>4oPVNC+9iMg;T; z$55eXB%#y7p>vL*3zT43yS~uD_0To=uz7~CO_i`+G{?Pqltag?v+=OMXJK#Ng~Kz3 zqiBZ7H<8abjxc$hA6XT*QhiE)h|N|jd^2wd zYZQl|LOd{S^fti=rarFnq0me`-dfx^f|YF9N7^nho>0YWiPVd{Us{(q!Pz*WKdE>y zsW^CmtahhZ^8%c}g`Mcdlo+F$7;KZ6keC=>nV346m=;K#$x)hZoK)ykx|dYitpo8{ zKko!F8HxXU9iXvQE8B`nK4Mi6$nk4kD7zyDLEx4582f{BEn#&*t^uIohH^?MrYVkq zIh>03k^xHv))G@GUw>6#v!#AixA~)*N-nCri^EDfmr6dAdY)K$R=|3-P|56{77bGs zm6MjxlNNuO#*W1KM#2_)u?n`)79lAeNsasMK{{%o`g_C>bcqnGAfO0tj~B#?&xvRR zmw7^xIVGG)hU-9)lu139Ik}!mkC^2~k%ej-_QfQNy)lflP=I?;fY$_#e-Z7gTHSl? zY{#W{;*H=s=-l^G2iYLFobR0V-_>$*>LT*{a)OGS-%(+r2S(~pyXdLu;3wwdIW?Fi zHJIV*dQFIgR$xbei+X!j3iwhBCv;tc^q5uMgvg^k8l%PiqFqh$0pPbjC$8?-6pULC zK8SyWRj_SX5KCQ<&`5ZZSCEusV4Uk=(d#j+PSl`R2pkCibc*v)lA?e#>a1?*t&Xc6 zjI-qUy`e5$xA@zE%J?ID{HFxtOnWcSeHo|3*6%vxd9}qiE^TxH2{rcK^#-ym?56B0 zWRs1i)3}tgK_v@?C1^b*AGS+Ckfj@q-!^fRwhK!!T|2OgX&A;!bC)_+YXO>2M$Fww z>I$a4JNW+4NZ;1b*+NxL_tc5*?T@YtLM-zCFa<(BEJwO6N2CbQ`BK4;+>J4$gl%fQ z+)zQdRDrLYN_6;z6swW~uZO&-Qeioe&ZWnLq{=_5Csw%Xi)j@owo0d&gG*A4M>3tS z$W|aY{i`Ima1pm?aJ6`_o#c?6^dpZfQq4CS#P3Tmil#NCo;6olHR{QlnoXh92QWX? z`E^X+>Z#Wn1fv)w*P0I1az4}o18Hc+IugA)`{cUx;Ww^agLLQNi4I>mVg{K7>We?; z_?Zf+Bnbs`4dKkzhcD%P#B{O!)Ie&l(;Cvyq>PosHJpruV_L1#wc7zm5kQQPPKDsS zG4A|g(~lKJd7M;Dv)oO!O(V<09|I1WnueMp5J%gS-Md{z4dO=6uwqSfn@0~vE3ORE z8$GfLW2axF2t>LAEiSB{3r&Sym_}>BbE@R;P4(Y%3ayAMBo~K8Z&PG0hm6m-Cc2Wm zPN!SZTH?L;Tkn=82tvtO=i4gCz3+ucp^8mmLgb@FUZh7LiV-2uGCWPUtNM2vmqQhm4d5glM7|1@i<*<(YSrlK*I+20fL9UP>2)DsES ztIgf3tI?Zf*9(=@TU^syJKtM<-P`}6ui;CdZLuAObKh!opLSiJD|d|ta{nY*e=UE% zZ?WdWUd?iS|M+-+*i-*D#y}LP_DF8vV7@lt2{j3X26{qE)u_t=)nzX)(N$-|!`7$F z4R)JHl$kjPxCm7@FUvtk{zP)`07TsGJ0i+0g9PWbRqvBL+5kcot`km?kP#=A^HaPp;oSNielWTAd z8bfSdUsgA2f-W-JFGO^Vt8$jYIFb52YlK55jWkkpQ1rW_v51HOY(k{sl`c|@-XeoJ zB6IyXLHGQpIJZq#$NSStF$X+_hRq~&?4*ZH`{xx(Ivy&96e=d3DG8OS92>xP>&v~e zC1c_H?QCj`XM2d)Ldb1eC3U+#ar!9A&$OP-c&|+7xlB%T$0otj4qlPDdFPAk3^;ej z>O@gPI%RTU1|I8$*y1GzU`o!K{0%T_QC9a>mOZM7f}aa;5B$}#XQ4Y6=FaA5&K5a3 z_v2_z1!CTlc0N;hzQSm}$alUbf4;M8KJ<8g5^6zNxvx`rA^PV+zwbiIc%S=I2xtW{ zm6k6ZfAQ{DKRCKS$ZS!;b8#_!ajR!>lRxVV;*u}LQWZYY@u+nwVyL~VKb6DBBP(#31=Z<8NcR1g3*!p~! zOM4{Cf7D}f)E^c$DC0QHyEJC;V}keitJ?8w*zqdr@?z@OPTKl)t!FfY9L1#NO0$zA zuuubX?h)^buEYw7!Ab(s=`G*s1K0(G1drq8#pdnjkK;@49`gThv5n^>B*e+g&dLNd zwzb?78rxT5`vPo>VOme5B4R%)R_XQxk-4OoEY(?U4g!|?mx=9R*uqde zeas86eGbkp2fAZOKU9Z-?pTiqG0+_YcF;o!^b`v(z;=WiEci-nji=P)i~J_?{?ph> zH@$3Ze*xjKraH^zZ=9d+g#Kx4zpA0>!KA$sTbY(uDT3+RzwlUD5zea=VUsQYTUslR z)AiZhP`Io|>)(evw!MGhvHzLa{)B)01fTAOd@#2Tizv9a?(=~+VBPn<4j@JNXyKUQ zN8k>>;ZGW7qytZ!`TyG;n-$xHV#@>!J6wPEbm6%UD7V6eAdU5a?%2L=lo*{8X@m@& z_*M+6nCf=y|JxnAC&NdLFg8duN-Z!*GArFTNVe^!da>9VgI|cPaUPoO*}h?#=QGY; zx(6n8H=wZvh;5M0KVoZy`ATd7DZ+kkBIG(CMew7h&VLgF5L-ZFTUe;{st(JbK_-V`)Gj$Ol-?q?6-!x|7mRhG7-IKY|Y9$3`vWvI(hze$39zk>nNC2^w{Yg z_4IypSZ2g{l_C)FX}?%(%`Q+s{{yzj%l*|kEy8B_Pi3?S@hS9ZM^x-f>HcP$Lq%SB|OHqEIn=hf5f(K1#KDM zam^dh*naS*K&U+ck+OOTQ|A=jQRjR;I z{+N5?aqgzY<4J=uBiCsw9JuMM8|lyESuX|n@nVSZl$&^5l>YD4E3lpaz$Er*{1;z8 zr62mA7NT`S1|J(hitzk!REIhMRWdJ#^touhQA-;mm7|0S>l98^zZ4%zLlDkK>uK(``Nr|5of1zZ`ai z2g?>fY+p3CUn6~dNFWp8QFtaJ2^Ja1DHz4YG;F?piX#mW@)3V$`aU{|y&{mUVnELI zeGiog8MQ=1piCSwdYxAzWNfm%2-AP>-BBEl|%;=Iek&s>qk3`%rSWfdLuki|F*D zx5!fKt@241F}>PhzdE~KyJO`cIiG91Q-O#S&v`>Q-FelJ*2N@$J8~|Azqr)15I8{a zy#)F1&k7lO&iRRBAqM`rIMV1Tl)|Kyk*swCfX4PRnE^2>$eA>o;%|WHS89sr;ek;* zB?O6Mmb};)=o|;Fz|l9q@@$*|Ppo(KEs@Y0lmNWzqYj8_@Ibz+1l zsG-GG(d9vdfW|hc;G5G`7KBQym}n!lYT{LP$z&{`v8DOhFsk#3XgC3^Aa8tF1_u&4ccc^MtjSj zW1AbV&MBO)K&-P+DwP0vnLn<|%#kToxd?QqNv*R!Zwndy5;KRE^Nc+qNnBsAw z3$&#v=Z1G!o9;(ad^!+{C3iWCEZ=-e$Vt5&1~j$}v31BSblc2(KOQc|{rqGZu}1bp zP%jf8b#j@hu82^mqLUKha&txXq|LOVr*JN8^QsU=<&z(#b1*45X9hBVHFBn&_|z1y zIE|@w0j`5#L!PXdF^`9bx%M4-0R)L7Z9IjHewiCVJj8DXT*;Z^TGPULBNHa-P2Y(| zZt}zi%`LL7ma23L>XjcRZHBIvS*7c$YzI$37wGD|$8mDtT}`^I#io4m5r=mPg9>>P z*K2R83fqzV6n(9)*EOyWdfGW>E0V4^j6)sODOQ#0)j;qzIW(H*gXdwVHOB65oqmeC zLw6=|S5V3}EPfoih~tZ^WC-Wbr$wqy`cbee`F-UY2|jpxhs-A{sH2^&b@h%O=mVo9HV@CI>XD_L3i-$3Ow9rUHt9(sGm zAY+ir@}oPo+Hgg<%hMlR_3gec`pS#=u_q>SRmw5o{y%XT;{Zu`aQ>7e_OFqC+fSzm zHD1zqjQed7KUHSkuyFO-54LK6p;_#3$exatRyw^>Ls|* zCJ6L1LKGtmd)3%RV19~aC5oCQ!izG-t~dS!Nt{7$lI>?ggzZIKFI_lmvTf_NWh*1X zB(slhO2=->5MWwkK*r=~%7SeMND(-U%z9?Mx%18Vv3*=F%us}V{N9@bkQU3%T*}dW z@y2Hb)0Yg!LV?{vX5h-s$H9;JsYOEz*H4guV23$qkpl*|Kfd}*ydex6xFMhvfGMd1y@oAw|Cjr z=BvwN*(uZocPQGa%>@r$+5u98ZfxEjMczdcUYvA~;rWo!J-7@A2Ya^AlncH<3Z8!JjcoOV$ zt9HAvlZ)_Rx^{|+s7$+3CPq;YxK1cz%+Bda=IS}Hh$=?9E!4R!&$;QIxvgWl2Qs<` zD!7N(x*J5eAN0A4QQ;cp!kmhF$lS-s;l!3PLUf*oC&$@2O z%Scay22cHaPm_kYZd<7c1F0Cy_-F%Ti^Sjd1;58_iPKn3$e2uAIJ`V@61*Br%4)r6 z^1bL25-!laF#0C#n1pxj zvq_iQadu42Ja&?q1Ft+af<9mSV*N8x?E9R%44`&$QXTlEJ>GU(-^SjHWx4yHq zW%svtgmuDBL8i zELJuCI~d2Qh%8(o$BUjY+?cRE?CfBQa1k{@v812mG1*ah+4t+&PyK?RIzcGa93_be z1Z{2nUT_2+aPE#3$panvi8YtF)>%>^5?vhKq%ar1Ad*1Uwari$kRs?Rlrg*&?DrlYhxN{N6-65J7q+34MclwyhO{wKE=ce#E9JEh&vTXF2u+;6o3{B zOvw!?a0~l>8x}#wlUZw$fq7;d0;q$-vRfPs z>ZPLZPXx)aO;zi@Hbne1$<@IXGRAdDN!Br4)Ty7#&0cc(2#m*Jqk1W#@@QO(UBFT0$*#_v zFB45oZMW(8CJpU;dB1$ejQo(r{IDRgh(@s}P8>i>9Bo@5mROMb&8E5=rq+rqRs>wr_v;lkF1FeP8av>$jiH->{G@Lr+uRe| z`WoAMlZqLmNd2f}AeW1S_Pqkd$?mQanC25&dP`7_+ShP9c-c$Qiz#-gDX~6&+b=9V z4ElER&=Ch&MnqOtB3`y;P*xFG)|Oe;(^>ZSpiCRSyp5wATD{!Fv0Ngy{0h<^8A%a^ z#tIFu!il{C!?XgMiwU=>;-h*10iN<7oJwNJ${piMSKmsHoJ!>`aHZB|r3N=E(_@dt z_bQ#ws&T@TDG z8G)WWS?xT!@o$1XTYv-mXnsBbzw2^k)vwpC_SafA)!H--fTZ}jIRy?J>)x^q9*Q}- znGU)ihIuSG;-d?S2ZcWxg-fgbd=?w32tf-)YG`a8LLP9AcZtaJ|Ejh4E}5%=IIf{j zD$=NNm_|u>blD}xw9(uosvVHo6zR@1>vkJ9EiaFlOh*Z0<|};~6&J`?=xF-3)8v^Q z-JvelWs2Qn+T4eSGf>o=-qC!t+dSDc_Ov`!{sziny?@RW4Eaf}aLr{LK6HG8ruB4U z{OC>5PLt#T*Mup~?>cAW$k|qGrueqSiD~rW2h+AEu1Qi_5~z>uL%5_{Tg7Ec?UN?$ zQ-kd@g{E(x$QB>k+5gJEZ=Qly?BI2yz&WB2SfRk<{)T_lL4@2%{Pc}Eq z8u|NY?$2}@-x)r3>0+0&d{$s}?PBMq=Uj#Xs&U|pE+vd^!4NAUvlPrj7*SUxaaShE z;cjUVvn+CtJa-SdX^(P9k78Dj?@W&-aFB4V|79-b}eE#Vt86JS=RQr@&$vxBn8fpfuKo#Ub z{f>Z7jCkLWqdn-{)7+32EJWHnoLS^D&fSQOGcu{+N?I`Ti&|s~S#QBCZ?$>tsRUyk zc~tz(x;N)KGfuSE!-u_L(E~HA_N7su^Ud2~pKvDf-OVDqABGv#K2fW6p5wT+Bt zi!3yuICpaRU{V6bRI0L_xuhKdG$k*S$gR0;d;y+Pp`-X}?z5*h9bz*b9yKlAGEFcu zEq^ynfia`RKGPyUqvSR-5;gOavP*w{M&NqJ7<*Qyq)Xp?_Kp86T-K~JXLeRDBAt)7tfL}UT;}_Mtc0;_6Ggkck))f$2l+r^`?+53^=Fms>JL z8Zddxj5ix_oU3iu1TbM8U(k=OgyTB?<-Dikqr0%e;bmgddf3@PIqDT($()CNG(^9Z zMf}so&kY!u!*3Xe_oP<`icgc&b3t4#2Y6^6fT)pnxF^Yl$gGR9NUS

zyQmA49DF7?_`4xd?7C$YY=~A zR0qLv20@*A$!S^md35~b8v#ARl`+Sr&|2Kz$W3g`BF@%{;jIaLT9fqNctM#h1-`9; z#!2B$FSW93$<=Eqf+@z5_U2wPR`zX!HCd(98`ajEuWpnYbkkaN=0C$=bV{f7=%@_{ ze2pyRO?WNL2tHfz!dMaP+KgJ*5?I=!C^))XI-k(#O3x1N?>+XS`CQN+J9#S-v6DlFJHb7THR+tI;bv7W2ZUrhgv9TedMk? z5S%*@LOSdOb0Qz4H~#8tusa+`JCrLr^Z?n7fe$D7{;quG^+wZVN&BnJ0ZC)BG@YPn zNOQaxFc1Sm+V(i!OLMR-3gcT0dl!?1(|w$Sd~%jB80Y~0jpP)TcR~RTPe|uQ=k4p` zHu5W%JU4C&yNp^WcNoh@PT~0w`ZDV~!Xe8R>-IwkdFtI)TZ(@6ZaB;u% zxCaMJY!N?##m>^Az2QGlbF=4WeD#+j1~#^g#8EFA+h)g{tiEs}F5DL>f_RjHe4$ig z_Dgt7{oÐ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]Folzalg|u;mR~_o7Y3 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 y+Qu-0C+fpyq|bhF;^N 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%0AD!zJ9Z}#W%S^62)o15d8aS=<|GkvuBoz` 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%0DTyAW%M!*A13fIz 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

(TD{47hQZkY&+FaZ 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 $bnA%x#^RwqR~F4ewkEf< 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�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 BNj;pC5 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

1^ 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 literal 0 HcmV?d00001 diff --git a/pr-preview/pr-976/img/concept.svg b/pr-preview/pr-976/img/concept.svg new file mode 100644 index 0000000000..af04ecafab --- /dev/null +++ b/pr-preview/pr-976/img/concept.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/img/favicon.ico b/pr-preview/pr-976/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..85a1642f7954237937df3437730c19557500f694 GIT binary patch literal 935 zcmV;Y16cftP)Px&VM#m!R>=7_Rg4Z;Q-3zawC~cLRO+6U8~h9MIw<))^|}kXPSXdr=tY| zfoo1dW-^&lu~^)iTYx{x-{b_S`h31YRz#keWxzD?xtvHOv|6p^m?1Z)xdQNFqqzde z=krE3n+;+X3IqaLEEd~`b`RyC=&Q+=aT^Wr;sU% zV#u<5N=2vOlgVVGTrQ8Tpp_A?*>J4Hk|b&Ic--G^w;Q^yZ>cIc=kGI)>TW4M_{p?a zPkT&sjtFlhrV+dy3T!2k4Iuzg+kmPUE;8X&=f&fmM$H5nfD$|e3~D-A;mY;1+IsBF z{?!{R=)8e`b~d{ta54Z^sYM3eynn8Nfl#eP0>IR#4rcc{WaRFnRj$h08(p*(PykfZ zG+j4wUV^ux!XPMf0R<=&3Z-;9?YNB|CwL2jXD5m+Q2?IzDJe!hz!=+kd)~DfHU_%O$Q{X+Ok`n|LJhfjE0G0*On*~bn6!l?T z5&$%$9_D!iL*RGrtun$nS>4{~k}i_T002>~Ry9eINM}{+d~Df=5cJS#BJ)ZJfL9kN zD-Na2$Jc%1&9ffqic-iz*5K2G5K-QWM<@e!1$jqJiqiHrUT@_*Wxzf#c3VLK5w*-{ zpPn;d?+8wA#bPlCH{6s56yH<({;wa7g5N(MQ-0#wW+DKiFz`K>%l&}QTQOYM-o002ov JPDHLkV1gKvrzijb literal 0 HcmV?d00001 diff --git a/pr-preview/pr-976/img/logos/contrast_icon.svg b/pr-preview/pr-976/img/logos/contrast_icon.svg new file mode 100644 index 0000000000..235ee27474 --- /dev/null +++ b/pr-preview/pr-976/img/logos/contrast_icon.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/pr-preview/pr-976/index.html b/pr-preview/pr-976/index.html new file mode 100644 index 0000000000..53da4cf7e1 --- /dev/null +++ b/pr-preview/pr-976/index.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next.html b/pr-preview/pr-976/next.html new file mode 100644 index 0000000000..bebd4c75d1 --- /dev/null +++ b/pr-preview/pr-976/next.html @@ -0,0 +1,45 @@ + + + + + +Contrast | Contrast + + + + + + + + + + + + + +
Version: Next

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/about/telemetry.html b/pr-preview/pr-976/next/about/telemetry.html new file mode 100644 index 0000000000..ec8a3b72ea --- /dev/null +++ b/pr-preview/pr-976/next/about/telemetry.html @@ -0,0 +1,36 @@ + + + + + +CLI telemetry | Contrast + + + + + + + + + + + + + +
Version: Next

CLI telemetry

+

The Contrast CLI sends telemetry data to Edgeless Systems when you use CLI commands. +This allows to understand how Contrast is used and to improve it.

+

The CLI sends the following data:

+
    +
  • The CLI version
  • +
  • The CLI target OS and architecture (GOOS and GOARCH)
  • +
  • The command that was run
  • +
  • The kind of error that occurred (if any)
  • +
+

The CLI doesn't collect sensitive information. +The implementation is open-source and can be reviewed.

+

IP addresses may be processed or stored for security purposes.

+

The data that the CLI collects adheres to the Edgeless Systems privacy policy.

+

You can disable telemetry by setting the environment variable DO_NOT_TRACK=1 before running the CLI.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/architecture/attestation.html b/pr-preview/pr-976/next/architecture/attestation.html new file mode 100644 index 0000000000..996af1b294 --- /dev/null +++ b/pr-preview/pr-976/next/architecture/attestation.html @@ -0,0 +1,104 @@ + + + + + +Attestation in Contrast | Contrast + + + + + + + + + + + + + +
Version: Next

Attestation in Contrast

+

This document describes the attestation architecture of Contrast, adhering to the definitions of Remote ATtestation procedureS (RATS) in RFC 9334. +The following gives a detailed description of Contrast's attestation architecture. +At the end of this document, we included an FAQ that answers the most common questions regarding attestation in hindsight of the security benefits.

+

Attestation architecture

+

Contrast integrates with the RATS architecture, leveraging their definition of roles and processes including Attesters, Verifiers, and Relying Parties.

+

Conceptual attestation architecture

+

Figure 1: Conceptual attestation architecture. Taken from RFC 9334.

+
    +
  • Attester: Assigned to entities that are responsible for creating Evidence which is then sent to a Verifier.
  • +
  • Verifier: These entities utilize the Evidence, Reference Values, and Endorsements. They assess the trustworthiness of the Attester by applying an Appraisal Policy for Evidence. Following this assessment, Verifiers generate Attestation Results for use by Relying Parties. The Appraisal Policy for Evidence may be provided by the Verifier Owner, programmed into the Verifier, or acquired through other means.
  • +
  • Relying Party: Assigned to entities that utilize Attestation Results, applying their own appraisal policies to make specific decisions, such as authorization decisions. This process is referred to as the "appraisal of Attestation Results." The Appraisal Policy for Attestation Results might be sourced from the Relying Party Owner, configured by the owner, embedded in the Relying Party, or obtained through other protocols or mechanisms.
  • +
+

Components of Contrast's attestation

+

The key components involved in the attestation process of Contrast are detailed below:

+

Attester: Application Pods

+

This includes all Pods of the Contrast deployment that run inside Confidential Containers and generate cryptographic evidence reflecting their current configuration and state. +Their evidence is rooted in the hardware measurements from the CPU and their confidential VM environment. +The details of this evidence are given below in the section on evidence generation and appraisal.

+

Attestation flow of a confidential pod

+

Figure 2: Attestation flow of a confidential pod. Based on the layered attester graphic in RFC 9334.

+

Pods run in Contrast's runtime environment (B), effectively within a confidential VM. +During launch, the CPU (A) measures the initial memory content of the confidential VM that contains Contrast's pod-VM image and generates the corresponding attestation evidence. +The image is in IGVM format, encapsulating all information required to launch a virtual machine, including the kernel, the initramfs, and kernel cmdline. +The kernel cmdline contains the root hash for dm-verity that ensures the integrity of the root filesystem. +The root filesystem contains all components of the container's runtime environment including the guest agent (C).

+

In the userland, the guest agent takes care of enforcing the runtime policy of the pod. +While the policy is passed in during the initialization procedure via the host, the evidence for the runtime policy is part of the CPU measurements. +During the deployment the policy is annotated to the Kubernetes Pod resources. +The hypervisor adds the hash of the policy to the attestation report via the HOSTDATA (on AMD SEV-SNP) or MRCONFIGID (Intel TDX) fields. +When provided with the policy from the Kata host, the guest agent verifies that the policy's hash matches the one in the HOSTDATA/MRCONFIGID field.

+

In summary a Pod's evidence is the attestation report of the CPU that provides evidence for runtime environment and the runtime policy.

+

Verifier: Coordinator and CLI

+

The Coordinator acts as a verifier within the Contrast deployment, configured with a Manifest that defines the reference values and serves as an appraisal policy for all pods in the deployment. +It also pulls endorsements from hardware vendors to verify the hardware claims. +The Coordinator operates within the cluster as a confidential container and provides similar evidence as any other Pod when it acts as an attester. +In RATS terminology, the Coordinator's dual role is defined as a lead attester in a composite device which spans the entire deployment: Coordinator and the workload pods. +It collects evidence from other attesters and conveys it to a verifier, generating evidence about the layout of the whole composite device based on the Manifest as the appraisal policy.

+

Deployment attestation as a composite device

+

Figure 3: Contrast deployment as a composite device. Based on the composite device in RFC 9334.

+

The CLI serves as the verifier for the Coordinator and the entire Contrast deployment, containing the reference values for the Coordinator and the endorsements from hardware vendors. +These reference values are built into the CLI during our release process and can be reproduced offline via reproducible builds.

+

Relying Party: Data owner

+

A relying party in the Contrast scenario could be, for example, the data owner that interacts with the application. +The relying party can use the CLI to obtain the attestation results and Contrast's CA certificates bound to these results. +The CA certificates can then be used by the relying party to authenticate the application, for example through TLS connections.

+

Evidence generation and appraisal

+

Evidence types and formats

+

In Contrast, attestation evidence revolves around a hardware-generated attestation report, which contains several critical pieces of information:

+
    +
  • The hardware attestation report: This report includes details such as the chip identifier, platform information, microcode versions, and comprehensive guest measurements. The entire report is signed by the CPU's private key, ensuring the authenticity and integrity of the data provided.
  • +
  • The launch measurements: Included within the hardware attestation report, this is a digest generated by the CPU that represents a hash of all initial guest memory pages. This includes essential components like the kernel, initramfs, and the kernel command line. Notably, it incorporates the root filesystem's dm-verity root hash, verifying the integrity of the root filesystem.
  • +
  • The runtime policy hash: Also part of the hardware attestation report, this field contains the hash of the Rego policy which dictates all expected API commands and their values from the host to the Kata guest agent. It encompasses crucial settings such as dm-verity hashes for the container image layers, environment variables, and mount points.
  • +
+

Appraisal policies for evidence

+

The appraisal of this evidence in Contrast is governed by two main components:

+
    +
  • The Manifest: A JSON file used by the Coordinator to align with reference values. It sets the expectations for runtime policy hashes for each pod and includes what should be reported in the hardware attestation report for each component of the deployment.
  • +
  • The CLI's appraisal policy: This policy encompasses expected values of the Coordinator’s guest measurements and its runtime policy. It's embedded into the CLI during the build process and ensures that any discrepancy between the built-in values and those reported by the hardware attestation can be identified and addressed. The integrity of this policy is safeguardable through reproducible builds, allowing verification against the source code reference.
  • +
+

Frequently asked questions about attestation in Contrast

+

What's the purpose of remote attestation in Contrast?

+

Remote attestation in Contrast ensures that software runs within a secure, isolated confidential computing environment. +This process certifies that the memory is encrypted and confirms the integrity and authenticity of the software running within the deployment. +By validating the runtime environment and the policies enforced on it, Contrast ensures that the system operates in a trustworthy state and hasn't been tampered with.

+

How does Contrast ensure the security of the attestation process?

+

Contrast leverages hardware-rooted security features such as AMD SEV-SNP or Intel TDX to generate cryptographic evidence of a pod’s current state and configuration. +This evidence is checked against pre-defined appraisal policies to guarantee that only verified and authorized pods are part of a Contrast deployment.

+

What security benefits does attestation provide?

+

Attestation confirms the integrity of the runtime environment and the identity of the workloads. +It plays a critical role in preventing unauthorized changes and detecting potential modifications at runtime. +The attestation provides integrity and authenticity guarantees, enabling relying parties—such as workload operators or data owners—to confirm the effective protection against potential threats, including malicious cloud insiders, co-tenants, or compromised workload operators. +More details on the specific security benefits can be found here.

+

How can you verify the authenticity of attestation results?

+

Attestation results in Contrast are tied to cryptographic proofs generated and signed by the hardware itself. +These proofs are then verified using public keys from trusted hardware vendors, ensuring that the results aren't only accurate but also resistant to tampering. +For further authenticity verification, all of Contrast's code is reproducibly built, and the attestation evidence can be verified locally from the source code.

+

How are attestation results used by relying parties?

+

Relying parties use attestation results to make informed security decisions, such as allowing access to sensitive data or resources only if the attestation verifies the system's integrity. +Thereafter, the use of Contrast's CA certificates in TLS connections provides a practical approach to communicate securely with the application.

+

Summary

+

In summary, Contrast's attestation strategy adheres to the RATS guidelines and consists of robust verification mechanisms that ensure each component of the deployment is secure and trustworthy. +This comprehensive approach allows Contrast to provide a high level of security assurance to its users.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/architecture/certificates.html b/pr-preview/pr-976/next/architecture/certificates.html new file mode 100644 index 0000000000..a3d5994119 --- /dev/null +++ b/pr-preview/pr-976/next/architecture/certificates.html @@ -0,0 +1,84 @@ + + + + + +Certificate authority | Contrast + + + + + + + + + + + + + +
Version: Next

Certificate authority

+

The Coordinator acts as a certificate authority (CA) for the workloads +defined in the manifest. +After a workload pod's attestation has been verified by the Coordinator, +it receives a mesh certificate and the mesh CA certificate. +The mesh certificate can be used for example in a TLS connection as the server or +client certificate to proof to the other party that the workload has been +verified by the Coordinator. The other party can verify the mesh certificate +with the mesh CA certificate. While the certificates can be used by the workload +developer in different ways, they're automatically used in Contrast's service +mesh to establish mTLS connections between workloads in the same deployment.

+

Public key infrastructure

+

The Coordinator establishes a public key infrastructure (PKI) for all workloads +contained in the manifest. The Coordinator holds three certificates: the root CA +certificate, the intermediate CA certificate, and the mesh CA certificate. +The root CA certificate is a long-lasting certificate and its private key signs +the intermediate CA certificate. The intermediate CA certificate and the mesh CA +certificate share the same private key. This intermediate private key is used +to sign the mesh certificates. Moreover, the intermediate private key and +therefore the intermediate CA certificate and the mesh CA certificate are +rotated when setting a new manifest.

+

PKI certificate chain

+

Certificate rotation

+

Depending on the configuration of the first manifest, it allows the workload +owner to update the manifest and, therefore, the deployment. +Workload owners and data owners can be mutually untrusted parties. +To protect against the workload owner silently introducing malicious containers, +the Coordinator rotates the intermediate private key every time the manifest is +updated and, therefore, the +intermediate CA certificate and mesh CA certificate. If the user doesn't +trust the workload owner, they use the mesh CA certificate obtained when they +verified the Coordinator and the manifest. This ensures that the user only +connects to workloads defined in the manifest they verified since only those +workloads' certificates are signed with this intermediate private key.

+

Similarly, the service mesh also uses the mesh CA certificate obtained when the +workload was started, so the workload only trusts endpoints that have been +verified by the Coordinator based on the same manifest. Consequently, a +manifest update requires a fresh rollout of the services in the service mesh.

+

Usage of the different certificates

+
    +
  • The root CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This should only be used if the data owner trusts all future updates to the +manifest and workloads. This is, for instance, the case when the workload owner is +the same entity as the data owner.
  • +
  • The mesh CA certificate is returned when verifying the Coordinator. +The data owner can use it to verify the mesh certificates of the workloads. +This certificate is bound to the manifest set when the Coordinator is verified. +If the manifest is updated, the mesh CA certificate changes. +New workloads will receive mesh certificates signed by the new mesh CA certificate. +The Coordinator with the new manifest needs to be verified to retrieve the new mesh CA certificate. +The service mesh also uses the mesh CA certificate to verify the mesh certificates.
  • +
  • The intermediate CA certificate links the root CA certificate to the +mesh certificate so that the mesh certificate can be verified with the root CA +certificate. It's part of the certificate chain handed out by +endpoints in the service mesh.
  • +
  • The mesh certificate is part of the certificate chain handed out by +endpoints in the service mesh. During the startup of a pod, the Initializer +requests a certificate from the Coordinator. This mesh certificate will be returned if the Coordinator successfully +verifies the workload. The mesh certificate +contains X.509 extensions with information from the workloads attestation +document.
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/architecture/observability.html b/pr-preview/pr-976/next/architecture/observability.html new file mode 100644 index 0000000000..bce4bbad15 --- /dev/null +++ b/pr-preview/pr-976/next/architecture/observability.html @@ -0,0 +1,65 @@ + + + + + +Observability | Contrast + + + + + + + + + + + + + +
Version: Next

Observability

+

The Contrast Coordinator can expose metrics in the +Prometheus format. These can be monitored to quickly +identify problems in the gRPC layer or attestation errors. Prometheus metrics +are numerical values associated with a name and additional key/values pairs, +called labels.

+

Exposed metrics

+

The metrics can be accessed at the Coordinator pod at the port specified in the +CONTRAST_METRICS_PORT environment variable under the /metrics endpoint. By +default, this environment variable isn't specified, hence no metrics will be +exposed.

+

The Coordinator exports gRPC metrics under the prefix contrast_grpc_server_. +These metrics are labeled with the gRPC service name and method name. +Metrics of interest include contrast_grpc_server_handled_total, which counts +the number of requests by return code, and +contrast_grpc_server_handling_seconds_bucket, which produces a histogram of
+request latency.

+

The gRPC service userapi.UserAPI records metrics for the methods +SetManifest and GetManifest, which get called when setting the +manifest and verifying the +Coordinator respectively.

+

The meshapi.MeshAPI service records metrics for the method NewMeshCert, which +gets called by the Initializer when starting a +new workload. Attestation failures from workloads to the Coordinator can be +tracked with the counter contrast_meshapi_attestation_failures_total.

+

The current manifest generation is exposed as a +gauge with the metric +name contrast_coordinator_manifest_generation. If no manifest is set at the +Coordinator, this counter will be zero.

+

Service mesh metrics

+

The Service Mesh can be configured to expose +metrics via its Envoy admin +interface. Be +aware that the admin interface can expose private information and allows +destructive operations to be performed. To enable the admin interface for the +Service Mesh, set the annotation +contrast.edgeless.systems/servicemesh-admin-interface-port in the configuration +of your workload. If this annotation is set, the admin interface will be started +on this port.

+

To access the admin interface, the ingress settings of the Service Mesh have to +be configured to allow access to the specified port (see Configuring the +Proxy). All metrics will be +exposed under the /stats endpoint. Metrics in Prometheus format can be scraped +from the /stats/prometheus endpoint.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/architecture/secrets.html b/pr-preview/pr-976/next/architecture/secrets.html new file mode 100644 index 0000000000..7debaa4197 --- /dev/null +++ b/pr-preview/pr-976/next/architecture/secrets.html @@ -0,0 +1,56 @@ + + + + + +Secrets & recovery | Contrast + + + + + + + + + + + + + +
Version: Next

Secrets & recovery

+

When the Coordinator is configured with the initial manifest, it generates a random secret seed. +From this seed, it uses an HKDF to derive the CA root key and a signing key for the manifest history. +This derivation is deterministic, so the seed can be used to bring any Coordinator to this Coordinator's state.

+

The secret seed is returned to the user on the first call to contrast set, encrypted with the user's public seed share owner key. +If no seed share owner key is provided, a key is generated and stored in the working directory.

+

Persistence

+

The Coordinator runs as a StatefulSet with a dynamically provisioned persistent volume. +This volume stores the manifest history and the associated runtime policies. +The manifest isn't considered sensitive information, because it needs to be passed to the untrusted infrastructure in order to start workloads. +However, the Coordinator must ensure its integrity and that the persisted data corresponds to the manifests set by authorized users. +Thus, the manifest is stored in plain text, but is signed with a private key derived from the Coordinator's secret seed.

+

Recovery

+

When a Coordinator starts up, it doesn't have access to the signing secret and can thus not verify the integrity of the persisted manifests. +It needs to be provided with the secret seed, from which it can derive the signing key that verifies the signatures. +This procedure is called recovery and is initiated by the workload owner. +The CLI decrypts the secret seed using the private seed share owner key, verifies the Coordinator and sends the seed through the Recover method. +The Coordinator recovers its key material and verifies the manifest history signature.

+

Workload Secrets

+

The Coordinator provides each workload a secret seed during attestation. +This secret can be used by the workload to derive additional secrets for example to encrypt persistent data. +Like the workload certificates, it's written to the secrets/workload-secret-seed path under the shared Kubernetes volume contrast-secrets.

+
warning

The workload owner can decrypt data encrypted with secrets derived from the workload secret. +The workload owner can derive the workload secret themselves, since it's derived from the secret seed known to the workload owner. +If the data owner and the workload owner is the same entity, then they can safely use the workload secrets.

+

Secure persistence

+

Remember that persistent volumes from the cloud provider are untrusted. +Using the workload secret, applications can set up trusted storage on top of untrusted block devices. +The following, slightly abbreviated resource outlines how this could be realized:

+
warning

This configuration snippet is intended to be educational and needs to be refined and adapted to your production environment. +Using it as-is may result in data corruption or data loss.

+
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: volume-tester
spec:
template:
spec:
containers:
- name: main
image: my.registry/my-image@sha256:0123...
command:
- /bin/sh
- -ec
- | # <-- Custom script that mounts the encrypted disk and then calls the original application.
device=/dev/csi0
if ! cryptsetup isLuks $device; then
cryptsetup luksFormat $device /contrast/secrets/workload-secret-seed
cryptsetup open $device state -d /contrast/secrets/workload-secret-seed
mkfs.ext4 /dev/mapper/state
cryptsetup close state
fi
cryptsetup open $device state -d /contrast/secrets/workload-secret-seed
/path/to/original/app
name: volume-tester
volumeDevices:
- name: state
devicePath: /dev/csi0
securityContext:
privileged: true # <-- This is necessary for mounting devices.
runtimeClassName: contrast-cc
volumeClaimTemplates:
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: state
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
volumeMode: Block # <-- The requested volume needs to be a raw block device.
+
note

This example assumes that you can modify the container image to include a shell and the cryptsetup utility. +Alternatively, you can set up a secure mount from a sidecar container inside an emptyDir mount shared with the main container. +The Contrast end-to-end tests include an example of this type of mount.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/architecture/security-considerations.html b/pr-preview/pr-976/next/architecture/security-considerations.html new file mode 100644 index 0000000000..e41496123a --- /dev/null +++ b/pr-preview/pr-976/next/architecture/security-considerations.html @@ -0,0 +1,68 @@ + + + + + +Security Considerations | Contrast + + + + + + + + + + + + + +
Version: Next

Security Considerations

+

Contrast ensures application integrity and provides secure means of communication and bootstrapping (see security benefits). +However, care must be taken when interacting with the outside of Contrast's confidential environment. +This page presents some tips for writing secure applications and outlines the trust boundaries app developers need to know.

+

General recommendations

+

Authentication

+

The application receives credentials from the Contrast Coordinator during initialization. +This allows to authenticate towards peers and to verify credentials received from peers. +The application should use the certificate bundle to authenticate incoming requests and be wary of unauthenticated requests or requests with a different root of trust (for example the internet PKI).

+

The recommendation to authenticate not only applies to network traffic, but also to volumes, GPUs and other devices. +Generally speaking, all information provided by the world outside the confidential VM should be treated with due scepticism, especially if it's not authenticated. +Common cases where Kubernetes apps interact with external services include DNS, Kubernetes API clients and cloud storage endpoints.

+

Encryption

+

Any external persistence should be encrypted with an authenticated cipher. +This recommendation applies to block devices or filesystems mounted into the container, but also to cloud blob storage or external databases.

+

Contrast security guarantees

+

If an application authenticates with a certificate signed by the Contrast Mesh CA of a given manifest, Contrast provides the following guarantees:

+
    +
  1. The container images used by the app are the images specified in the resource definitions.
  2. +
  3. The command line arguments of containers are exactly the arguments specified in the resource definitions.
  4. +
  5. All environment variables are either specified in resource definitions, in the container image manifest or in a settings file for the Contrast CLI.
  6. +
  7. The containers run in a confidential VM that matches the reference values in the manifest.
  8. +
  9. The containers' root filesystems are mounted in encrypted memory.
  10. +
+

Limitations inherent to policy checking

+

Workload policies serve as workload identities. +From the perspective of the Contrast Coordinator, all workloads that authenticate with the same policy are equal. +Thus, it's not possible to disambiguate, for example, pods spawned from a deployment or to limit the amount of certificates issued per policy.

+

Container image references from Kubernetes resource definitions are taken into account when generating the policy. +A mutable reference may lead to policy failures or unverified image content, depending on the Contrast runtime. +Reliability and security can only be ensured with a full image reference, including digest. +The docker pull documentation explains pinned image references in detail.

+

Policies can only verify what can be inferred at generation time. +Some attributes of Kubernetes pods can't be predicted and thus can't be verified. +Particularly the downward API contains many fields that are dynamic or depend on the host environment, rendering it unsafe for process environment or arguments. +The same goes for ConfigMap and Secret resources, which can also be used to populate container fields. +If the application requires such external information, it should be injected as a mount point and carefully inspected before use.

+

Another type of dynamic content are persistent volumes. +Any volumes mounted to the pod need to be scrutinized, and sensitive data must not be written to unprotected volumes. +Ideally, a volume is mounted as a raw block device and authenticated encryption is added within the confidential container.

+

Logs

+

By default, container logs are visible to the host. +Sensitive information shouldn't be logged.

+

As of right now, hiding logs isn't natively supported. +If ReadStreamRequest is denied in the policy, the Kata Agent stops reading the logs. +This causes the pipes used for standard out and standard error to fill up and potentially deadlock the container. +If absolutely required, standard out and standard error should be manually redirected to /dev/null inside the container.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/basics/confidential-containers.html b/pr-preview/pr-976/next/basics/confidential-containers.html new file mode 100644 index 0000000000..dc99194060 --- /dev/null +++ b/pr-preview/pr-976/next/basics/confidential-containers.html @@ -0,0 +1,45 @@ + + + + + +Confidential Containers | Contrast + + + + + + + + + + + + + +
Version: Next

Confidential Containers

+

Contrast uses some building blocks from Confidential Containers (CoCo), a CNCF Sandbox project that aims to standardize confidential computing at the pod level. +The project is under active development and many of the high-level features are still in flux. +Contrast uses the more stable core primitive provided by CoCo: its Kubernetes runtime.

+

Kubernetes RuntimeClass

+

Kubernetes can be extended to use more than one container runtime with RuntimeClass objects. +The Container Runtime Interface (CRI) implementation, for example containerd, dispatches pod management API calls to the appropriate RuntimeClass. +RuntimeClass implementations are usually based on an OCI runtime, such as runc, runsc or crun. +In CoCo's case, the runtime is Kata Containers with added confidential computing capabilities.

+

Kata Containers

+

Kata Containers is an OCI runtime that runs pods in VMs. +The pod VM spawns an agent process that accepts management commands from the Kata runtime running on the host. +There are two options for creating pod VMs: local to the Kubernetes node, or remote VMs created with cloud provider APIs. +Using local VMs requires either bare-metal servers or VMs with support for nested virtualization. +Local VMs communicate with the host over a virtual socket. +For remote VMs, host-to-agent communication is tunnelled through the cloud provider's network.

+

Kata Containers was originally designed to isolate the guest from the host, but it can also run pods in confidential VMs (CVMs) to shield pods from their underlying infrastructure. +In confidential mode, the guest agent is configured with an Open Policy Agent (OPA) policy to authorize API calls from the host. +This policy also contains checksums for the expected container images. +It's derived from Kubernetes resource definitions and its checksum is included in the attestation report.

+

AKS CoCo preview

+

Azure Kubernetes Service (AKS) provides CoCo-enabled node pools as a preview offering. +These node pools leverage Azure VM types capable of nested virtualization (CVM-in-VM) and the CoCo stack is pre-installed. +Contrast can be deployed directly into a CoCo-enabled AKS cluster.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/basics/features.html b/pr-preview/pr-976/next/basics/features.html new file mode 100644 index 0000000000..82b7b611e2 --- /dev/null +++ b/pr-preview/pr-976/next/basics/features.html @@ -0,0 +1,39 @@ + + + + + +Product features | Contrast + + + + + + + + + + + + + +
Version: Next

Product features

+

Contrast simplifies the deployment and management of Confidential Containers, offering optimal data security for your workloads while integrating seamlessly with your existing Kubernetes environment.

+

From a security perspective, Contrast employs the Confidential Containers concept and provides security benefits that go beyond individual containers, shielding your entire deployment from the underlying infrastructure.

+

From an operational perspective, Contrast provides the following key features:

+
    +
  • +

    Managed Kubernetes compatibility: Initially compatible with Azure Kubernetes Service (AKS), Contrast is designed to support additional platforms such as AWS EKS and Google Cloud GKE as they begin to accommodate confidential containers.

    +
  • +
  • +

    Lightweight installation: Contrast can be integrated as a day-2 operation within existing clusters, adding minimal components to your setup. This facilitates straightforward deployments using your existing YAML configurations, Helm charts, or Kustomization, enabling native Kubernetes orchestration of your applications.

    +
  • +
  • +

    Remote attestation: Contrast generates a concise attestation statement that verifies the identity, authenticity, and integrity of your deployment both internally and to external parties. This architecture ensures that updates or scaling of the application don't compromise the attestation’s validity.

    +
  • +
  • +

    Service mesh: Contrast securely manages a Public Key Infrastructure (PKI) for your deployments, issues workload-specific certificates, and establishes transparent mutual TLS (mTLS) connections across pods. This is done by harnessing the envoy proxy to ensure secure communications within your Kubernetes cluster.

    +
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/basics/security-benefits.html b/pr-preview/pr-976/next/basics/security-benefits.html new file mode 100644 index 0000000000..3a9c7e0465 --- /dev/null +++ b/pr-preview/pr-976/next/basics/security-benefits.html @@ -0,0 +1,125 @@ + + + + + +Contrast security overview | Contrast + + + + + + + + + + + + + +
Version: Next

Contrast security overview

+

This document outlines the security measures of Contrast and its capability to counter various threats. +Contrast is designed to shield entire Kubernetes deployments from the infrastructure, enabling entities to manage sensitive information (such as regulated or personally identifiable information (PII)) in the public cloud, while maintaining data confidentiality and ownership.

+

Contrast is applicable in situations where establishing trust with the workload operator or the underlying infrastructure is challenging. +This is particularly beneficial for regulated sectors looking to transition sensitive activities to the cloud, without sacrificing security or compliance. +It allows for cloud adoption by maintaining a hardware-based separation from the cloud service provider.

+

Confidential computing foundation

+

Leveraging Confidential Computing technology, Contrast provides three defining security properties:

+
    +
  • Encryption of data in use: Contrast ensures that all data processed in memory is encrypted, making it inaccessible to unauthorized users or systems, even if they have physical access to the hardware.
  • +
  • Workload isolation: Each pod runs in its isolated runtime environment, preventing any cross-contamination between workloads, which is critical for multi-tenant infrastructures.
  • +
  • Remote attestation: This feature allows data owners and workload operators to verify that the Contrast environment executing their workloads hasn't been tampered with and is running in a secure, pre-approved configuration.
  • +
+

The runtime encryption is transparently provided by the confidential computing hardware during the workload's lifetime. +The workload isolation and remote attestation involves two phases:

+
    +
  • An attestation process detects modifications to the workload image or its runtime environment during the initialization. This protects the workload's integrity pre-attestation.
  • +
  • A protected runtime environment and a policy mechanism prevents the platform operator from accessing or compromising the instance at runtime. This protects a workload's integrity and confidentiality post-attestation.
  • +
+

For more details on confidential computing see our whitepaper. +The attestation architecture describes Contrast's attestation process and the resulting chain of trust in detail.

+

Components of a Contrast deployment

+

Contrast uses the Kubernetes runtime of the Confidential Containers project. +Confidential Containers significantly decrease the size of the trusted computing base (TCB) of a Kubernetes deployment, by isolating each pod within its own confidential micro-VM environment. +The TCB is the totality of elements in a computing environment that must be trusted not to be compromised. +A smaller TCB results in a smaller attack surface. The following diagram shows how Confidential Containers remove the cloud & datacenter infrastructure and the physical hosts, including the hypervisor, the host OS, the Kubernetes control plane, and other components, from the TCB (red). +In the confidential context, depicted in green, only the workload containers along with their confidential micro-VM environment are included within the TCB. +Their integrity is verifiable through remote attestation.

+

Contrast uses hardware-based mechanisms, specifically leveraging CPU features, such as AMD SEV or Intel TDX, to provide the isolation of the workload. +This implies that both the CPU and its microcode are integral components of the TCB. +However, it should be noted that the CPU microcode aspects aren't depicted in the accompanying graphic.

+

TCB comparison

+

Contrast adds the following components to a deployment that become part of the TCB. +The components that are part of the TCB are:

+
    +
  • The workload containers: Container images that run the actual application.
  • +
  • The runtime environment: The confidential micro-VM that acts as the container runtime.
  • +
  • The sidecar containers: Containers that provide additional functionality such as initialization and service mesh.
  • +
  • The runtime policies: Policies that enforce the runtime environments for the workload containers during their lifetime.
  • +
  • The manifest: A manifest file defining the reference values of an entire confidential deployment. It contains the policy hashes for all pods of the deployment and the expected hardware reference values for the Confidential Container runtime.
  • +
  • The Coordinator: An attestation service that runs in a Confidential Container in the Kubernetes cluster. The Coordinator is configured with the manifest. User-facing, you can verify this service and the effective manifest using remote attestation, providing you with a concise attestation for the entire deployment. Cluster-facing, it verifies all pods and their policies based on remote attestation procedures and the manifest.
  • +
+

Personas in a Contrast deployment

+

In a Contrast deployment, there are three parties:

+
    +
  • +

    The container image provider, who creates the container images that represent the application that has access to the protected data.

    +
  • +
  • +

    The workload operator, who runs the workload in a Kubernetes cluster. The operator typically has full administrative privileges to the deployment. The operator can manage cluster resources such as nodes, volumes, and networking rules, and the operator can interact with any Kubernetes or underlying cloud API.

    +
  • +
  • +

    The data owner, who owns the protected data. A data owner can verify the deployment using the Coordinator attestation service. The verification includes the identity, integrity, and confidentiality of the workloads, the runtime environment and the access permissions.

    +
  • +
+

Contrast supports a trust model where the container image provider, workload operator, and data owner are separate, mutually distrusting parties.

+

The following diagram shows the system components and parties.

+

Components and parties

+

Threat model and mitigations

+

This section describes the threat vectors that Contrast helps to mitigate.

+

The following attacks are out of scope for this document:

+
    +
  • Attacks on the application code itself, such as insufficient access controls.
  • +
  • Attacks on the Confidential Computing hardware directly, such as side-channel attacks.
  • +
  • Attacks on the availability, such as denial-of-service (DOS) attacks.
  • +
+

Possible attacks

+

Contrast is designed to defend against five possible attacks:

+
    +
  • A malicious cloud insider: malicious employees or third-party contractors of cloud service providers (CSPs) potentially have full access to various layers of the cloud infrastructure. That goes from the physical datacenter up to the hypervisor and Kubernetes layer. For example, they can access the physical memory of the machines, modify the hypervisor, modify disk contents, intercept network communications, and attempt to compromise the confidential container at runtime. A malicious insider can expand the attack surface or restrict the runtime environment. For example, a malicious operator can add a storage device to introduce new attack vectors. As another example, a malicious operator can constrain resources such as limiting a guest's memory size, changing its disk space, or changing firewall rules.
  • +
  • A malicious cloud co-tenant: malicious cloud user ("hackers") may break out of their tenancy and access other tenants' data. Advanced attackers may even be able to establish a permanent foothold within the infrastructure and access data over a longer period. The threats are analogous to the cloud insider access scenario, without the physical access.
  • +
  • A malicious workload operator: malicious workload operators, for example Kubernetes administrators, have full access to the workload deployment and the underlying Kubernetes platform. The threats are analogously to the cloud insider access scenario, with access to everything that's above the hypervisor level.
  • +
  • A malicious attestation client: this attacker connects to the attestation service and sends malformed request.
  • +
  • A malicious container image provider: a malicious container image provider has full control over the application development itself. This attacker might release a malicious version of the workload containing harmful operations.
  • +
+

Attack surfaces

+

The following table describes the attack surfaces that are available to attackers.

+
AttackerTargetAttack surfaceRisks
Cloud insiderConfidential Container, WorkloadPhysical memoryAttacker can dump the physical memory of the workloads.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk readsAnything read from the disk is within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadDisk writesAnything written to disk is visible to an attacker.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadKubernetes Control PlaneInstance attributes read from the Kubernetes control plane, including mount points and environment variables, are within the attacker's control.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadContainer RuntimeThe attacker can use container runtime APIs (for example "kubectl exec") to perform operations on the workload container.
Cloud insider, cloud hacker, workload operatorConfidential Container, WorkloadNetworkIntra-deployment (between containers) as well as external network connections to the image repository or attestation service can be intercepted.
Attestation clientCoordinator attestation serviceAttestation requestsThe attestation service has complex, crypto-heavy logic that's challenging to write defensively.
Container image providerWorkloadWorkloadThis attacker might release an upgrade to the workload containing harmful changes, such as a backdoor.
+

Threats and mitigations

+

Contrast shields a workload from the aforementioned threats with three main components:

+
    +
  1. The runtime environment safeguards against the physical memory and disk attack surface.
  2. +
  3. The runtime policies safeguard against the Kubernetes control plane and container runtime attack surface.
  4. +
  5. The service mesh safeguards against the network attack surface.
  6. +
+

The following tables describe concrete threats and how they're mitigated in Contrast grouped by these categories:

+
    +
  • Attacks on the confidential container environment
  • +
  • Attacks on the attestation service
  • +
  • Attacks on workloads
  • +
+

Attacks on the confidential container environment

+

This table describes potential threats and mitigation strategies related to the confidential container environment.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection of the launcher or image repository.An attacker can change the image URL and control the workload binary. However these actions are reflected in the attestation report. The image repository isn't controlled using an access list, therefore the image is assumed to be viewable by everyone. You must ensure that the workload container image doesn't contain any secrets.Within the runtime policies and attestation
An attacker modifies the workload image on disk after it was downloaded and measured.This threat is mitigated by a read-only partition that's integrity-protected. The workload image is protected by dm-verity.Within the Contrast runtime environment
An attacker modifies a container's runtime environment configuration in the Kubernetes control plane.The attestation process and the runtime policies detects unsafe configurations that load non-authentic images or perform any other modification to the expected runtime environment.Within the runtime policies and attestation
+

Attacks on the Coordinator attestation service

+

This table describes potential threats and mitigation strategies to the attestation service.

+
ThreatMitigationMitigation implementation
An attacker intercepts the Coordinator deployment and modifies the image or hijacks the runtime environment.This threat is mitigated by having an attestation procedure and attested, encrypted TLS connections to the Coordinator. The attestation evidence for the Coordinator image is distributed with our releases, protected by supply chain security, and fully reproducible.Within the attestation
An attacker intercepts the network connection between the workload and the Coordinator and reads secret keys from the wire.This threat is mitigated by having an attested, encrypted TLS connection. This connection helps protect the secrets from passive eavesdropping. The attacker can't create valid workload certificates that would be accepted in Contrast's service mesh. An attacker can't impersonate a valid workload container because the container's identity is guaranteed by the attestation protocol.Within the network between your workload and the Coordinator.
An attacker exploits parsing discrepancies, which leads to undetected changes in the attestation process.This risk is mitigated by having a parsing engine written in memory-safe Go that's tested against the attestation specification of the hardware vendor. The runtime policies are available as an attestation artifact for further inspection and audits to verify their effectiveness.Within the Coordinator
An attacker uses all service resources, which brings the Coordinator down in a denial of service (DoS) attack.In the future, this reliability risk is mitigated by having a distributed Coordinator service that can be easily replicated and scaled out as needed.Within the Coordinator
+

Attacks on workloads

+

This table describes potential threats and mitigation strategies related to workloads.

+
ThreatMitigationMitigation implementation
An attacker intercepts the network connection between two workload containers.This threat is mitigated by having transparently encrypted TLS connections between the containers in your deployment.Within the service mesh
An attacker reads or modifies data written to disk via persistent volumes.Currently, persistent volumes aren't supported in Contrast. In the future, this threat is mitigated by encrypted and integrity-protected volume mounts.Within the Contrast runtime environment
An attacker publishes a new image version containing malicious code.The attestation process and the runtime policies require a data owner to accept a specific version of the workload and any update to the workload needs to be explicitly acknowledged.Within the attestation
+

Examples of Contrast's threat model in practice

+

The following table describes three example use cases and how they map to the defined threat model in this document:

+
Use CaseExample Scenario
Migrate sensitive workloads to the cloudTechSolve Inc., a software development firm, aimed to enhance its defense-in-depth strategy for its cloud-based development environment, especially for projects involving proprietary algorithms and client data. TechSolve acts as the image provider, workload operator, and data owner, combining all three personas in this scenario. In our attestation terminology, they're the workload operator and relying party in one entity. Their threat model includes a malicious cloud insider and cloud co-tenant.
Make your SaaS more trustworthySaaSProviderX, a company offering cloud-based project management tools, sought to enhance its platform's trustworthiness amidst growing concerns about data breaches and privacy. Here, the relying party is the SaaS customer as the data owner. The goal is to achieve a form of operator exclusion and only allow selective operations on the deployment. Hence, their threat model includes a malicious workload operator.
Simplify regulatory complianceHealthSecure Inc. has been managing a significant volume of sensitive patient data on-premises. With the increasing demand for advanced data analytics and the need for scalable infrastructure, the firm decides to migrate its data analytics operations to the cloud. However, the primary concern is maintaining the confidentiality and security of patient data during and after the migration, in compliance with healthcare regulations. In this compliance scenario, the regulator serves as an additional relying party. HealthSecure must implement a mechanism that ensures the isolation of patient data can be verifiably guaranteed to the regulator.
+

In each scenario, Contrast ensures exclusive data access and processing capabilities are confined to the designated workloads. It achieves this by effectively isolating the workload from the infrastructure and other components of the stack. Data owners are granted the capability to audit and approve the deployment environment before submitting their data, ensuring a secure handover. Meanwhile, workload operators are equipped to manage and operate the application seamlessly, without requiring direct access to either the workload or its associated data.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/components/overview.html b/pr-preview/pr-976/next/components/overview.html new file mode 100644 index 0000000000..2a25af94c2 --- /dev/null +++ b/pr-preview/pr-976/next/components/overview.html @@ -0,0 +1,68 @@ + + + + + +Components | Contrast + + + + + + + + + + + + + +
Version: Next

Components

+

Contrast is composed of several key components that work together to manage and scale confidential containers effectively within Kubernetes environments. +This page provides an overview of the core components essential for deploying and managing Contrast.

+

components overview

+

The CLI (Command Line Interface)

+

The CLI serves as the primary management tool for Contrast deployments. It's designed to streamline the configuration and operation of Contrast in several ways:

+
    +
  • Installation and setup: The CLI facilitates the installation of the necessary runtime classes required for Contrast to function within a Kubernetes cluster.
  • +
  • Policy generation: It allows users to generate runtime policies, adapt the deployment files, and generate the Contrast manifest.
  • +
  • Configuration management: Through the CLI, users can configure the Contrast Coordinator with the generated manifest.
  • +
  • Verification and attestation: The CLI provides tools to verify the integrity and authenticity of the Coordinator and the entire deployment via remote attestation.
  • +
+

The Coordinator

+

The Contrast Coordinator is the central remote attestation service of a Contrast deployment. +It runs inside a confidential container inside your cluster. +The Coordinator can be verified via remote attestation, and a Contrast deployment is self-contained. +The Coordinator is configured with a manifest, a configuration file containing the reference attestation values of your deployment. +It ensures that your deployment's topology adheres to your specified manifest by verifying the identity and integrity of all confidential pods inside the deployment. +The Coordinator is also a certificate authority and issues certificates for your workload pods during the attestation procedure. +Your workload pods can establish secure, encrypted communication channels between themselves based on these certificates using the Coordinator as the root CA. +As your app needs to scale, the Coordinator transparently verifies new instances and then provides them with their certificates to join the deployment.

+

To verify your deployment, the Coordinator's remote attestation statement combined with the manifest offers a concise single remote attestation statement for your entire deployment. +A third party can use this to verify the integrity of your distributed app, making it easy to assure stakeholders of your app's identity and integrity.

+

The Manifest

+

The manifest is the configuration file for the Coordinator, defining your confidential deployment. +It's automatically generated from your deployment by the Contrast CLI. +It currently consists of the following parts:

+
    +
  • Policies: The identities of your Pods, represented by the hashes of their respective runtime policies.
  • +
  • Reference Values: The remote attestation reference values for the Kata confidential micro-VM that's the runtime environment of your Pods.
  • +
  • WorkloadOwnerKeyDigest: The workload owner's public key digest. Used for authenticating subsequent manifest updates.
  • +
+

Runtime policies

+

Runtime Policies are a mechanism to enable the use of the untrusted Kubernetes API for orchestration while ensuring the confidentiality and integrity of your confidential containers. +They allow us to enforce the integrity of your containers' runtime environment as defined in your deployment files. +The runtime policy mechanism is based on the Open Policy Agent (OPA) and translates the Kubernetes deployment YAML into the Rego policy language of OPA. +The Kata Agent inside the confidential micro-VM then enforces the policy by only acting on permitted requests. +The Contrast CLI provides the tooling for automatically translating Kubernetes deployment YAML into the Rego policy language of OPA.

+

The Initializer

+

Contrast provides an Initializer that handles the remote attestation on the workload side transparently and +fetches the workload certificate. The Initializer runs as an init container before your workload is started. +It provides the workload container and the service mesh sidecar with the workload certificates.

+

The Contrast runtime

+

Contrast depends on a Kubernetes runtime class, which is installed +by the node-installer DaemonSet. +This runtime consists of a containerd runtime plugin, a virtual machine manager (cloud-hypervisor), and a podvm image (IGVM and rootFS). +The installer takes care of provisioning every node in the cluster so it provides this runtime class.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/components/policies.html b/pr-preview/pr-976/next/components/policies.html new file mode 100644 index 0000000000..9919ee05c7 --- /dev/null +++ b/pr-preview/pr-976/next/components/policies.html @@ -0,0 +1,85 @@ + + + + + +Policies | Contrast + + + + + + + + + + + + + +
Version: Next

Policies

+

Kata runtime policies are an integral part of the Confidential Containers preview on AKS. +They prescribe how a Kubernetes pod must be configured to launch successfully in a confidential VM. +In Contrast, policies act as a workload identifier: only pods with a policy registered in the manifest receive workload certificates and may participate in the confidential deployment. +Verification of the Contrast Coordinator and its manifest transitively guarantees that all workloads meet the owner's expectations.

+

Structure

+

The Kata agent running in the confidential micro-VM exposes an RPC service AgentService to the Kata runtime. +This service handles potentially untrustworthy requests from outside the TCB, which need to be checked against a policy.

+

Kata runtime policies are written in the policy language Rego. +They specify what AgentService methods can be called, and the permissible parameters for each call.

+

Policies consist of two parts: a list of rules and a data section. +While the list of rules is static, the data section is populated with information from the PodSpec and other sources.

+

Generation

+

Runtime policies are programmatically generated from Kubernetes manifests by the Contrast CLI. +The generate subcommand inspects pod definitions and derives rules for validating the pod at the Kata agent. +There are two important integrity checks: container image checksums and OCI runtime parameters.

+

For each of the container images used in a pod, the CLI downloads all image layers and produces a cryptographic dm-verity checksum. +These checksums are the basis for the policy's storage data.

+

The CLI combines information from the PodSpec, ConfigMaps, and Secrets in the provided Kubernetes manifests to derive a permissible set of command-line arguments and environment variables. +These constitute the policy's OCI data.

+

Evaluation

+

The generated policy document is annotated to the pod definitions in Base64 encoding. +This annotation is propagated to the Kata runtime, which calculates the SHA256 checksum for the policy and uses that as SNP HOSTDATA or TDX MRCONFIGID for the confidential micro-VM.

+

After the VM launched, the runtime calls the agent's SetPolicy method with the full policy document. +If the policy doesn't match the checksum in HOSTDATA or MRCONFIGID, the agent rejects the policy. +Otherwise, it applies the policy to all future AgentService requests.

+

Guarantees

+

The policy evaluation provides the following guarantees for pods launched with the correct generated policy:

+
    +
  • Command and its arguments are set as specified in the resources.
  • +
  • There are no unexpected additional environment variables.
  • +
  • The container image layers correspond to the layers observed at policy generation time. +Thus, only the expected workload image can be instantiated.
  • +
  • Executing additional processes in a container is prohibited.
  • +
  • Sending data to a container's standard input is prohibited.
  • +
+

The current implementation of policy checking has some blind spots:

+
    +
  • Containers can be started in any order, or be omitted entirely.
  • +
  • Environment variables may be missing.
  • +
  • Volumes other than the container root volume don't have integrity checks (particularly relevant for mounted ConfigMaps and Secrets).
  • +
+

Trust

+

Contrast verifies its confidential containers following these steps:

+
    +
  1. The Contrast CLI generates a policy and attaches it to the pod definition.
  2. +
  3. Kubernetes schedules the pod on a node with the confidential computing runtime.
  4. +
  5. Containerd invokes the Kata runtime to create the pod sandbox.
  6. +
  7. The Kata runtime starts a CVM with the policy's digest as HOSTDATA/MRCONFIGID.
  8. +
  9. The Kata runtime sets the policy using the SetPolicy method.
  10. +
  11. The Kata agent verifies that the incoming policy's digest matches HOSTDATA/MRCONFIGID.
  12. +
  13. The CLI sets a manifest in the Contrast Coordinator, including a list of permitted policies.
  14. +
  15. The Contrast Initializer sends an attestation report to the Contrast Coordinator, asking for a mesh certificate.
  16. +
  17. The Contrast Coordinator verifies that the started pod has a permitted policy hash in its HOSTDATA/MRCONFIGID field.
  18. +
+

After the last step, we know that the policy hasn't been tampered with and, thus, that the workload matches expectations and may receive mesh certificates.

+

Platform Differences

+

Contrast uses different rules and data sections for different platforms. +This results in different policy hashes for different platforms.

+

The generate command automatically derives the correct set of rules and data sections from the reference-values flag.

+

The verify, set, and recover commands need to know the coordinator's expected policy hash to verify its identity. +By default these commands assume that the coordinator is using the policy for the AKS-CLH-SNP platform. +If the coordinator is running on a different platform, the correct policy hash can be looked up in the coordinator-policy.hash file bundled with the Contrast release. +The coordinator policy hash can be overwritten using the --coordinator-policy-hash flag.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/components/runtime.html b/pr-preview/pr-976/next/components/runtime.html new file mode 100644 index 0000000000..fad46efd01 --- /dev/null +++ b/pr-preview/pr-976/next/components/runtime.html @@ -0,0 +1,77 @@ + + + + + +Contrast Runtime | Contrast + + + + + + + + + + + + + +
Version: Next

Contrast Runtime

+

The Contrast runtime is responsible for starting pods as confidential virtual machines. +This works by specifying the runtime class to be used in a pod spec and by registering the runtime class with the apiserver. +The RuntimeClass resource defines a name for referencing the class and +a handler used by the container runtime (containerd) to identify the class.

+
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
# This name is used by pods in the runtimeClassName field
name: contrast-cc-abcdef
# This name is used by the
# container runtime interface implementation (containerd)
handler: contrast-cc-abcdef
+

Confidential pods that are part of a Contrast deployment need to specify the +same runtime class in the runtimeClassName field, so Kubernetes uses the +Contrast runtime instead of the default containerd / runc handler.

+
apiVersion: v1
kind: Pod
spec:
runtimeClassName: contrast-cc-abcdef
# ...
+

Node-level components

+

The runtime consists of additional software components that need to be installed +and configured on every SEV-SNP-enabled/TDX-enabled worker node. +This installation is performed automatically by the node-installer DaemonSet.

+

Runtime components

+

Containerd shim

+

The handler field in the Kubernetes RuntimeClass instructs containerd not to use the default runc implementation. +Instead, containerd invokes a custom plugin called containerd-shim-contrast-cc-v2. +This shim is described in more detail in the upstream source repository and in the containerd documentation.

+

Virtual machine manager (VMM)

+

The containerd shim uses a virtual machine monitor to create a confidential virtual machine for every pod. +On AKS, Contrast uses cloud-hypervisor. +On bare metal, Contrast uses QEMU. +The appropriate files are installed on every node by the node-installer.

+

Snapshotters

+

Contrast uses containerd snapshotters to provide container images to the pod-VM. +Each snapshotter consists of a host component that pulls container images and a guest component used to mount/pull container images.

+

On AKS, Contrast uses the tardev snapshotter to provide container images as block devices to the pod-VM. +The tardev snapshotter uses dm-verity to protect the integrity of container images. +Expected dm-verity container image hashes are part of Contrast runtime policies and are enforced by the kata-agent. +This enables workload attestation by specifying the allowed container image as part of the policy. Read the chapter on policies for more information.

+

On bare metal, Contrast uses the nydus snapshotter to store metadata about the images. This metadata is communicated to the guest, so that it can pull the images itself.

+

Pod-VM image

+

Every pod-VM starts with the same guest image. It consists of an IGVM file and a root filesystem. +The IGVM file describes the initial memory contents of a pod-VM and consists of:

+
    +
  • Linux kernel image
  • +
  • initrd
  • +
  • kernel commandline
  • +
+

Additionally, a root filesystem image is used that contains a read-only partition with the user space of the pod-VM and a verity partition to guarantee the integrity of the root filesystem. +The root filesystem contains systemd as the init system, and the kata agent for managing the pod.

+

This pod-VM image isn't specific to any pod workload. Instead, container images are mounted at runtime.

+

Node installer DaemonSet

+

The RuntimeClass resource above registers the runtime with the Kubernetes api. +The node-level installation is carried out by the Contrast node-installer +DaemonSet that ships with every Contrast release.

+

After deploying the installer, it performs the following steps on each node:

+
    +
  • Install the Contrast containerd shim (containerd-shim-contrast-cc-v2)
  • +
  • Install cloud-hypervisor or QEMU as the virtual machine manager (VMM)
  • +
  • Install an IGVM file or separate firmware and kernel files for pod-VMs of this class
  • +
  • Install a read only root filesystem disk image for the pod-VMs of this class
  • +
  • Reconfigure containerd by adding a runtime plugin that corresponds to the handler field of the Kubernetes RuntimeClass
  • +
  • Restart containerd to make it aware of the new plugin
  • +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/components/service-mesh.html b/pr-preview/pr-976/next/components/service-mesh.html new file mode 100644 index 0000000000..668d6e17fd --- /dev/null +++ b/pr-preview/pr-976/next/components/service-mesh.html @@ -0,0 +1,97 @@ + + + + + +Service mesh | Contrast + + + + + + + + + + + + + +
Version: Next

Service mesh

+

The Contrast service mesh secures the communication of the workload by automatically +wrapping the network traffic inside mutual TLS (mTLS) connections. The +verification of the endpoints in the connection establishment is based on +certificates that are part of the +PKI of the Coordinator.

+

The service mesh can be enabled on a per-workload basis by adding a service mesh +configuration to the workload's object annotations. During the contrast generate +step, the service mesh is added as a sidecar +container to +all workloads which have a specified configuration. The service mesh container first +sets up iptables rules based on its configuration and then starts +Envoy for TLS origination and termination.

+

Configuring the proxy

+

The service mesh container can be configured using the following object annotations:

+
    +
  • contrast.edgeless.systems/servicemesh-ingress to configure ingress.
  • +
  • contrast.edgeless.systems/servicemesh-egress to configure egress.
  • +
  • contrast.edgeless.systems/servicemesh-admin-interface-port to configure the Envoy +admin interface. If not specified, no admin interface will be started.
  • +
+

If you aren't using the automatic service mesh injection and want to configure the +service mesh manually, set the environment variables CONTRAST_INGRESS_PROXY_CONFIG, +CONTRAST_EGRESS_PROXY_CONFIG and CONTRAST_ADMIN_PORT in the service mesh sidecar directly.

+

Ingress

+

All TCP ingress traffic is routed over Envoy by default. Since we use +TPROXY, the destination address +remains the same throughout the packet handling.

+

Any incoming connection is required to present a client certificate signed by the +mesh CA certificate. +Envoy presents a certificate chain of the mesh +certificate of the workload and the intermediate CA certificate as the server certificate.

+

If the deployment contains workloads which should be reachable from outside the +Service Mesh, while still handing out the certificate chain, disable client +authentication by setting the annotation contrast.edgeless.systems/servicemesh-ingress as +<name>#<port>#false. Separate multiple entries with ##. You can choose any +descriptive string identifying the service on the given port for the <name> field, +as it's only informational.

+

Disable redirection and TLS termination altogether by specifying +<name>#<port>#true. This can be beneficial if the workload itself handles TLS +on that port or if the information exposed on this port is non-sensitive.

+

The following example workload exposes a web service on port 8080 and metrics on +port 7890. The web server is exposed to a 3rd party end-user which wants to +verify the deployment, therefore it's still required that the server hands out +it certificate chain signed by the mesh CA certificate. The metrics should be +exposed via TCP without TLS.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-ingress: "web#8080#false##metrics#7890#true"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: web-svc
image: ghcr.io/edgelesssys/frontend:v1.2.3@...
ports:
- containerPort: 8080
name: web
- containerPort: 7890
name: metrics
+

When invoking contrast generate, the resulting deployment will be injected with the +Contrast service mesh as an init container.

+
# ...
initContainers:
- env:
- name: CONTRAST_INGRESS_PROXY_CONFIG
value: "web#8080#false##metrics#7890#true"
image: "ghcr.io/edgelesssys/contrast/service-mesh-proxy:latest"
name: contrast-service-mesh
restartPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN
privileged: true
volumeMounts:
- name: contrast-secrets
mountPath: /contrast
+

Note, that changing the environment variables of the sidecar container directly will +only have an effect if the workload isn't configured to automatically generate a +service mesh component on contrast generate. Otherwise, the service mesh sidecar +container will be regenerated on every invocation of the command.

+

Egress

+

To be able to route the egress traffic of the workload through Envoy, the remote +endpoints' IP address and port must be configurable.

+
    +
  • Choose an IP address inside the 127.0.0.0/8 CIDR and a port not yet in use +by the pod.
  • +
  • Configure the workload to connect to this IP address and port.
  • +
  • Set <name>#<chosen IP>:<chosen port>#<original-hostname-or-ip>:<original-port> +as the contrast.edgeless.systems/servicemesh-egress workload annotation. Separate multiple +entries with ##. Choose any string identifying the service on the given port as +<name>.
  • +
+

This redirects the traffic over Envoy. The endpoint must present a valid +certificate chain which must be verifiable with the +mesh CA certificate. +Furthermore, Envoy uses a certificate chain with the mesh certificate of the workload +and the intermediate CA certificate as the client certificate.

+

The following example workload has no ingress connections and two egress +connection to different microservices. The microservices are part +of the confidential deployment. One is reachable under billing-svc:8080 and +the other under cart-svc:8080.

+
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
annotations:
contrast.edgeless.systems/servicemesh-egress: "billing#127.137.0.1:8081#billing-svc:8080##cart#127.137.0.2:8081#cart-svc:8080"
spec:
replicas: 1
template:
spec:
runtimeClassName: contrast-cc
containers:
- name: currency-conversion
image: ghcr.io/edgelesssys/conversion:v1.2.3@...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/deployment.html b/pr-preview/pr-976/next/deployment.html new file mode 100644 index 0000000000..a052da92bc --- /dev/null +++ b/pr-preview/pr-976/next/deployment.html @@ -0,0 +1,140 @@ + + + + + +Workload deployment | Contrast + + + + + + + + + + + + + +
Version: Next

Workload deployment

+

The following instructions will guide you through the process of making an existing Kubernetes deployment +confidential and deploying it together with Contrast.

+

A running CoCo-enabled cluster is required for these steps, see the setup guide on how to set up a cluster on AKS.

+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass (contrast-cc), +which needs to be installed in the cluster prior to the Coordinator or any confidential workloads. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-aks-clh-snp.yml
+

Deploy the Contrast Coordinator

+

Install the latest Contrast Coordinator release, comprising a single replica deployment and a +LoadBalancer service, into your cluster.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-aks-clh-snp.yml
+

Prepare your Kubernetes resources

+

Your Kubernetes resources need some modifications to run as Confidential Containers. +This section guides you through the process and outlines the necessary changes.

+

Security review

+

Contrast ensures integrity and confidentiality of the applications, but interactions with untrusted systems require the developers' attention. +Review the security considerations and the certificates section for writing secure Contrast application.

+

RuntimeClass

+

Contrast will add annotations to your Kubernetes YAML files. If you want to keep the original files +unchanged, you can copy the files into a separate local directory. +You can also generate files from a Helm chart or from a Kustomization.

+
mkdir resources
kustomize build $MY_RESOURCE_DIR > resources/all.yml
+

To specify that a workload (pod, deployment, etc.) should be deployed as confidential containers, +add runtimeClassName: contrast-cc to the pod spec (pod definition or template). +This is a placeholder name that will be replaced by a versioned runtimeClassName when generating policies.

+
spec: # v1.PodSpec
runtimeClassName: contrast-cc
+

Handling TLS

+

In the initialization process, the contrast-secrets shared volume is populated with X.509 certificates for your workload. +These certificates are used by the Contrast Service Mesh, but can also be used by your application directly. +The following tab group explains the setup for both scenarios.

+

Contrast can be configured to handle TLS in a sidecar container. +This is useful for workloads that are hard to configure with custom certificates, like Java applications.

Configuration of the sidecar depends heavily on the application. +The following example is for an application with these properties:

    +
  • The container has a main application at TCP port 8001, which should be TLS-wrapped and doesn't require client authentication.
  • +
  • The container has a metrics endpoint at TCP port 8080, which should be accessible in plain text.
  • +
  • All other endpoints require client authentication.
  • +
  • The app connects to a Kubernetes service backend.default:4001, which requires client authentication.
  • +

Add the following annotations to your workload:

metadata: # apps/v1.Deployment, apps/v1.DaemonSet, ...
annotations:
contrast.edgeless.systems/servicemesh-ingress: "main#8001#false##metrics#8080#true"
contrast.edgeless.systems/servicemesh-egress: "backend#127.0.0.2:4001#backend.default:4001"

During the generate step, this configuration will be translated into a Service Mesh sidecar container which handles TLS connections automatically. +The only change required to the app itself is to let it connect to 127.0.0.2:4001 to reach the backend service. +You can find more detailed documentation in the Service Mesh chapter.

+

Generate policy annotations and manifest

+

Run the generate command to add the necessary components to your deployment files. +This will add the Contrast Initializer to every workload with the specified contrast-cc runtime class +and the Contrast Service Mesh to all workloads that have a specified configuration. +After that, it will generate the execution policies and add them as annotations to your deployment files. +A manifest.json with the reference values of your deployment will be created.

+
contrast generate --reference-values aks-clh-snp resources/
+
warning

Please be aware that runtime policies currently have some blind spots. For example, they can't guarantee the starting order of containers. See the current limitations for more details.

+

If you don't want the Contrast Initializer to automatically be added to your +workloads, there are two ways you can skip the Initializer injection step, +depending on how you want to customize your deployment.

+

You can disable the Initializer injection completely by specifying the +--skip-initializer flag in the generate command.

contrast generate --reference-values aks-clh-snp --skip-initializer resources/
+

When disabling the automatic Initializer injection, you can manually add the +Initializer as a sidecar container to your workload before generating the +policies. Configure the workload to use the certificates written to the +contrast-secrets volumeMount.

+
# v1.PodSpec
spec:
initContainers:
- env:
- name: COORDINATOR_HOST
value: coordinator
image: "ghcr.io/edgelesssys/contrast/initializer:latest"
name: contrast-initializer
volumeMounts:
- mountPath: /contrast
name: contrast-secrets
volumes:
- emptyDir: {}
name: contrast-secrets
+

Apply the resources

+

Apply the resources to the cluster. Your workloads will block in the initialization phase until a +manifest is set at the Coordinator.

+
kubectl apply -f resources/
+

Connect to the Contrast Coordinator

+

For the next steps, we will need to connect to the Coordinator. The released Coordinator resource +includes a LoadBalancer definition we can use.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
+
Port-forwarding of Confidential Containers

kubectl port-forward uses a Container Runtime Interface (CRI) method that isn't supported by the Kata shim. +If you can't use a public load balancer, you can deploy a port-forwarder. +The port-forwarder relays traffic from a CoCo pod and can be accessed via kubectl port-forward.

Upstream tracking issue: https://github.com/kata-containers/kata-containers/issues/1693.

+

Set the manifest

+

Attest the Coordinator and set the manifest:

+
contrast set -c "${coordinator}:1313" resources/
+

This will use the reference values from the manifest file to attest the Coordinator. +After this step, the Coordinator will start issuing TLS certificates to the workloads. The init container +will fetch a certificate for the workload and the workload is started.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Verify the Coordinator

+

An end user (data owner) can verify the Contrast deployment using the verify command.

+
contrast verify -c "${coordinator}:1313"
+

The CLI will attest the Coordinator using the reference values from the given manifest file. It will then write the +service mesh root certificate and the history of manifests into the verify/ directory. In addition, the policies +referenced in the active manifest are also written to the directory. The verification will fail if the active +manifest at the Coordinator doesn't match the manifest passed to the CLI.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Communicate with workloads

+

You can securely connect to the workloads using the Coordinator's mesh-ca.pem as a trusted CA certificate. +First, expose the service on a public IP address via a LoadBalancer service:

+
kubectl patch svc ${MY_SERVICE} -p '{"spec": {"type": "LoadBalancer"}}'
kubectl wait --timeout=30s --for=jsonpath='{.status.loadBalancer.ingress}' service/${MY_SERVICE}
lbip=$(kubectl get svc ${MY_SERVICE} -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $lbip
+
Subject alternative names and LoadBalancer IP

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the SAN field. +Validation fails since the certificate contains no IP entries as a subject alternative name (SAN). +For example, attempting to connect with curl and the mesh CA certificate will throw the following error:

$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Recover the Coordinator

+

If the Contrast Coordinator restarts, it enters recovery mode and waits for an operator to provide key material. +For demonstration purposes, you can simulate this scenario by deleting the Coordinator pod.

+
kubectl delete pod -l app.kubernetes.io/name=coordinator
+

Kubernetes schedules a new pod, but that pod doesn't have access to the key material the previous pod held in memory and can't issue certificates for workloads yet. +You can confirm this by running verify again, or you can restart a workload pod, which should stay in the initialization phase. +However, the secret seed in your working directory is sufficient to recover the coordinator.

+
contrast recover -c "${coordinator}:1313"
+

Now that the Coordinator is recovered, all workloads should pass initialization and enter the running state. +You can now verify the Coordinator again, which should return the same manifest you set before.

+
warning

The recovery process invalidates the mesh CA certificate: +existing workloads won't be able to communicate with workloads newly spawned. +All workloads should be restarted after the recovery succeeded.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/examples/emojivoto.html b/pr-preview/pr-976/next/examples/emojivoto.html new file mode 100644 index 0000000000..a5af77671a --- /dev/null +++ b/pr-preview/pr-976/next/examples/emojivoto.html @@ -0,0 +1,146 @@ + + + + + +Confidential emoji voting | Contrast + + + + + + + + + + + + + +
Version: Next

Confidential emoji voting

+

screenshot of the emojivoto UI

+

This tutorial guides you through deploying emojivoto as a +confidential Contrast deployment and validating the deployment from a voter's perspective.

+

Emojivoto is an example app allowing users to vote for different emojis and view votes +on a leader board. It has a microservice architecture consisting of a +web frontend (web), a gRPC backend for listing available emojis (emoji), and a backend for +the voting and leader board logic (voting). The vote-bot simulates user traffic by submitting +votes to the frontend.

+

Emojivoto can be seen as a lighthearted example of an app dealing with sensitive data. +Contrast protects emojivoto in two ways. First, it shields emojivoto as a whole from the infrastructure, for example, Azure. +Second, it can be configured to also prevent data access even from the administrator of the app. In the case of emojivoto, this gives assurance to users that their votes remain secret.

+

emojivoto components topology

+

Prerequisites

+
    +
  • Installed Contrast CLI
  • +
  • A running Kubernetes cluster with support for confidential containers, either on AKS or on bare metal.
  • +
+

Steps to deploy emojivoto with Contrast

+

Download the deployment files

+

The emojivoto deployment files are part of the Contrast release. You can download them by running:

+
curl -fLO https://github.com/edgelesssys/contrast/releases/latest/download/emojivoto-demo.yml --create-dirs --output-dir deployment
+

Deploy the Contrast runtime

+

Contrast depends on a custom Kubernetes RuntimeClass, +which needs to be installed to the cluster initially. +This consists of a RuntimeClass resource and a DaemonSet that performs installation on worker nodes. +This step is only required once for each version of the runtime. +It can be shared between Contrast deployments.

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/runtime-aks-clh-snp.yml
+

Deploy the Contrast Coordinator

+

Deploy the Contrast Coordinator, comprising a single replica deployment and a +LoadBalancer service, into your cluster:

+
kubectl apply -f https://github.com/edgelesssys/contrast/releases/latest/download/coordinator-aks-clh-snp.yml
+

Generate policy annotations and manifest

+

Run the generate command to generate the execution policies and add them as +annotations to your deployment files. A manifest.json file with the reference values +of your deployment will be created:

+
contrast generate --reference-values aks-clh-snp deployment/
+
Runtime class and Initializer

The deployment YAML shipped for this demo is already configured to be used with Contrast. +A runtime class contrast-cc-<platform>-<runtime-hash> +was added to the pods to signal they should be run as Confidential Containers. During the generation process, +the Contrast Initializer will be added as an init container to these +workloads to facilitate the attestation and certificate pulling before the actual workload is started.

Further, the deployment YAML is also configured with the Contrast service mesh. +The configured service mesh proxy provides transparent protection for the communication between +the different components of emojivoto.

+

Set the manifest

+

Configure the coordinator with a manifest. It might take up to a few minutes +for the load balancer to be created and the Coordinator being available.

+
coordinator=$(kubectl get svc coordinator -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "The user API of your Contrast Coordinator is available at $coordinator:1313"
contrast set -c "${coordinator}:1313" deployment/
+

The CLI will use the reference values from the manifest to attest the Coordinator deployment +during the TLS handshake. If the connection succeeds, it's ensured that the Coordinator +deployment hasn't been tampered with.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Deploy emojivoto

+

Now that the coordinator has a manifest set, which defines the emojivoto deployment as an allowed workload, +we can deploy the application:

+
kubectl apply -f deployment/
+
Inter-deployment communication

The Contrast Coordinator issues mesh certificates after successfully validating workloads. +These certificates can be used for secure inter-deployment communication. The Initializer +sends an attestation report to the Coordinator, retrieves certificates and a private key in return +and writes them to a volumeMount. The service mesh sidecar is configured to use the credentials +from the volumeMount when communicating with other parts of the deployment over mTLS. +The public facing frontend for voting uses the mesh certificate without client authentication.

+

Verifying the deployment as a user

+

In different scenarios, users of an app may want to verify its security and identity before sharing data, for example, before casting a vote. +With Contrast, a user only needs a single remote-attestation step to verify the deployment - regardless of the size or scale of the deployment. +Contrast is designed such that, by verifying the Coordinator, the user transitively verifies those systems the Coordinator has already verified or will verify in the future. +Successful verification of the Coordinator means that the user can be sure that the given manifest will be enforced.

+

Verifying the Coordinator

+

A user can verify the Contrast deployment using the verify +command:

+
contrast verify -c "${coordinator}:1313" -m manifest.json
+

The CLI will verify the Coordinator via remote attestation using the reference values from a given manifest. This manifest needs +to be communicated out of band to everyone wanting to verify the deployment, as the verify command checks +if the currently active manifest at the Coordinator matches the manifest given to the CLI. If the command succeeds, +the Coordinator deployment was successfully verified to be running in the expected Confidential +Computing environment with the expected code version. The Coordinator will then return its +configuration over the established TLS channel. The CLI will store this information, namely the root +certificate of the mesh (mesh-ca.pem) and the history of manifests, into the verify/ directory. +In addition, the policies referenced in the manifest history are also written into the same directory.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Auditing the manifest history and artifacts

+

In the next step, the Coordinator configuration that was written by the verify command needs to be audited. +A potential voter should inspect the manifest and the referenced policies. They could delegate +this task to an entity they trust.

+

Connecting securely to the application

+

After ensuring the configuration of the Coordinator fits the expectation, the user can securely connect +to the application using the Coordinator's mesh-ca.pem as a trusted CA certificate.

+

To access the web frontend, expose the service on a public IP address via a LoadBalancer service:

+
frontendIP=$(kubectl get svc web-svc -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "Frontend is available at https://$frontendIP, you can visit it in your browser."
+

Using openssl, the certificate of the service can be validated with the mesh-ca.pem:

+
openssl s_client -CAfile verify/mesh-ca.pem -verify_return_error -connect ${frontendIP}:443 < /dev/null
+

Updating the certificate SAN and the manifest (optional)

+

By default, mesh certificates are issued with a wildcard DNS entry. The web frontend is accessed +via load balancer IP in this demo. Tools like curl check the certificate for IP entries in the subject alternative name (SAN) field. +Validation fails since the certificate contains no IP entries as a SAN. +For example, a connection attempt using the curl and the mesh CA certificate with throw the following error:

+
$ curl --cacert ./verify/mesh-ca.pem "https://${frontendIP}:443"
curl: (60) SSL: no alternative certificate subject name matches target host name '203.0.113.34'
+

Configuring the service SAN in the manifest

+

The Policies section of the manifest maps policy hashes to a list of SANs. To enable certificate verification +of the web frontend with tools like curl, edit the policy with your favorite editor and add the frontendIP to +the list that already contains the "web" DNS entry:

+
   "Policies": {
...
"99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b": {
"SANs": [
"web",
- "*"
+ "*",
+ "203.0.113.34"
],
"WorkloadSecretID": "web"
},
+

Updating the manifest

+

Next, set the changed manifest at the coordinator with:

+
contrast set -c "${coordinator}:1313" deployment/
+

The Contrast Coordinator will rotate the mesh ca certificate on the manifest update. Workload certificates issued +after the manifest update are thus issued by another certificate authority and services receiving the new CA certificate chain +won't trust parts of the deployment that got their certificate issued before the update. This way, Contrast ensures +that parts of the deployment that received a security update won't be infected by parts of the deployment at an older +patch level that may have been compromised. The mesh-ca.pem is updated with the new CA certificate chain.

+
warning

On bare metal, the coordinator policy hash must be overwritten using --coordinator-policy-hash.

+

Rolling out the update

+

The Coordinator has the new manifest set, but the different containers of the app are still +using the older certificate authority. The Contrast Initializer terminates after the initial attestation +flow and won't pull new certificates on manifest updates.

+

To roll out the update, use:

+
kubectl rollout restart deployment/emoji
kubectl rollout restart deployment/vote-bot
kubectl rollout restart deployment/voting
kubectl rollout restart deployment/web
+

After the update has been rolled out, connecting to the frontend using curl will successfully validate +the service certificate and return the HTML document of the voting site:

+
curl --cacert ./mesh-ca.pem "https://${frontendIP}:443"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/features-limitations.html b/pr-preview/pr-976/next/features-limitations.html new file mode 100644 index 0000000000..e62347b68c --- /dev/null +++ b/pr-preview/pr-976/next/features-limitations.html @@ -0,0 +1,51 @@ + + + + + +Planned features and limitations | Contrast + + + + + + + + + + + + + +
Version: Next

Planned features and limitations

+

This section lists planned features and current limitations of Contrast.

+

Availability

+
    +
  • Platform support: At present, Contrast is exclusively available on Azure AKS, supported by the Confidential Container preview for AKS. Expansion to other cloud platforms is planned, pending the availability of necessary infrastructure enhancements.
  • +
  • Bare-metal support: Support for running Contrast on bare-metal Kubernetes is available for AMD SEV-SNP and Intel TDX.
  • +
+

Kubernetes features

+
    +
  • Persistent volumes: Contrast only supports volumes with volumeMode: Block. These block devices are provided by the untrusted environment and should be treated accordingly. We plan to provide transparent encryption on top of block devices in a future release.
  • +
  • Port forwarding: This feature isn't yet supported by Kata Containers. You can deploy a port-forwarder as a workaround.
  • +
  • Resource limits: There is an existing bug on AKS where container memory limits are incorrectly applied. The current workaround involves using only memory requests instead of limits.
  • +
+

Runtime policies

+
    +
  • Coverage: While the enforcement of workload policies generally functions well, there are scenarios not yet fully covered. It's crucial to review deployments specifically for these edge cases.
  • +
  • Order of events: The current policy evaluation mechanism on API requests isn't stateful, so it can't ensure a prescribed order of events. Consequently, there's no guaranteed enforcement that the service mesh sidecar container runs before the workload container. This order ensures that all traffic between pods is securely encapsulated within TLS connections.
  • +
  • Absence of events: Policies can't ensure certain events have happened. A container, such as the service mesh sidecar, can be omitted entirely. Environment variables may be missing.
  • +
  • Volume integrity checks: Integrity checks don't cover any volume mounts, such as ConfigMaps and Secrets.
  • +
+
warning

The policy limitations, in particular the missing guarantee that our service mesh sidecar has been started before the workload container, affect the service mesh implementation of Contrast. +Currently, this requires inspecting the iptables rules on startup or terminating TLS connections in the workload directly.

+

Tooling integration

+
    +
  • CLI availability: The CLI tool is currently only available for Linux. This limitation arises because certain upstream dependencies haven't yet been ported to other platforms.
  • +
+

Automatic recovery and high availability

+

The Contrast Coordinator is a singleton and can't be scaled to more than one instance. +When this instance's pod is restarted, for example for node maintenance, it needs to be recovered manually. +In a future release, we plan to support distributed Coordinator instances that can recover automatically.

+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/getting-started/bare-metal.html b/pr-preview/pr-976/next/getting-started/bare-metal.html new file mode 100644 index 0000000000..eac177e21a --- /dev/null +++ b/pr-preview/pr-976/next/getting-started/bare-metal.html @@ -0,0 +1,36 @@ + + + + + +Prepare a bare-metal instance | Contrast + + + + + + + + + + + + + +
Version: Next

Prepare a bare-metal instance

+

Hardware and firmware setup

+
    +
  1. Update your BIOS to a version that supports AMD SEV-SNP. Updating to the latest available version is recommended as newer versions will likely contain security patches for AMD SEV-SNP.
  2. +
  3. Enter BIOS setup to enable SMEE, IOMMU, RMP coverage, and SEV-SNP. Set the SEV-ES ASID Space Limit to a non-zero number (higher is better).
  4. +
  5. Download the latest firmware version for your processor from AMD, unpack it, and place it in /lib/firmware/amd.
  6. +

Consult AMD's Using SEV with AMD EPYC Processors user guide for more information.

+

Kernel Setup

+

Install a kernel with version 6.11 or greater. If you're following this guide before 6.11 has been released, use 6.11-rc3. Don't use 6.11-rc4 - 6.11-rc6 as they contain a regression. 6.11-rc7+ might work.

+

Increase the user.max_inotify_instances sysctl limit by adding user.max_inotify_instances=8192 to /etc/sysctl.d/99-sysctl.conf and running sysctl --system.

+

K3s Setup

+
    +
  1. Follow the K3s setup instructions to create a cluster.
  2. +
  3. Install a block storage provider such as Longhorn and mark it as the default storage class.
  4. +
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/getting-started/cluster-setup.html b/pr-preview/pr-976/next/getting-started/cluster-setup.html new file mode 100644 index 0000000000..d97a8d7c5e --- /dev/null +++ b/pr-preview/pr-976/next/getting-started/cluster-setup.html @@ -0,0 +1,64 @@ + + + + + +Create a cluster | Contrast + + + + + + + + + + + + + +
Version: Next

Create a cluster

+

Prerequisites

+
    +
  • Install version 2.44.1 or newer of the Azure CLI. Note that your package manager will likely install an outdated version.
  • +
  • Install a recent version of kubectl.
  • +
+

Prepare using the AKS preview

+

First, log in to your Azure subscription:

+
az login
+

CoCo on AKS is currently in preview. An extension for the az CLI is needed to create such a cluster. +Add the extension with the following commands:

+
az extension add \
--name aks-preview \
--allow-preview true
az extension update \
--name aks-preview \
--allow-preview true
+

Then register the required feature flags in your subscription to allow access to the public preview:

+
az feature register \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview"
+

The registration can take a few minutes. The status of the operation can be checked with the following +command, which should show the registration state as Registered:

+
az feature show \
--namespace "Microsoft.ContainerService" \
--name "KataCcIsolationPreview" \
--output table
+

Afterward, refresh the registration of the ContainerService provider:

+
az provider register \
--namespace "Microsoft.ContainerService"
+

Create resource group

+

The AKS with CoCo preview is currently available in the following locations:

+
CentralIndia
eastus
EastUS2EUAP
GermanyWestCentral
japaneast
northeurope
SwitzerlandNorth
UAENorth
westeurope
westus
+

Set the name of the resource group you want to use:

+
azResourceGroup="ContrastDemo"
+

You can either use an existing one or create a new resource group with the following command:

+
azLocation="westus" # Select a location from the list above

az group create \
--name "${azResourceGroup:?}" \
--location "${azLocation:?}"
+

Create AKS cluster

+

First, create a CoCo enabled AKS cluster with:

+
# Select the name for your AKS cluster
azClusterName="ContrastDemo"

az aks create \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}" \
--kubernetes-version 1.30 \
--os-sku AzureLinux \
--node-vm-size Standard_DC4as_cc_v5 \
--workload-runtime KataCcIsolation \
--node-count 1 \
--generate-ssh-keys
+

Finally, update your kubeconfig with the credentials to access the cluster:

+
az aks get-credentials \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+

For validation, list the available nodes using kubectl:

+
kubectl get nodes
+

It should show a single node:

+
NAME                                STATUS   ROLES    AGE     VERSION
aks-nodepool1-32049705-vmss000000 Ready <none> 9m47s v1.29.0
+

🥳 Congratulations. You're now ready to set up your first application with Contrast. Follow this example to learn how.

+

Cleanup

+

After trying out Contrast, you might want to clean up the cloud resources created in this step. +In case you've created a new resource group, you can just delete that group with

+
az group delete \
--name "${azResourceGroup:?}"
+

Deleting the resource group will also delete the cluster and all other related resources.

+

To only cleanup the AKS cluster and node pools, run

+
az aks delete \
--resource-group "${azResourceGroup:?}" \
--name "${azClusterName:?}"
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/getting-started/install.html b/pr-preview/pr-976/next/getting-started/install.html new file mode 100644 index 0000000000..550a9934f7 --- /dev/null +++ b/pr-preview/pr-976/next/getting-started/install.html @@ -0,0 +1,26 @@ + + + + + +Installation | Contrast + + + + + + + + + + + + + +
Version: Next

Installation

+

Download the Contrast CLI from the latest release:

+
curl --proto '=https' --tlsv1.2 -fLo contrast https://github.com/edgelesssys/contrast/releases/latest/download/contrast
+

After that, install the Contrast CLI in your PATH, e.g.:

+
sudo install contrast /usr/local/bin/contrast
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/next/troubleshooting.html b/pr-preview/pr-976/next/troubleshooting.html new file mode 100644 index 0000000000..a7e036a829 --- /dev/null +++ b/pr-preview/pr-976/next/troubleshooting.html @@ -0,0 +1,100 @@ + + + + + +Troubleshooting | Contrast + + + + + + + + + + + + + +
Version: Next

Troubleshooting

+

This section contains information on how to debug your Contrast deployment.

+

Logging

+

Collecting logs can be a good first step to identify problems in your +deployment. Both the CLI and the Contrast Coordinator as well as the Initializer +can be configured to emit additional logs.

+

CLI

+

The CLI logs can be configured with the --log-level command-line flag, which +can be set to either debug, info, warn or error. The default is info. +Setting this to debug can get more fine-grained information as to where the +problem lies.

+

Coordinator and Initializer

+

The logs from the Coordinator and the Initializer can be configured via the +environment variables CONTRAST_LOG_LEVEL, CONTRAST_LOG_FORMAT and +CONTRAST_LOG_SUBSYSTEMS.

+
    +
  • CONTRAST_LOG_LEVEL can be set to one of either debug, info, warn, or +error, similar to the CLI (defaults to info).
  • +
  • CONTRAST_LOG_FORMAT can be set to text or json, determining the output +format (defaults to text).
  • +
  • CONTRAST_LOG_SUBSYSTEMS is a comma-separated list of subsystems that should +be enabled for logging, which are disabled by default. Subsystems include: +kds-getter, issuer and validator. +To enable all subsystems, use * as the value for this environment variable. +Warnings and error messages from subsystems get printed regardless of whether +the subsystem is listed in the CONTRAST_LOG_SUBSYSTEMS environment variable.
  • +
+

To configure debug logging with all subsystems for your Coordinator, add the +following variables to your container definition.

+
spec: # v1.PodSpec
containers:
image: "ghcr.io/edgelesssys/contrast/coordinator:latest"
name: coordinator
env:
- name: CONTRAST_LOG_LEVEL
value: debug
- name: CONTRAST_LOG_SUBSYSTEMS
value: "*"
# ...
+
info

While the Contrast Coordinator has a policy that allows certain configurations, +the Initializer and service mesh don't. When changing environment variables of other +parts than the Coordinator, ensure to rerun contrast generate to update the policy.

+

To access the logs generated by the Coordinator, you can use kubectl with the +following command:

+
kubectl logs <coordinator-pod-name>
+

Pod fails to start

+

If the Coordinator or a workload pod fails to even start, it can be helpful to +look at the events of the pod during the startup process using the describe +command.

+
kubectl -n <namespace> events --for pod/<coordinator-pod-name>
+

Example output:

+
LAST SEEN  TYPE     REASON  OBJECT             MESSAGE
32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...
+

A common error, as in this example, is that the container creation was blocked by the +policy. Potential reasons are a modification of the deployment YAML without updating +the policies afterward, or a version mismatch between Contrast components.

+

Regenerating the policies

+

To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated +policies, rerun

+
contrast generate
+

on your deployment. If any of the policy annotations change, re-deploy with the updated policies.

+

Pin container images

+

When generating the policies, Contrast will download the images specified in your deployment +YAML and include their cryptographic identity. If the image tag is moved to another +container image after the policy has been generated, the image downloaded at deploy time +will differ from the one at generation time, and the policy enforcement won't allow the +container to be started in the pod VM.

+

To ensure the correct image is always used, pin the container image to a fixed sha256:

+
image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac
+

This way, the same image will still be pulled when the container tag (22.04) is moved +to another image.

+

Validate Contrast components match

+

A version mismatch between Contrast components can cause policy validation or attestation +to fail. Each Contrast runtime is identifiable based on its (shortened) measurement value +used to name the runtime class version.

+

First, analyze which runtime class is currently installed in your cluster by running

+
kubectl get runtimeclasses
+

This should give you output similar to the following one.

+
NAME                                           HANDLER                                        AGE
contrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h
kata-cc-isolation kata-cc 45d
+

The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided +by the AKS CoCo preview, which isn't used by Contrast).

+

Next, check if the pod that won't start has the correct runtime class configured, and the +Coordinator uses the exact same runtime:

+
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>
+

The output should list the runtime class the pod is using:

+
contrast-cc-aks-clh-snp-7173acb5
+

Version information about the currently used CLI can be obtained via the version flag:

+
contrast --version
+
contrast version v0.X.0

runtime handler: contrast-cc-aks-clh-snp-7173acb5
launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35
genpolicy version: 3.2.0.azl1.genpolicy0
image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...
ghcr.io/edgelesssys/contrast/initializer@sha256:...
+ + \ No newline at end of file diff --git a/pr-preview/pr-976/search-index-docs-default-0.5.json b/pr-preview/pr-976/search-index-docs-default-0.5.json new file mode 100644 index 0000000000..79d91494da --- /dev/null +++ b/pr-preview/pr-976/search-index-docs-default-0.5.json @@ -0,0 +1 @@ +{"documents":[{"id":133,"pageTitle":"Contrast","sectionTitle":"Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.5","type":"docs"},{"id":134,"pageTitle":"Contrast","sectionTitle":"Goal","sectionRoute":"/contrast/pr-preview/pr-976/0.5#goal","type":"docs"},{"id":135,"pageTitle":"Contrast","sectionTitle":"Use Cases","sectionRoute":"/contrast/pr-preview/pr-976/0.5#use-cases","type":"docs"},{"id":136,"pageTitle":"Contrast","sectionTitle":"Next steps","sectionRoute":"/contrast/pr-preview/pr-976/0.5#next-steps","type":"docs"},{"id":137,"pageTitle":"Architecture","sectionTitle":"Architecture","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":138,"pageTitle":"Architecture","sectionTitle":"🗃️ Components","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":139,"pageTitle":"Architecture","sectionTitle":"📄️ Confidential Containers","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":140,"pageTitle":"Architecture","sectionTitle":"🗃️ Attestation","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":141,"pageTitle":"Architecture","sectionTitle":"🗃️ Certificates and Identities","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":142,"pageTitle":"Architecture","sectionTitle":"🗃️ Network Encryption","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture","type":"docs"},{"id":143,"pageTitle":"coordinator","sectionTitle":"coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinator","type":"docs"},{"id":144,"pageTitle":"hardware","sectionTitle":"hardware","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardware","type":"docs"},{"id":145,"pageTitle":"manifest","sectionTitle":"manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifest","type":"docs"},{"id":146,"pageTitle":"pod-vm","sectionTitle":"pod-vm","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vm","type":"docs"},{"id":147,"pageTitle":"runtime-policies","sectionTitle":"runtime-policies","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policies","type":"docs"},{"id":148,"pageTitle":"pki","sectionTitle":"pki","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pki","type":"docs"},{"id":149,"pageTitle":"cli","sectionTitle":"cli","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/components/cli","type":"docs"},{"id":150,"pageTitle":"coordinator","sectionTitle":"coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/components/coordinator","type":"docs"},{"id":151,"pageTitle":"init-container","sectionTitle":"init-container","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/components/init-container","type":"docs"},{"id":152,"pageTitle":"confidential-containers","sectionTitle":"confidential-containers","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/confidential-containers","type":"docs"},{"id":16,"pageTitle":"protocols-and-keys","sectionTitle":"protocols-and-keys","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keys","type":"docs"},{"id":153,"pageTitle":"sidecar","sectionTitle":"sidecar","sectionRoute":"/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecar","type":"docs"},{"id":17,"pageTitle":"Confidential Containers","sectionTitle":"Confidential Containers","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers","type":"docs"},{"id":18,"pageTitle":"Confidential Containers","sectionTitle":"Kubernetes RuntimeClass","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers#kubernetes-runtimeclass","type":"docs"},{"id":19,"pageTitle":"Confidential Containers","sectionTitle":"Kata Containers","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers#kata-containers","type":"docs"},{"id":20,"pageTitle":"Confidential Containers","sectionTitle":"AKS CoCo Preview","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/confidential-containers#aks-coco-preview","type":"docs"},{"id":21,"pageTitle":"Product Features","sectionTitle":"Product Features","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/features","type":"docs"},{"id":22,"pageTitle":"security-benefits","sectionTitle":"security-benefits","sectionRoute":"/contrast/pr-preview/pr-976/0.5/basics/security-benefits","type":"docs"},{"id":23,"pageTitle":"","sectionTitle":"📄️ Hardware","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/attestation","type":"docs"},{"id":24,"pageTitle":"","sectionTitle":"📄️ Pod VM","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/attestation","type":"docs"},{"id":25,"pageTitle":"","sectionTitle":"📄️ Runtime policies","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/attestation","type":"docs"},{"id":26,"pageTitle":"","sectionTitle":"📄️ Manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/attestation","type":"docs"},{"id":27,"pageTitle":"","sectionTitle":"📄️ Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/attestation","type":"docs"},{"id":31,"pageTitle":"","sectionTitle":"📄️ PKI","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/certificates-and-identities","type":"docs"},{"id":28,"pageTitle":"","sectionTitle":"📄️ Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/components","type":"docs"},{"id":29,"pageTitle":"","sectionTitle":"📄️ Init container","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/components","type":"docs"},{"id":30,"pageTitle":"","sectionTitle":"📄️ CLI","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/components","type":"docs"},{"id":32,"pageTitle":"","sectionTitle":"📄️ Sidecar","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/network-encryption","type":"docs"},{"id":33,"pageTitle":"","sectionTitle":"📄️ Protocols and Keys","sectionRoute":"/contrast/pr-preview/pr-976/0.5/category/network-encryption","type":"docs"},{"id":34,"pageTitle":"Workload deployment","sectionTitle":"Workload deployment","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment","type":"docs"},{"id":35,"pageTitle":"Workload deployment","sectionTitle":"Deploy the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#deploy-the-contrast-coordinator","type":"docs"},{"id":36,"pageTitle":"Workload deployment","sectionTitle":"Prepare your Kubernetes resources","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#prepare-your-kubernetes-resources","type":"docs"},{"id":37,"pageTitle":"Workload deployment","sectionTitle":"Generate policy annotations and manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#generate-policy-annotations-and-manifest","type":"docs"},{"id":38,"pageTitle":"Workload deployment","sectionTitle":"Apply the resources","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#apply-the-resources","type":"docs"},{"id":39,"pageTitle":"Workload deployment","sectionTitle":"Connect to the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#connect-to-the-contrast-coordinator","type":"docs"},{"id":40,"pageTitle":"Workload deployment","sectionTitle":"Set the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#set-the-manifest","type":"docs"},{"id":41,"pageTitle":"Workload deployment","sectionTitle":"Verify the Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#verify-the-coordinator","type":"docs"},{"id":42,"pageTitle":"Workload deployment","sectionTitle":"Communicate with workloads","sectionRoute":"/contrast/pr-preview/pr-976/0.5/deployment#communicate-with-workloads","type":"docs"},{"id":43,"pageTitle":"Examples","sectionTitle":"Examples","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples","type":"docs"},{"id":44,"pageTitle":"Examples","sectionTitle":"📄️ Confidential emoji voting","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples","type":"docs"},{"id":45,"pageTitle":"Confidential emoji voting","sectionTitle":"Confidential emoji voting","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto","type":"docs"},{"id":46,"pageTitle":"Confidential emoji voting","sectionTitle":"Motivation","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#motivation","type":"docs"},{"id":47,"pageTitle":"Confidential emoji voting","sectionTitle":"Prerequisites","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#prerequisites","type":"docs"},{"id":48,"pageTitle":"Confidential emoji voting","sectionTitle":"Steps to deploy emojivoto with Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#steps-to-deploy-emojivoto-with-contrast","type":"docs"},{"id":49,"pageTitle":"Confidential emoji voting","sectionTitle":"Deploy the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#deploy-the-contrast-coordinator","type":"docs"},{"id":50,"pageTitle":"Confidential emoji voting","sectionTitle":"Generate policy annotations and manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#generate-policy-annotations-and-manifest","type":"docs"},{"id":51,"pageTitle":"Confidential emoji voting","sectionTitle":"Set the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#set-the-manifest","type":"docs"},{"id":52,"pageTitle":"Confidential emoji voting","sectionTitle":"Deploy emojivoto","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#deploy-emojivoto","type":"docs"},{"id":53,"pageTitle":"Confidential emoji voting","sectionTitle":"Voter's perspective: Verifying the ballot","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#voters-perspective-verifying-the-ballot","type":"docs"},{"id":54,"pageTitle":"Confidential emoji voting","sectionTitle":"Attest the Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#attest-the-coordinator","type":"docs"},{"id":55,"pageTitle":"Confidential emoji voting","sectionTitle":"Manifest history and artifact audit","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#manifest-history-and-artifact-audit","type":"docs"},{"id":56,"pageTitle":"Confidential emoji voting","sectionTitle":"Confidential connection to the attested workload","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#confidential-connection-to-the-attested-workload","type":"docs"},{"id":57,"pageTitle":"Confidential emoji voting","sectionTitle":"Certificate SAN and manifest update (optional)","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#certificate-san-and-manifest-update-optional","type":"docs"},{"id":58,"pageTitle":"Confidential emoji voting","sectionTitle":"Configure the service SAN in the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#configure-the-service-san-in-the-manifest","type":"docs"},{"id":59,"pageTitle":"Confidential emoji voting","sectionTitle":"Update the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#update-the-manifest","type":"docs"},{"id":60,"pageTitle":"Confidential emoji voting","sectionTitle":"Rolling out the update","sectionRoute":"/contrast/pr-preview/pr-976/0.5/examples/emojivoto#rolling-out-the-update","type":"docs"},{"id":61,"pageTitle":"Getting started","sectionTitle":"Getting started","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started","type":"docs"},{"id":62,"pageTitle":"Getting started","sectionTitle":"📄️ Install","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started","type":"docs"},{"id":63,"pageTitle":"Getting started","sectionTitle":"📄️ Cluster setup","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started","type":"docs"},{"id":64,"pageTitle":"Getting started","sectionTitle":"📄️ First steps","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started","type":"docs"},{"id":154,"pageTitle":"Create a cluster","sectionTitle":"Create a cluster","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup","type":"docs"},{"id":155,"pageTitle":"Create a cluster","sectionTitle":"Prerequisites","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup#prerequisites","type":"docs"},{"id":156,"pageTitle":"Create a cluster","sectionTitle":"Prepare using the AKS preview","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup#prepare-using-the-aks-preview","type":"docs"},{"id":157,"pageTitle":"Create a cluster","sectionTitle":"Create resource group","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup#create-resource-group","type":"docs"},{"id":158,"pageTitle":"Create a cluster","sectionTitle":"Create AKS cluster","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup#create-aks-cluster","type":"docs"},{"id":159,"pageTitle":"Create a cluster","sectionTitle":"Cleanup","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setup#cleanup","type":"docs"},{"id":160,"pageTitle":"first-steps","sectionTitle":"first-steps","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/first-steps","type":"docs"},{"id":161,"pageTitle":"Installation","sectionTitle":"Installation","sectionRoute":"/contrast/pr-preview/pr-976/0.5/getting-started/install","type":"docs"}],"index":{"version":"2.3.9","fields":["title","content","tags"],"fieldVectors":[["title/133",[0,1.237]],["content/133",[0,1.401,1,2.927,2,2.549,3,1.564,4,1.845,5,1.721,6,0.864,7,2.038,8,2.301,9,3.446,10,1.738,11,2.549,12,1.202,13,2.115,14,2.927,15,2.927,16,1.423,17,1.564,18,2.927,19,1.646,20,2.115,21,2.927,22,2.115,23,2.927,24,2.927,25,2.927,26,2.927,27,2.927,28,2.115,29,2.301,30,1.564,31,1.646,32,1.423,33,2.927,34,2.301,35,2.927,36,2.115,37,2.549,38,1.738]],["tags/133",[]],["title/134",[39,5.154]],["content/134",[0,1.027,6,0.837,7,1.99,9,2.229,17,1.515,38,1.684,40,2.229,41,2.469,42,1.905,43,2.834,44,2.229,45,2.834,46,2.541,47,4.052,48,2.834,49,2.834,50,1.905,51,2.834,52,2.229,53,2.834,54,2.834,55,4.278,56,1.905,57,2.834,58,1.078,59,2.469,60,2.834,61,2.834,62,2.049,63,1.786,64,2.834,65,2.834,66,2.834,67,2.834,68,2.469,69,2.834,70,2.049,71,2.834,72,2.469,73,2.469,74,2.049,75,1.443,76,2.469,77,1.905,78,2.229,79,2.834,80,2.469,81,2.469,82,2.469]],["tags/134",[]],["title/135",[83,1.374,84,3.024]],["content/135",[0,0.839,4,1.032,5,0.963,17,1.867,38,2.964,42,3.354,56,2.349,58,1.329,59,3.044,83,1.147,84,2.526,85,3.495,86,2.806,87,2.202,88,2.526,89,3.044,90,4.99,91,3.495,92,3.044,93,1.436,94,3.495,95,2.748,96,3.044,97,3.495,98,3.495,99,3.495,100,2.748,101,3.044,102,3.495,103,3.495,104,3.495,105,3.044,106,3.495]],["tags/135",[]],["title/136",[107,3.024,108,2.034]],["content/136",[0,1.152,4,1.418,5,1.323,36,3.47,86,2.699,87,3.024,88,3.47,109,4.8,110,4.181,111,4.181,112,4.8,113,4.8,114,4.8,115,4.8,116,4.181,117,3.47]],["tags/136",[]],["title/137",[118,4.052]],["content/137",[4,1.302,5,1.215,44,3.466,77,2.963,119,1.098,120,3.466,121,3.84,122,4.71,123,1.811,124,3.84,125,1.741,126,3.466,127,3.466,128,3.466]],["tags/137",[]],["title/138",[119,0.63,120,3.29]],["content/138",[121,5.567,122,4.296]],["tags/138",[]],["title/139",[4,1.04,5,0.97,119,0.53]],["content/139",[]],["tags/139",[]],["title/140",[119,0.63,123,1.719]],["content/140",[122,4.296,124,5.567]],["tags/140",[]],["title/141",[119,0.53,125,1.391,126,2.769]],["content/141",[122,4.296,127,5.025]],["tags/141",[]],["title/142",[44,2.769,119,0.53,128,2.769]],["content/142",[77,4.296,122,4.296]],["tags/142",[]],["title/143",[129,1.155]],["content/143",[]],["tags/143",[]],["title/144",[19,2.898]],["content/144",[]],["tags/144",[]],["title/145",[130,1.42]],["content/145",[]],["tags/145",[]],["title/146",[12,1.719,16,2.034]],["content/146",[]],["tags/146",[]],["title/147",[131,1.865,132,1.653]],["content/147",[]],["tags/147",[]],["title/148",[133,3.725]],["content/148",[]],["tags/148",[]],["title/149",[134,2.397]],["content/149",[]],["tags/149",[]],["title/150",[129,1.155]],["content/150",[]],["tags/150",[]],["title/151",[5,1.153,135,2.485]],["content/151",[]],["tags/151",[]],["title/152",[4,1.236,5,1.153]],["content/152",[]],["tags/152",[]],["title/16",[136,3.024,137,2.485]],["content/16",[]],["tags/16",[]],["title/153",[138,3.725]],["content/153",[]],["tags/153",[]],["title/17",[4,1.236,5,1.153]],["content/17",[0,1.209,4,1.488,5,0.976,7,1.647,11,4.387,12,1.455,17,1.892,30,2.691,36,2.559,38,2.103,83,1.654,87,2.231,89,3.084,131,1.578,139,3.084,140,3.084,141,3.541,142,3.541,143,3.541,144,3.541,145,4.387,146,3.541,147,3.541,148,3.541,149,3.541,150,3.541,151,3.084,152,3.541,153,3.541,154,3.541]],["tags/17",[]],["title/18",[7,1.946,155,3.645]],["content/18",[4,0.969,5,1.548,7,1.527,9,2.581,10,1.95,12,1.349,36,2.373,38,1.95,63,2.068,74,2.373,83,1.078,84,2.373,131,2.748,155,4.894,156,3.282,157,2.859,158,3.282,159,2.859,160,2.859,161,4.77,162,3.282,163,3.282,164,2.581,165,2.859,166,3.282,167,3.282,168,2.859,169,2.581,170,3.282,171,3.282,172,3.282,173,3.282,174,2.581,175,2.859]],["tags/18",[]],["title/19",[5,1.153,10,2.485]],["content/19",[3,2.079,4,0.9,5,1.244,7,1.417,10,2.311,12,1.855,16,2.999,17,0.986,20,1.334,40,1.451,47,1.451,52,1.451,56,2.048,62,1.334,72,1.608,74,1.334,83,0.606,95,1.451,123,0.758,128,1.451,131,1.358,132,1.537,164,2.396,165,1.608,168,1.608,176,3.891,177,1.846,178,4.516,179,1.451,180,1.846,181,1.038,182,3.93,183,1.608,184,1.608,185,1.358,186,3.389,187,1.334,188,2.396,189,1.334,190,1.846,191,1.846,192,1.846,193,1.241,194,1.608,195,2.654,196,2.202,197,1.608,198,1.846,199,1.846,200,1.846,201,1.451,202,1.608,203,1.608,204,1.846,205,0.897,206,1.846,207,1.846,208,1.451,209,3.047,210,1.451,211,1.608,212,1.846,213,0.859,214,1.451,215,1.608]],["tags/19",[]],["title/20",[30,1.882,31,1.98,32,1.712]],["content/20",[0,0.885,6,1.089,7,1.714,16,2.519,17,1.969,30,3.202,31,2.073,32,2.519,58,1.401,75,1.876,100,2.898,175,3.211,187,3.745,194,3.211,195,3.211,202,3.211,216,4.074,217,1.792,218,3.745,219,4.074,220,3.686,221,3.211,222,3.686,223,3.686,224,3.686]],["tags/20",[]],["title/21",[87,2.636,225,4.184]],["content/21",[0,1.204,4,0.945,5,1.047,6,1.265,7,1.993,8,1.11,12,0.58,17,1.298,22,1.02,32,0.686,40,1.11,42,0.949,47,1.91,56,0.949,58,0.924,68,2.787,70,2.312,73,2.117,74,2.312,75,0.719,76,1.23,77,0.949,78,1.91,80,1.23,83,0.463,86,2.409,87,0.889,88,1.02,93,0.998,95,1.11,100,1.11,101,1.23,105,1.23,110,1.23,118,1.11,120,1.11,123,0.998,125,0.558,126,1.11,133,1.02,137,1.443,169,1.11,174,1.11,188,1.11,193,0.949,196,1.02,203,1.23,205,0.686,216,1.11,217,1.181,218,1.02,226,1.412,227,1.412,228,1.91,229,1.412,230,1.412,231,1.412,232,1.412,233,1.412,234,0.838,235,0.889,236,0.949,237,1.23,238,1.412,239,1.412,240,1.412,241,1.412,242,1.412,243,1.412,244,1.412,245,2.43,246,0.949,247,1.23,248,1.412,249,1.11,250,1.23,251,1.23,252,1.23,253,1.412,254,1.412,255,2.117,256,0.838,257,1.412,258,1.412,259,0.838,260,1.412,261,1.23,262,1.412,263,1.412,264,1.756,265,0.794,266,1.412,267,1.23,268,1.412,269,0.794,270,0.754,271,0.949,272,0.838,273,1.23,274,1.23,275,1.412,276,1.412,277,0.949,278,1.23,279,0.754,280,1.23,281,1.412,282,1.412,283,1.412]],["tags/21",[]],["title/22",[86,2.353,88,3.024]],["content/22",[]],["tags/22",[]],["title/23",[19,2.353,119,0.63]],["content/23",[12,2.123,16,2.512,19,2.906,119,1.154,129,1.158,130,1.424,131,2.303,132,2.042]],["tags/23",[]],["title/24",[12,1.447,16,1.712,119,0.53]],["content/24",[12,2.123,16,2.512,19,2.906,119,1.154,129,1.158,130,1.424,131,2.303,132,2.042]],["tags/24",[]],["title/25",[119,0.53,131,1.569,132,1.391]],["content/25",[12,2.123,16,2.512,19,2.906,119,1.154,129,1.158,130,1.424,131,2.303,132,2.042]],["tags/25",[]],["title/26",[119,0.63,130,1.153]],["content/26",[12,2.123,16,2.512,19,2.906,119,1.154,129,1.158,130,1.424,131,2.303,132,2.042]],["tags/26",[]],["title/27",[119,0.63,129,0.937]],["content/27",[12,2.123,16,2.512,19,2.906,119,1.154,129,1.158,130,1.424,131,2.303,132,2.042]],["tags/27",[]],["title/31",[119,0.63,133,3.024]],["content/31",[119,0.962,133,4.619]],["tags/31",[]],["title/28",[119,0.63,129,0.937]],["content/28",[5,1.575,119,1.117,129,1.28,134,2.658,135,3.394]],["tags/28",[]],["title/29",[5,0.97,119,0.53,135,2.092]],["content/29",[5,1.575,119,1.117,129,1.28,134,2.658,135,3.394]],["tags/29",[]],["title/30",[119,0.63,134,1.946]],["content/30",[5,1.575,119,1.117,129,1.28,134,2.658,135,3.394]],["tags/30",[]],["title/32",[119,0.63,138,3.024]],["content/32",[119,1.067,136,4.313,137,3.544,138,4.313]],["tags/32",[]],["title/33",[119,0.53,136,2.545,137,2.092]],["content/33",[119,1.067,136,4.313,137,3.544,138,4.313]],["tags/33",[]],["title/34",[6,1.236,93,1.719]],["content/34",[0,1.009,3,2.245,4,1.241,6,1.675,7,1.954,30,2.245,34,3.304,58,1.598,62,3.037,70,3.037,108,2.043,179,3.304,189,3.037,218,3.037,234,2.496,246,2.825,284,3.661,285,4.941,286,4.202,287,4.202,288,2.139,289,3.304]],["tags/34",[]],["title/35",[0,0.845,6,1.04,129,0.789]],["content/35",[0,1.152,6,1.418,58,1.825,75,2.444,129,1.075,217,2.333,290,3.774,291,3.774,292,4.181,293,3.774,294,4.181,295,3.227,296,2.699,297,3.227,298,3.47,299,4.8]],["tags/35",[]],["title/36",[7,1.638,213,1.638,300,3.068]],["content/36",[0,0.732,4,0.545,5,0.509,6,0.9,7,0.859,10,1.81,12,1.598,20,2.202,41,1.608,83,0.606,93,1.598,119,0.68,125,0.729,129,0.414,139,1.608,186,1.608,201,1.451,205,0.897,211,1.608,213,1.81,214,1.451,235,1.92,236,1.241,249,1.451,250,3.389,251,1.608,252,3.389,256,1.096,277,3.036,301,2.451,302,1.241,303,3.551,304,1.334,305,1.846,306,3.047,307,1.846,308,1.451,309,3.047,310,3.047,311,3.047,312,3.047,313,1.846,314,1.846,315,1.846,316,1.846,317,1.846,318,1.846,319,3.047,320,2.654,321,2.654,322,3.047,323,1.334,324,2.654,325,2.811,326,3.389,327,1.846,328,1.846,329,1.846,330,1.846,331,1.163,332,1.846,333,1.846,334,1.846,335,1.846]],["tags/36",[]],["title/37",[130,0.838,132,1.201,256,1.806,302,2.044]],["content/37",[0,1.113,3,2.477,6,1.788,13,3.35,132,1.831,181,2.607,185,2.066,213,2.156,256,4.004,301,2.92,302,3.116,303,3.644,331,2.92,336,4.038,337,3.116]],["tags/37",[]],["title/38",[213,1.946,297,2.813]],["content/38",[58,1.858,93,2.008,129,1.095,130,1.347,140,4.257,213,2.913,235,3.079,288,2.488,296,2.748,297,4.211,298,3.532,338,4.887,339,4.257]],["tags/38",[]],["title/39",[0,0.845,129,0.789,279,1.882]],["content/39",[4,0.812,5,1.152,6,0.812,10,1.632,12,1.129,30,1.468,46,1.632,52,2.16,83,1.66,107,1.986,108,1.336,129,1.133,131,1.225,159,2.394,160,2.394,193,1.847,213,1.278,214,2.16,271,1.847,272,1.632,279,1.468,291,2.16,295,1.847,296,2.35,340,1.986,341,2.394,342,1.986,343,1.986,344,6.078,345,6.078,346,2.748,347,2.748,348,2.748,349,2.748,350,1.986,351,1.986,352,2.748,353,2.394,354,1.847,355,2.748,356,2.748,357,2.748,358,2.748,359,2.748]],["tags/39",[]],["title/40",[130,1.153,288,2.13]],["content/40",[0,1.025,5,1.176,93,2.659,108,2.075,117,4.143,123,1.754,125,1.686,129,1.284,130,1.176,135,2.535,213,1.985,272,2.535,277,2.869,288,2.918,326,3.718,360,2.69,361,2.869,362,4.269]],["tags/40",[]],["title/41",[129,0.937,259,2.485]],["content/41",[0,1.198,6,1.032,42,2.349,83,1.638,123,1.436,125,1.381,129,0.783,130,1.375,132,1.381,134,2.321,181,1.966,217,1.699,236,2.349,259,3.77,270,1.867,308,3.923,323,2.526,331,2.202,337,2.349,360,2.202,361,2.349,363,3.495,364,2.526,365,3.044,366,2.748,367,3.044,368,2.349,369,2.748,370,2.748]],["tags/41",[]],["title/42",[93,1.719,196,3.024]],["content/42",[5,0.432,29,1.232,46,0.931,50,1.054,63,0.988,77,1.054,83,1.135,86,0.881,93,0.644,119,0.613,125,2.086,182,1.232,217,1.681,221,1.365,234,0.931,269,1.494,270,2.176,271,1.054,272,0.931,279,1.848,280,1.365,295,2.325,296,1.494,321,1.365,325,2.291,339,1.365,342,1.921,343,1.133,350,1.133,351,1.133,354,1.786,360,0.988,368,1.054,371,1.365,372,2.566,373,1.232,374,1.054,375,1.365,376,3.585,377,1.365,378,1.232,379,2.657,380,1.567,381,1.567,382,1.567,383,1.567,384,1.567,385,1.567,386,1.567,387,1.567,388,1.567,389,1.567,390,1.232,391,1.567,392,3.013,393,3.013,394,1.365,395,1.365,396,1.232,397,2.719,398,1.054,399,0.988,400,1.232,401,1.232,402,2.738,403,1.232,404,1.786,405,1.365,406,1.365,407,1.365,408,1.365,409,1.365,410,1.232,411,2.089,412,1.232,413,1.365,414,1.365,415,1.365,416,1.232,417,2.315,418,1.365,419,1.365,420,1.365,421,1.365,422,1.365]],["tags/42",[]],["title/43",[63,3.247]],["content/43",[4,1.688,119,0.86,423,4.131,424,3.394,425,4.978,426,3.6,427,4.978]],["tags/43",[]],["title/44",[4,0.898,119,0.458,423,2.197,424,1.806]],["content/44",[425,5.438,426,3.934,427,5.438]],["tags/44",[]],["title/45",[4,1.04,423,2.545,424,2.092]],["content/45",[0,0.718,4,0.884,6,1.572,62,2.162,63,1.885,118,2.352,228,2.352,269,1.682,285,2.606,353,2.606,364,3.22,398,2.995,399,2.807,423,3.847,424,3.927,426,2.807,428,2.991,429,2.162,430,2.162,431,2.352,432,2.352,433,2.991,434,4.455,435,4.455,436,2.991,437,2.991,438,2.991,439,4.455,440,2.162,441,1.885,442,2.991,443,2.606,444,2.991,445,2.991]],["tags/45",[]],["title/46",[446,5.154]],["content/46",[3,1.798,4,0.994,17,1.798,22,2.432,38,1.998,42,2.262,83,1.594,92,2.931,93,1.995,123,1.382,179,2.645,189,3.51,217,1.636,237,2.931,261,2.931,273,2.931,364,3.51,365,2.931,424,3.705,430,2.432,447,3.364,448,3.364,449,3.364,450,4.23,451,4.855,452,2.931,453,3.364,454,2.931,455,3.364,456,3.364,457,3.364]],["tags/46",[]],["title/47",[458,3.725]],["content/47",[0,1.009,3,2.245,4,1.241,5,1.158,6,1.241,28,3.037,31,2.363,34,3.304,58,2.441,75,2.887,134,1.954,185,1.873,193,2.825,234,2.496,246,2.825,284,4.941,441,2.648,459,4.202,460,3.304,461,3.037]],["tags/47",[]],["title/48",[0,0.73,6,0.898,108,1.478,426,1.915]],["content/48",[]],["tags/48",[]],["title/49",[0,0.845,6,1.04,129,0.789]],["content/49",[0,1.195,6,1.872,58,1.892,129,1.115,217,2.419,292,4.335,293,3.913,294,4.335,295,3.346,296,2.799,297,3.346,298,3.597,462,4.977]],["tags/49",[]],["title/50",[130,0.838,132,1.201,256,1.806,302,2.044]],["content/50",[0,1.229,3,2.268,4,0.828,5,1.17,6,1.686,10,1.666,12,1.152,13,2.028,20,2.028,83,0.921,93,1.744,117,2.028,123,1.152,125,1.108,131,1.892,132,1.108,135,1.666,174,3.337,181,1.578,185,1.25,205,1.364,235,2.674,236,1.886,247,2.443,249,2.205,256,3.042,301,1.767,302,1.886,303,3.337,320,2.443,331,1.767,336,2.443,337,1.886,400,2.205,463,4.245,464,2.805,465,2.205,466,2.805,467,2.443,468,2.205,469,2.805]],["tags/50",[]],["title/51",[130,1.153,288,2.13]],["content/51",[0,1.087,6,1.593,83,1.004,123,1.257,129,1.493,130,0.843,134,1.423,164,2.405,185,1.363,205,1.487,264,2.211,277,2.056,279,1.635,288,1.557,289,2.405,331,1.928,337,2.056,341,2.665,342,2.211,343,2.211,350,2.211,351,2.211,360,1.928,361,2.056,364,2.211,366,2.405,390,2.405,441,2.854,470,2.665,471,2.665,472,2.665,473,3.059,474,3.059,475,3.059,476,3.059,477,2.665,478,2.665,479,3.059,480,3.059]],["tags/51",[]],["title/52",[6,1.236,426,2.636]],["content/52",[0,0.61,6,1.733,83,1.581,86,1.429,93,1.979,123,1.044,125,1.903,129,1.079,130,0.7,137,1.509,196,3.92,201,1.998,205,1.235,215,2.213,235,1.601,255,2.213,269,1.429,270,1.358,272,1.509,278,2.213,288,1.294,296,1.429,297,1.708,298,1.837,324,3.428,354,1.708,367,2.213,378,1.998,426,2.48,430,1.837,431,1.998,432,1.998,460,1.998,478,2.213,481,2.541,482,2.541,483,3.935,484,1.998,485,2.541,486,2.541,487,2.213,488,1.998,489,1.837,490,2.541,491,2.541,492,2.541,493,2.213,494,2.541]],["tags/52",[]],["title/53",[228,2.39,259,1.806,450,2.648,495,3.04]],["content/53",[0,0.788,4,0.969,6,1.659,8,2.581,108,1.596,123,2.534,129,1.259,130,0.904,188,3.75,205,1.596,259,3.337,293,2.581,304,2.373,340,2.373,424,1.95,429,2.373,452,2.859,454,2.859,465,2.581,468,2.581,496,3.282,497,3.282,498,3.282,499,3.282,500,3.282,501,3.282,502,3.282,503,3.282,504,2.859,505,3.282,506,3.282,507,3.282]],["tags/53",[]],["title/54",[123,1.719,129,0.937]],["content/54",[0,0.981,3,1.425,4,0.788,6,1.206,22,1.927,37,2.323,38,1.584,83,1.341,96,2.323,123,1.095,125,1.053,129,1.112,130,1.125,132,1.053,134,1.9,181,2.297,197,2.323,205,1.296,210,3.211,236,1.792,259,3.562,270,2.182,274,2.323,277,1.792,308,3.211,323,1.927,325,1.5,331,1.68,337,1.792,360,1.68,361,1.792,366,2.096,368,1.792,369,3.211,370,2.096,372,1.68,429,1.927,477,2.323,484,2.096,488,2.096,489,1.927,508,2.323,509,2.666,510,2.666,511,2.666]],["tags/54",[]],["title/55",[130,0.838,369,2.39,512,3.04,513,2.648]],["content/55",[50,3.063,107,3.294,108,2.215,129,1.021,130,1.256,132,1.8,181,2.563,205,2.215,259,2.707,323,3.294,340,3.294,370,3.583,429,3.294,508,3.97,513,3.97,514,4.557,515,4.557,516,4.557,517,4.557]],["tags/55",[]],["title/56",[4,0.898,93,1.249,123,1.249,279,1.624]],["content/56",[46,1.701,50,1.926,83,1.416,86,1.611,93,1.177,119,0.431,125,1.704,129,0.642,205,1.393,210,2.252,217,2.521,264,2.071,269,1.611,270,2.304,271,1.926,279,2.304,295,1.926,342,3.117,343,2.071,354,1.926,371,2.495,372,3.268,373,2.252,375,2.495,376,2.252,377,2.495,390,2.252,398,2.899,399,2.717,411,2.252,417,3.757,418,2.495,419,2.495,420,2.495,421,2.495,422,2.495,441,1.805,518,2.864,519,2.864,520,2.864,521,2.864,522,2.864]],["tags/56",[]],["title/57",[125,1.057,130,0.737,184,2.33,265,1.504,404,1.798]],["content/57",[5,0.728,29,2.076,46,1.568,63,1.664,83,0.867,119,0.397,125,2.359,182,2.076,234,1.568,269,1.485,270,2.166,272,1.568,279,1.411,325,2.775,350,1.909,351,1.909,354,1.775,368,1.775,372,1.664,376,3.879,392,3.531,393,3.531,394,2.3,395,2.3,396,2.076,397,3.879,398,1.775,399,1.664,400,2.076,401,2.076,402,3.72,403,2.076,404,2.725,405,2.3,406,2.3,407,2.3,408,2.3,409,2.3,410,2.076,411,2.076,412,2.076,413,2.3,414,2.3,415,2.3,416,2.076]],["tags/57",[]],["title/58",[130,0.838,205,1.478,217,1.478,404,2.044]],["content/58",[5,0.939,111,2.968,119,1.099,125,1.346,130,0.939,132,2.479,218,2.463,301,2.146,396,2.678,397,2.678,398,3.857,399,2.146,401,2.678,402,2.29,404,2.29,416,2.678,440,3.542,465,2.678,504,2.968,523,3.407,524,3.407,525,3.407,526,3.407,527,3.407,528,3.407,529,3.407]],["tags/58",[]],["title/59",[130,1.153,265,2.353]],["content/59",[0,1.17,6,1.618,50,1.741,81,2.256,86,1.456,93,1.064,107,1.872,125,2.471,129,0.895,130,1.343,145,2.256,208,2.036,217,1.259,264,1.872,265,3.081,267,2.256,270,2.134,272,2.895,288,2.033,360,1.632,361,1.741,368,1.741,372,1.632,373,3.14,378,2.036,460,3.832,468,2.036,530,2.59,531,2.59,532,2.59,533,2.887,534,2.887,535,3.993,536,3.479,537,2.59,538,2.59,539,2.256]],["tags/59",[]],["title/60",[265,1.98,540,3.068,541,2.769]],["content/60",[0,0.61,2,2.213,5,0.7,82,2.213,83,1.581,123,1.044,125,1.903,129,0.569,130,1.084,151,2.213,208,1.998,217,1.235,235,2.48,265,2.709,269,1.429,270,1.358,279,1.358,288,1.294,296,3.05,372,1.601,399,1.601,402,2.645,410,1.998,412,1.998,424,1.509,430,1.837,432,1.998,443,2.213,467,2.213,484,1.998,488,1.998,534,2.845,536,2.213,539,2.213,540,3.428,541,3.094,542,2.541,543,5.423,544,5.423,545,2.541,546,3.935,547,2.541,548,2.541,549,2.541]],["tags/60",[]],["title/61",[116,3.645,117,3.024]],["content/61",[58,1.928,75,2.581,108,2.465,119,1.059,246,3.408,374,3.408,458,3.665,461,3.665,533,3.665,550,3.987,551,3.987]],["tags/61",[]],["title/62",[75,2.13,119,0.63]],["content/62",[461,4.411,533,4.411,550,4.798,551,4.798]],["tags/62",[]],["title/63",[58,1.339,119,0.53,246,2.367]],["content/63",[458,4.732]],["tags/63",[]],["title/64",[108,1.712,119,0.53,374,2.367]],["content/64",[]],["tags/64",[]],["title/154",[58,1.591,185,1.865]],["content/154",[]],["tags/154",[]],["title/155",[458,3.725]],["content/155",[13,3.597,32,2.419,58,1.892,75,2.534,134,2.315,185,2.218,216,3.913,290,3.913,489,3.597,552,6.337,553,4.977,554,4.977,555,3.346]],["tags/155",[]],["title/156",[31,1.71,32,1.478,83,0.998,300,2.648]],["content/156",[17,1.779,28,1.487,30,1.099,31,3.185,32,2.038,46,1.222,58,0.782,78,1.617,87,2.642,119,0.991,134,0.957,169,1.617,181,1.872,185,0.917,189,1.487,234,1.977,265,1.157,271,1.383,301,2.097,325,2.71,340,1.487,403,1.617,431,3.297,470,1.792,471,1.792,472,1.792,555,3.807,556,4.818,557,3.329,558,4.818,559,2.057,560,2.057,561,4.193,562,4.193,563,3.329,564,4.193,565,1.792,566,2.9,567,2.057,568,2.057,569,2.057,570,2.057,571,2.057,572,2.057]],["tags/156",[]],["title/157",[185,1.569,213,1.638,573,2.545]],["content/157",[28,2.211,30,1.635,31,1.721,32,1.487,70,2.211,83,1.487,119,0.812,157,2.665,181,1.721,185,2.019,213,2.107,234,2.69,288,1.557,304,2.211,325,2.547,440,2.211,441,1.928,534,2.211,555,2.056,573,3.899,574,5.394,575,3.059,576,3.059,577,3.059,578,3.059,579,3.059,580,3.059,581,3.059,582,3.059,583,3.059,584,3.059,585,3.059,586,3.059,587,2.665,588,3.059,589,2.405,590,3.059]],["tags/157",[]],["title/158",[32,1.712,58,1.339,185,1.569]],["content/158",[7,0.751,16,1.324,30,0.863,32,2.603,46,0.959,58,1.578,83,0.53,93,0.663,119,1.043,127,2.142,131,0.719,137,0.959,183,1.406,185,1.214,187,4.066,193,1.085,213,1.644,219,1.269,256,0.959,265,0.908,269,0.908,296,1.532,301,1.716,325,2.829,374,1.085,440,1.167,441,1.017,489,1.969,493,2.373,555,2.376,565,1.406,566,1.406,573,2.555,587,1.406,589,2.779,591,1.614,592,3.079,593,1.614,594,2.724,595,2.724,596,2.724,597,2.724,598,2.724,599,2.724,600,1.614,601,1.614,602,1.614,603,2.724,604,1.614,605,1.614,606,1.614,607,1.614,608,1.614,609,1.614,610,1.614,611,2.724,612,2.724,613,2.724,614,1.614,615,2.724,616,1.614,617,1.614]],["tags/158",[]],["title/159",[618,4.489]],["content/159",[0,0.743,3,1.653,32,2.221,56,2.08,58,1.737,84,2.237,108,1.504,119,0.817,185,2.036,187,2.237,213,2.974,219,2.433,289,2.433,304,2.237,325,2.569,534,2.237,541,2.433,555,3.071,573,4.623,589,3.591,592,2.696,618,2.696,619,3.094,620,3.094,621,3.094,622,6.395,623,3.094]],["tags/159",[]],["title/160",[108,2.034,374,2.813]],["content/160",[]],["tags/160",[]],["title/161",[75,2.624]],["content/161",[0,1.551,31,2.045,75,1.851,134,2.387,290,2.859,291,4.035,402,3.45,461,3.71,487,3.168,533,2.628,550,4.677,551,4.035,624,5.132,625,5.132,626,3.636,627,3.636,628,3.636,629,3.636,630,3.636,631,3.636,632,3.636,633,3.636]],["tags/161",[]]],"invertedIndex":[["",{"_index":119,"title":{"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{},"44":{},"62":{},"63":{},"64":{},"138":{},"139":{},"140":{},"141":{},"142":{}},"content":{"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"31":{},"32":{},"33":{},"36":{},"42":{},"43":{},"56":{},"57":{},"58":{},"61":{},"137":{},"156":{},"157":{},"158":{},"159":{}},"tags":{}}],["1",{"_index":127,"title":{},"content":{"137":{},"141":{},"158":{}},"tags":{}}],["1.29",{"_index":593,"title":{},"content":{"158":{}},"tags":{}}],["2",{"_index":77,"title":{},"content":{"21":{},"42":{},"134":{},"137":{},"142":{}},"tags":{}}],["203.0.113.34",{"_index":416,"title":{},"content":{"42":{},"57":{},"58":{}},"tags":{}}],["3",{"_index":121,"title":{},"content":{"137":{},"138":{}},"tags":{}}],["30",{"_index":382,"title":{},"content":{"42":{}},"tags":{}}],["32049705",{"_index":610,"title":{},"content":{"158":{}},"tags":{}}],["32238657",{"_index":616,"title":{},"content":{"158":{}},"tags":{}}],["45",{"_index":617,"title":{},"content":{"158":{}},"tags":{}}],["5",{"_index":124,"title":{},"content":{"137":{},"140":{}},"tags":{}}],["60",{"_index":413,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b",{"_index":529,"title":{},"content":{"58":{}},"tags":{}}],["9m47",{"_index":614,"title":{},"content":{"158":{}},"tags":{}}],["abov",{"_index":588,"title":{},"content":{"157":{}},"tags":{}}],["accept",{"_index":180,"title":{},"content":{"19":{}},"tags":{}}],["access",{"_index":46,"title":{},"content":{"39":{},"42":{},"56":{},"57":{},"134":{},"156":{},"158":{}},"tags":{}}],["accommod",{"_index":243,"title":{},"content":{"21":{}},"tags":{}}],["account",{"_index":553,"title":{},"content":{"155":{}},"tags":{}}],["action",{"_index":114,"title":{},"content":{"136":{}},"tags":{}}],["activ",{"_index":147,"title":{},"content":{"17":{}},"tags":{}}],["actual",{"_index":469,"title":{},"content":{"50":{}},"tags":{}}],["ad",{"_index":174,"title":{},"content":{"18":{},"21":{},"50":{}},"tags":{}}],["add",{"_index":301,"title":{},"content":{"36":{},"37":{},"50":{},"58":{},"156":{},"158":{}},"tags":{}}],["addit",{"_index":236,"title":{},"content":{"21":{},"36":{},"41":{},"50":{},"54":{}},"tags":{}}],["address",{"_index":377,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["admin",{"_index":57,"title":{},"content":{"134":{}},"tags":{}}],["administr",{"_index":59,"title":{},"content":{"134":{},"135":{}},"tags":{}}],["afterward",{"_index":570,"title":{},"content":{"156":{}},"tags":{}}],["ag",{"_index":608,"title":{},"content":{"158":{}},"tags":{}}],["agent",{"_index":178,"title":{},"content":{"19":{}},"tags":{}}],["aim",{"_index":143,"title":{},"content":{"17":{}},"tags":{}}],["ak",{"_index":32,"title":{"20":{},"156":{},"158":{}},"content":{"20":{},"21":{},"133":{},"155":{},"156":{},"157":{},"158":{},"159":{}},"tags":{}}],["allow",{"_index":431,"title":{},"content":{"45":{},"52":{},"156":{}},"tags":{}}],["alreadi",{"_index":465,"title":{},"content":{"50":{},"53":{},"58":{}},"tags":{}}],["altern",{"_index":393,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["alway",{"_index":43,"title":{},"content":{"134":{}},"tags":{}}],["annot",{"_index":302,"title":{"37":{},"50":{}},"content":{"36":{},"37":{},"50":{}},"tags":{}}],["anoth",{"_index":532,"title":{},"content":{"59":{}},"tags":{}}],["api",{"_index":164,"title":{},"content":{"18":{},"19":{},"51":{}},"tags":{}}],["app",{"_index":430,"title":{},"content":{"45":{},"46":{},"52":{},"60":{}},"tags":{}}],["appli",{"_index":297,"title":{"38":{}},"content":{"35":{},"38":{},"49":{},"52":{}},"tags":{}}],["applic",{"_index":255,"title":{},"content":{"21":{},"52":{}},"tags":{}}],["approach",{"_index":27,"title":{},"content":{"133":{}},"tags":{}}],["appropri",{"_index":166,"title":{},"content":{"18":{}},"tags":{}}],["architectur",{"_index":118,"title":{"137":{}},"content":{"21":{},"45":{}},"tags":{}}],["archiv",{"_index":626,"title":{},"content":{"161":{}},"tags":{}}],["artifact",{"_index":512,"title":{"55":{}},"content":{},"tags":{}}],["attack",{"_index":60,"title":{},"content":{"134":{}},"tags":{}}],["attempt",{"_index":407,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["attest",{"_index":123,"title":{"54":{},"56":{},"140":{}},"content":{"19":{},"21":{},"40":{},"41":{},"46":{},"50":{},"51":{},"52":{},"53":{},"54":{},"60":{},"137":{}},"tags":{}}],["attestation’",{"_index":268,"title":{},"content":{"21":{}},"tags":{}}],["audit",{"_index":513,"title":{"55":{}},"content":{"55":{}},"tags":{}}],["authent",{"_index":260,"title":{},"content":{"21":{}},"tags":{}}],["author",{"_index":208,"title":{},"content":{"19":{},"59":{},"60":{}},"tags":{}}],["avail",{"_index":441,"title":{},"content":{"45":{},"47":{},"51":{},"56":{},"157":{},"158":{}},"tags":{}}],["aw",{"_index":238,"title":{},"content":{"21":{}},"tags":{}}],["az",{"_index":555,"title":{},"content":{"155":{},"156":{},"157":{},"158":{},"159":{}},"tags":{}}],["azclusternam",{"_index":592,"title":{},"content":{"158":{},"159":{}},"tags":{}}],["azclustername=\"contrastdemo",{"_index":591,"title":{},"content":{"158":{}},"tags":{}}],["azloc",{"_index":590,"title":{},"content":{"157":{}},"tags":{}}],["azlocation=\"westu",{"_index":586,"title":{},"content":{"157":{}},"tags":{}}],["azresourcegroup",{"_index":589,"title":{},"content":{"157":{},"158":{},"159":{}},"tags":{}}],["azresourcegroup=\"contrastdemo",{"_index":585,"title":{},"content":{"157":{}},"tags":{}}],["azur",{"_index":216,"title":{},"content":{"20":{},"21":{},"155":{}},"tags":{}}],["azurelinux",{"_index":596,"title":{},"content":{"158":{}},"tags":{}}],["backend",{"_index":439,"title":{},"content":{"45":{}},"tags":{}}],["balanc",{"_index":351,"title":{},"content":{"39":{},"42":{},"51":{},"57":{}},"tags":{}}],["ballot",{"_index":450,"title":{"53":{}},"content":{"46":{}},"tags":{}}],["bare",{"_index":190,"title":{},"content":{"19":{}},"tags":{}}],["base",{"_index":9,"title":{},"content":{"18":{},"133":{},"134":{}},"tags":{}}],["bash",{"_index":383,"title":{},"content":{"42":{}},"tags":{}}],["be",{"_index":473,"title":{},"content":{"51":{}},"tags":{}}],["befor",{"_index":468,"title":{},"content":{"50":{},"53":{},"59":{}},"tags":{}}],["begin",{"_index":242,"title":{},"content":{"21":{}},"tags":{}}],["benefit",{"_index":88,"title":{"22":{}},"content":{"21":{},"135":{},"136":{}},"tags":{}}],["beyond",{"_index":231,"title":{},"content":{"21":{}},"tags":{}}],["block",{"_index":140,"title":{},"content":{"17":{},"38":{}},"tags":{}}],["board",{"_index":435,"title":{},"content":{"45":{}},"tags":{}}],["bot",{"_index":443,"title":{},"content":{"45":{},"60":{}},"tags":{}}],["both",{"_index":261,"title":{},"content":{"21":{},"46":{}},"tags":{}}],["browser",{"_index":522,"title":{},"content":{"56":{}},"tags":{}}],["build",{"_index":139,"title":{},"content":{"17":{},"36":{}},"tags":{}}],["bundl",{"_index":461,"title":{},"content":{"47":{},"61":{},"62":{},"161":{}},"tags":{}}],["c",{"_index":360,"title":{},"content":{"40":{},"41":{},"42":{},"51":{},"54":{},"59":{}},"tags":{}}],["ca",{"_index":373,"title":{},"content":{"42":{},"56":{},"59":{}},"tags":{}}],["cacert",{"_index":410,"title":{},"content":{"42":{},"57":{},"60":{}},"tags":{}}],["cafil",{"_index":419,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["call",{"_index":165,"title":{},"content":{"18":{},"19":{}},"tags":{}}],["can't",{"_index":349,"title":{},"content":{"39":{}},"tags":{}}],["capabl",{"_index":175,"title":{},"content":{"18":{},"20":{}},"tags":{}}],["case",{"_index":84,"title":{"135":{}},"content":{"18":{},"135":{},"159":{}},"tags":{}}],["cc",{"_index":320,"title":{},"content":{"36":{},"50":{}},"tags":{}}],["centralindia",{"_index":575,"title":{},"content":{"157":{}},"tags":{}}],["cert",{"_index":326,"title":{},"content":{"36":{},"40":{}},"tags":{}}],["certif",{"_index":125,"title":{"57":{},"141":{}},"content":{"21":{},"36":{},"40":{},"41":{},"42":{},"50":{},"52":{},"54":{},"56":{},"57":{},"58":{},"59":{},"60":{},"137":{}},"tags":{}}],["chain",{"_index":535,"title":{},"content":{"59":{}},"tags":{}}],["chang",{"_index":81,"title":{},"content":{"59":{},"134":{}},"tags":{}}],["channel",{"_index":509,"title":{},"content":{"54":{}},"tags":{}}],["chart",{"_index":251,"title":{},"content":{"21":{},"36":{}},"tags":{}}],["chart_nam",{"_index":314,"title":{},"content":{"36":{}},"tags":{}}],["check",{"_index":403,"title":{},"content":{"42":{},"57":{},"156":{}},"tags":{}}],["checksum",{"_index":209,"title":{},"content":{"19":{}},"tags":{}}],["class",{"_index":463,"title":{},"content":{"50":{}},"tags":{}}],["clean",{"_index":620,"title":{},"content":{"159":{}},"tags":{}}],["cleanup",{"_index":618,"title":{"159":{}},"content":{"159":{}},"tags":{}}],["cli",{"_index":134,"title":{"30":{},"149":{}},"content":{"28":{},"29":{},"30":{},"41":{},"47":{},"51":{},"54":{},"155":{},"156":{},"161":{}},"tags":{}}],["cloud",{"_index":56,"title":{},"content":{"19":{},"21":{},"134":{},"135":{},"159":{}},"tags":{}}],["cluster",{"_index":58,"title":{"63":{},"154":{},"158":{}},"content":{"20":{},"21":{},"34":{},"35":{},"38":{},"47":{},"49":{},"61":{},"134":{},"135":{},"155":{},"156":{},"158":{},"159":{}},"tags":{}}],["cncf",{"_index":141,"title":{},"content":{"17":{}},"tags":{}}],["co",{"_index":65,"title":{},"content":{"134":{}},"tags":{}}],["coco",{"_index":30,"title":{"20":{}},"content":{"17":{},"20":{},"34":{},"39":{},"133":{},"156":{},"157":{},"158":{}},"tags":{}}],["coco'",{"_index":173,"title":{},"content":{"18":{}},"tags":{}}],["code",{"_index":96,"title":{},"content":{"54":{},"135":{}},"tags":{}}],["collabor",{"_index":106,"title":{},"content":{"135":{}},"tags":{}}],["come",{"_index":61,"title":{},"content":{"134":{}},"tags":{}}],["command",{"_index":181,"title":{},"content":{"19":{},"37":{},"41":{},"50":{},"54":{},"55":{},"156":{},"157":{}},"tags":{}}],["commun",{"_index":196,"title":{"42":{}},"content":{"19":{},"21":{},"52":{}},"tags":{}}],["compat",{"_index":73,"title":{},"content":{"21":{},"134":{}},"tags":{}}],["complianc",{"_index":103,"title":{},"content":{"135":{}},"tags":{}}],["compon",{"_index":120,"title":{"138":{}},"content":{"21":{},"137":{}},"tags":{}}],["compris",{"_index":292,"title":{},"content":{"35":{},"49":{}},"tags":{}}],["compromis",{"_index":267,"title":{},"content":{"21":{},"59":{}},"tags":{}}],["comput",{"_index":38,"title":{},"content":{"17":{},"18":{},"46":{},"54":{},"133":{},"134":{},"135":{}},"tags":{}}],["concept",{"_index":110,"title":{},"content":{"21":{},"136":{}},"tags":{}}],["concis",{"_index":257,"title":{},"content":{"21":{}},"tags":{}}],["confidenti",{"_index":4,"title":{"17":{},"44":{},"45":{},"56":{},"139":{},"152":{}},"content":{"17":{},"18":{},"19":{},"21":{},"34":{},"36":{},"39":{},"43":{},"45":{},"46":{},"47":{},"50":{},"53":{},"54":{},"133":{},"135":{},"136":{},"137":{}},"tags":{}}],["config",{"_index":333,"title":{},"content":{"36":{}},"tags":{}}],["configur",{"_index":205,"title":{"58":{}},"content":{"19":{},"21":{},"36":{},"50":{},"51":{},"52":{},"53":{},"54":{},"55":{},"56":{}},"tags":{}}],["connect",{"_index":279,"title":{"39":{},"56":{}},"content":{"21":{},"39":{},"42":{},"51":{},"56":{},"57":{},"60":{}},"tags":{}}],["consid",{"_index":447,"title":{},"content":{"46":{}},"tags":{}}],["consist",{"_index":437,"title":{},"content":{"45":{}},"tags":{}}],["contain",{"_index":5,"title":{"17":{},"19":{},"29":{},"139":{},"151":{},"152":{}},"content":{"17":{},"18":{},"19":{},"21":{},"28":{},"29":{},"30":{},"36":{},"39":{},"40":{},"42":{},"47":{},"50":{},"57":{},"58":{},"60":{},"133":{},"135":{},"136":{},"137":{}},"tags":{}}],["containerd",{"_index":162,"title":{},"content":{"18":{}},"tags":{}}],["containers/issues/1693",{"_index":359,"title":{},"content":{"39":{}},"tags":{}}],["containers/kata",{"_index":358,"title":{},"content":{"39":{}},"tags":{}}],["containerservic",{"_index":572,"title":{},"content":{"156":{}},"tags":{}}],["contrast",{"_index":0,"title":{"35":{},"39":{},"48":{},"49":{},"133":{}},"content":{"17":{},"20":{},"21":{},"34":{},"35":{},"36":{},"37":{},"40":{},"41":{},"45":{},"47":{},"49":{},"50":{},"51":{},"52":{},"53":{},"54":{},"59":{},"60":{},"133":{},"134":{},"135":{},"136":{},"159":{},"161":{}},"tags":{}}],["contrast.zip",{"_index":628,"title":{},"content":{"161":{}},"tags":{}}],["coordin",{"_index":129,"title":{"27":{},"28":{},"35":{},"39":{},"41":{},"49":{},"54":{},"143":{},"150":{}},"content":{"23":{},"24":{},"25":{},"26":{},"27":{},"28":{},"29":{},"30":{},"35":{},"36":{},"38":{},"39":{},"40":{},"41":{},"49":{},"51":{},"52":{},"53":{},"54":{},"55":{},"56":{},"59":{},"60":{}},"tags":{}}],["coordinator'",{"_index":371,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["coordinator.yml",{"_index":462,"title":{},"content":{"49":{}},"tags":{}}],["coordinator:1313",{"_index":474,"title":{},"content":{"51":{}},"tags":{}}],["coordinator=$(kubectl",{"_index":341,"title":{},"content":{"39":{},"51":{}},"tags":{}}],["coordinator_host",{"_index":330,"title":{},"content":{"36":{}},"tags":{}}],["coordinator}:1313",{"_index":361,"title":{},"content":{"40":{},"41":{},"51":{},"54":{},"59":{}},"tags":{}}],["copi",{"_index":306,"title":{},"content":{"36":{}},"tags":{}}],["core",{"_index":89,"title":{},"content":{"17":{},"135":{}},"tags":{}}],["count",{"_index":599,"title":{},"content":{"158":{}},"tags":{}}],["cp",{"_index":315,"title":{},"content":{"36":{}},"tags":{}}],["creat",{"_index":185,"title":{"154":{},"157":{},"158":{}},"content":{"19":{},"37":{},"47":{},"50":{},"51":{},"155":{},"156":{},"157":{},"158":{},"159":{}},"tags":{}}],["credenti",{"_index":493,"title":{},"content":{"52":{},"158":{}},"tags":{}}],["cri",{"_index":160,"title":{},"content":{"18":{},"39":{}},"tags":{}}],["crun",{"_index":172,"title":{},"content":{"18":{}},"tags":{}}],["curl",{"_index":402,"title":{},"content":{"42":{},"57":{},"58":{},"60":{},"161":{}},"tags":{}}],["current",{"_index":28,"title":{},"content":{"47":{},"133":{},"156":{},"157":{}},"tags":{}}],["cvm",{"_index":202,"title":{},"content":{"19":{},"20":{}},"tags":{}}],["data",{"_index":42,"title":{},"content":{"21":{},"41":{},"46":{},"134":{},"135":{}},"tags":{}}],["datacent",{"_index":53,"title":{},"content":{"134":{}},"tags":{}}],["day",{"_index":76,"title":{},"content":{"21":{},"134":{}},"tags":{}}],["decid",{"_index":496,"title":{},"content":{"53":{}},"tags":{}}],["default",{"_index":394,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["defin",{"_index":482,"title":{},"content":{"52":{}},"tags":{}}],["definit",{"_index":214,"title":{},"content":{"19":{},"36":{},"39":{}},"tags":{}}],["deleg",{"_index":515,"title":{},"content":{"55":{}},"tags":{}}],["delet",{"_index":622,"title":{},"content":{"159":{}},"tags":{}}],["demo",{"_index":400,"title":{},"content":{"42":{},"50":{},"57":{}},"tags":{}}],["deploy",{"_index":6,"title":{"34":{},"35":{},"48":{},"49":{},"52":{}},"content":{"20":{},"21":{},"34":{},"35":{},"36":{},"37":{},"39":{},"41":{},"45":{},"47":{},"49":{},"50":{},"51":{},"52":{},"53":{},"54":{},"59":{},"133":{},"134":{}},"tags":{}}],["deployment/emoji",{"_index":545,"title":{},"content":{"60":{}},"tags":{}}],["deployment/vot",{"_index":546,"title":{},"content":{"60":{}},"tags":{}}],["deployment/web",{"_index":547,"title":{},"content":{"60":{}},"tags":{}}],["deriv",{"_index":212,"title":{},"content":{"19":{}},"tags":{}}],["design",{"_index":40,"title":{},"content":{"19":{},"21":{},"134":{}},"tags":{}}],["dev/nul",{"_index":422,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["develop",{"_index":148,"title":{},"content":{"17":{}},"tags":{}}],["differ",{"_index":432,"title":{},"content":{"45":{},"52":{},"60":{}},"tags":{}}],["directli",{"_index":224,"title":{},"content":{"20":{}},"tags":{}}],["directori",{"_index":308,"title":{},"content":{"36":{},"41":{},"54":{}},"tags":{}}],["dispatch",{"_index":163,"title":{},"content":{"18":{}},"tags":{}}],["distribut",{"_index":498,"title":{},"content":{"53":{}},"tags":{}}],["dn",{"_index":396,"title":{},"content":{"42":{},"57":{},"58":{}},"tags":{}}],["do",{"_index":499,"title":{},"content":{"53":{}},"tags":{}}],["document",{"_index":2,"title":{},"content":{"60":{},"133":{}},"tags":{}}],["don't",{"_index":266,"title":{},"content":{"21":{}},"tags":{}}],["done",{"_index":280,"title":{},"content":{"21":{},"42":{}},"tags":{}}],["download",{"_index":550,"title":{},"content":{"61":{},"62":{},"161":{}},"tags":{}}],["dure",{"_index":475,"title":{},"content":{"51":{}},"tags":{}}],["e.g",{"_index":631,"title":{},"content":{"161":{}},"tags":{}}],["each",{"_index":494,"title":{},"content":{"52":{}},"tags":{}}],["eastu",{"_index":576,"title":{},"content":{"157":{}},"tags":{}}],["eastus2euap",{"_index":577,"title":{},"content":{"157":{}},"tags":{}}],["echo",{"_index":390,"title":{},"content":{"42":{},"51":{},"56":{}},"tags":{}}],["edit",{"_index":525,"title":{},"content":{"58":{}},"tags":{}}],["editor",{"_index":527,"title":{},"content":{"58":{}},"tags":{}}],["ek",{"_index":239,"title":{},"content":{"21":{}},"tags":{}}],["embed",{"_index":366,"title":{},"content":{"41":{},"51":{},"54":{}},"tags":{}}],["emoji",{"_index":423,"title":{"44":{},"45":{}},"content":{"43":{},"45":{}},"tags":{}}],["emojivoto",{"_index":426,"title":{"48":{},"52":{}},"content":{"43":{},"44":{},"45":{},"52":{}},"tags":{}}],["employ",{"_index":229,"title":{},"content":{"21":{}},"tags":{}}],["employe",{"_index":54,"title":{},"content":{"134":{}},"tags":{}}],["emptydir",{"_index":335,"title":{},"content":{"36":{}},"tags":{}}],["enabl",{"_index":218,"title":{},"content":{"20":{},"21":{},"34":{},"58":{}},"tags":{}}],["encrypt",{"_index":44,"title":{"142":{}},"content":{"134":{},"137":{}},"tags":{}}],["end",{"_index":363,"title":{},"content":{"41":{}},"tags":{}}],["enforc",{"_index":507,"title":{},"content":{"53":{}},"tags":{}}],["ensur",{"_index":264,"title":{},"content":{"21":{},"51":{},"56":{},"59":{}},"tags":{}}],["entir",{"_index":233,"title":{},"content":{"21":{}},"tags":{}}],["entiti",{"_index":517,"title":{},"content":{"55":{}},"tags":{}}],["entri",{"_index":397,"title":{},"content":{"42":{},"57":{},"58":{}},"tags":{}}],["env",{"_index":329,"title":{},"content":{"36":{}},"tags":{}}],["environ",{"_index":22,"title":{},"content":{"21":{},"46":{},"54":{},"133":{}},"tags":{}}],["envoy",{"_index":282,"title":{},"content":{"21":{}},"tags":{}}],["error",{"_index":409,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["escal",{"_index":67,"title":{},"content":{"134":{}},"tags":{}}],["establish",{"_index":274,"title":{},"content":{"21":{},"54":{}},"tags":{}}],["etc",{"_index":318,"title":{},"content":{"36":{}},"tags":{}}],["even",{"_index":97,"title":{},"content":{"135":{}},"tags":{}}],["exampl",{"_index":63,"title":{"43":{}},"content":{"18":{},"42":{},"45":{},"57":{},"134":{}},"tags":{}}],["execut",{"_index":13,"title":{},"content":{"37":{},"50":{},"133":{},"155":{}},"tags":{}}],["exist",{"_index":70,"title":{},"content":{"21":{},"34":{},"134":{},"157":{}},"tags":{}}],["expect",{"_index":210,"title":{},"content":{"19":{},"54":{},"56":{}},"tags":{}}],["expos",{"_index":375,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["extend",{"_index":156,"title":{},"content":{"18":{}},"tags":{}}],["extens",{"_index":556,"title":{},"content":{"156":{}},"tags":{}}],["extern",{"_index":263,"title":{},"content":{"21":{}},"tags":{}}],["f",{"_index":298,"title":{},"content":{"35":{},"38":{},"49":{},"52":{}},"tags":{}}],["facilit",{"_index":247,"title":{},"content":{"21":{},"50":{}},"tags":{}}],["fail",{"_index":406,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["fair",{"_index":452,"title":{},"content":{"46":{},"53":{}},"tags":{}}],["favorit",{"_index":526,"title":{},"content":{"58":{}},"tags":{}}],["featur",{"_index":87,"title":{"21":{}},"content":{"17":{},"21":{},"135":{},"136":{},"156":{}},"tags":{}}],["fetch",{"_index":362,"title":{},"content":{"40":{}},"tags":{}}],["few",{"_index":471,"title":{},"content":{"51":{},"156":{}},"tags":{}}],["field",{"_index":405,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["file",{"_index":303,"title":{},"content":{"36":{},"37":{},"50":{}},"tags":{}}],["final",{"_index":605,"title":{},"content":{"158":{}},"tags":{}}],["first",{"_index":374,"title":{"64":{},"160":{}},"content":{"42":{},"61":{},"158":{}},"tags":{}}],["fit",{"_index":518,"title":{},"content":{"56":{}},"tags":{}}],["flag",{"_index":559,"title":{},"content":{"156":{}},"tags":{}}],["flo",{"_index":624,"title":{},"content":{"161":{}},"tags":{}}],["flow",{"_index":82,"title":{},"content":{"60":{},"134":{}},"tags":{}}],["fluentli",{"_index":69,"title":{},"content":{"134":{}},"tags":{}}],["flux",{"_index":152,"title":{},"content":{"17":{}},"tags":{}}],["follow",{"_index":234,"title":{},"content":{"21":{},"34":{},"42":{},"47":{},"57":{},"156":{},"157":{}},"tags":{}}],["forward",{"_index":345,"title":{},"content":{"39":{}},"tags":{}}],["frontend",{"_index":399,"title":{},"content":{"42":{},"45":{},"56":{},"57":{},"58":{},"60":{}},"tags":{}}],["frontendip",{"_index":528,"title":{},"content":{"58":{}},"tags":{}}],["frontendip=$(kubectl",{"_index":519,"title":{},"content":{"56":{}},"tags":{}}],["frontendip}:443",{"_index":421,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["futur",{"_index":502,"title":{},"content":{"53":{}},"tags":{}}],["gener",{"_index":256,"title":{"37":{},"50":{}},"content":{"21":{},"36":{},"37":{},"50":{},"158":{}},"tags":{}}],["germanywestcentr",{"_index":578,"title":{},"content":{"157":{}},"tags":{}}],["get",{"_index":116,"title":{"61":{}},"content":{"136":{}},"tags":{}}],["ghcr.io/edgelesssys/contrast/initializer:latest",{"_index":328,"title":{},"content":{"36":{}},"tags":{}}],["gke",{"_index":241,"title":{},"content":{"21":{}},"tags":{}}],["go",{"_index":230,"title":{},"content":{"21":{}},"tags":{}}],["goal",{"_index":39,"title":{"134":{}},"content":{},"tags":{}}],["googl",{"_index":240,"title":{},"content":{"21":{}},"tags":{}}],["grep",{"_index":386,"title":{},"content":{"42":{}},"tags":{}}],["group",{"_index":573,"title":{"157":{}},"content":{"157":{},"158":{},"159":{}},"tags":{}}],["grpc",{"_index":438,"title":{},"content":{"45":{}},"tags":{}}],["guest",{"_index":176,"title":{},"content":{"19":{}},"tags":{}}],["guid",{"_index":285,"title":{},"content":{"34":{},"45":{}},"tags":{}}],["handshak",{"_index":476,"title":{},"content":{"51":{}},"tags":{}}],["har",{"_index":281,"title":{},"content":{"21":{}},"tags":{}}],["hardwar",{"_index":19,"title":{"23":{},"144":{}},"content":{"23":{},"24":{},"25":{},"26":{},"27":{},"133":{}},"tags":{}}],["hash",{"_index":524,"title":{},"content":{"58":{}},"tags":{}}],["hasn't",{"_index":479,"title":{},"content":{"51":{}},"tags":{}}],["head",{"_index":115,"title":{},"content":{"136":{}},"tags":{}}],["helm",{"_index":250,"title":{},"content":{"21":{},"36":{}},"tags":{}}],["high",{"_index":150,"title":{},"content":{"17":{}},"tags":{}}],["highli",{"_index":448,"title":{},"content":{"46":{}},"tags":{}}],["histori",{"_index":369,"title":{"55":{}},"content":{"41":{},"54":{}},"tags":{}}],["host",{"_index":182,"title":{},"content":{"19":{},"42":{},"57":{}},"tags":{}}],["html",{"_index":548,"title":{},"content":{"60":{}},"tags":{}}],["http",{"_index":492,"title":{},"content":{"52":{}},"tags":{}}],["https://$frontendip",{"_index":520,"title":{},"content":{"56":{}},"tags":{}}],["https://${frontendip}:443",{"_index":412,"title":{},"content":{"42":{},"57":{},"60":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/contrast",{"_index":629,"title":{},"content":{"161":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml",{"_index":299,"title":{},"content":{"35":{}},"tags":{}}],["https://github.com/kata",{"_index":357,"title":{},"content":{"39":{}},"tags":{}}],["ident",{"_index":126,"title":{"141":{}},"content":{"21":{},"137":{}},"tags":{}}],["imag",{"_index":211,"title":{},"content":{"19":{},"36":{}},"tags":{}}],["implement",{"_index":161,"title":{},"content":{"18":{}},"tags":{}}],["impos",{"_index":79,"title":{},"content":{"134":{}},"tags":{}}],["includ",{"_index":52,"title":{},"content":{"19":{},"39":{},"134":{}},"tags":{}}],["increas",{"_index":90,"title":{},"content":{"135":{}},"tags":{}}],["individu",{"_index":232,"title":{},"content":{"21":{}},"tags":{}}],["infect",{"_index":538,"title":{},"content":{"59":{}},"tags":{}}],["inform",{"_index":37,"title":{},"content":{"54":{},"133":{}},"tags":{}}],["infrastructur",{"_index":47,"title":{},"content":{"19":{},"21":{},"134":{}},"tags":{}}],["ingress",{"_index":387,"title":{},"content":{"42":{}},"tags":{}}],["init",{"_index":135,"title":{"29":{},"151":{}},"content":{"28":{},"29":{},"30":{},"40":{},"50":{}},"tags":{}}],["initcontain",{"_index":322,"title":{},"content":{"36":{}},"tags":{}}],["initi",{"_index":235,"title":{},"content":{"21":{},"36":{},"38":{},"50":{},"52":{},"60":{}},"tags":{}}],["insid",{"_index":14,"title":{},"content":{"133":{}},"tags":{}}],["inspect",{"_index":514,"title":{},"content":{"55":{}},"tags":{}}],["instal",{"_index":75,"title":{"62":{},"161":{}},"content":{"20":{},"21":{},"35":{},"47":{},"61":{},"134":{},"155":{},"161":{}},"tags":{}}],["instruct",{"_index":284,"title":{},"content":{"34":{},"47":{}},"tags":{}}],["integr",{"_index":68,"title":{},"content":{"21":{},"134":{}},"tags":{}}],["inter",{"_index":483,"title":{},"content":{"52":{}},"tags":{}}],["interest",{"_index":451,"title":{},"content":{"46":{}},"tags":{}}],["interfac",{"_index":159,"title":{},"content":{"18":{},"39":{}},"tags":{}}],["intern",{"_index":262,"title":{},"content":{"21":{}},"tags":{}}],["ip",{"_index":376,"title":{},"content":{"42":{},"56":{},"57":{}},"tags":{}}],["isn't",{"_index":347,"title":{},"content":{"39":{}},"tags":{}}],["isol",{"_index":20,"title":{},"content":{"19":{},"36":{},"50":{},"133":{}},"tags":{}}],["issu",{"_index":272,"title":{},"content":{"21":{},"39":{},"40":{},"42":{},"52":{},"57":{},"59":{}},"tags":{}}],["it'",{"_index":72,"title":{},"content":{"19":{},"134":{}},"tags":{}}],["item",{"_index":122,"title":{},"content":{"137":{},"138":{},"140":{},"141":{},"142":{}},"tags":{}}],["japaneast",{"_index":579,"title":{},"content":{"157":{}},"tags":{}}],["jump",{"_index":112,"title":{},"content":{"136":{}},"tags":{}}],["kata",{"_index":10,"title":{"19":{}},"content":{"18":{},"19":{},"36":{},"39":{},"50":{},"133":{}},"tags":{}}],["kataccisol",{"_index":604,"title":{},"content":{"158":{}},"tags":{}}],["kataccisolationpreview",{"_index":563,"title":{},"content":{"156":{}},"tags":{}}],["keep",{"_index":41,"title":{},"content":{"36":{},"134":{}},"tags":{}}],["key",{"_index":137,"title":{"16":{},"33":{}},"content":{"21":{},"32":{},"33":{},"52":{},"158":{}},"tags":{}}],["kubeconfig",{"_index":606,"title":{},"content":{"158":{}},"tags":{}}],["kubectl",{"_index":296,"title":{},"content":{"35":{},"38":{},"39":{},"42":{},"49":{},"52":{},"60":{},"158":{}},"tags":{}}],["kubernet",{"_index":7,"title":{"18":{},"36":{}},"content":{"17":{},"18":{},"19":{},"20":{},"21":{},"34":{},"36":{},"133":{},"134":{},"158":{}},"tags":{}}],["kustom",{"_index":252,"title":{},"content":{"21":{},"36":{}},"tags":{}}],["latest",{"_index":290,"title":{},"content":{"35":{},"155":{},"161":{}},"tags":{}}],["layer",{"_index":48,"title":{},"content":{"134":{}},"tags":{}}],["lbip",{"_index":391,"title":{},"content":{"42":{}},"tags":{}}],["lbip=$(kubectl",{"_index":389,"title":{},"content":{"42":{}},"tags":{}}],["leader",{"_index":434,"title":{},"content":{"45":{}},"tags":{}}],["leak",{"_index":457,"title":{},"content":{"46":{}},"tags":{}}],["learn",{"_index":109,"title":{},"content":{"136":{}},"tags":{}}],["level",{"_index":145,"title":{},"content":{"17":{},"59":{}},"tags":{}}],["leverag",{"_index":220,"title":{},"content":{"20":{}},"tags":{}}],["lift",{"_index":25,"title":{},"content":{"133":{}},"tags":{}}],["lightweight",{"_index":244,"title":{},"content":{"21":{}},"tags":{}}],["list",{"_index":440,"title":{},"content":{"45":{},"58":{},"157":{},"158":{}},"tags":{}}],["load",{"_index":350,"title":{},"content":{"39":{},"42":{},"51":{},"57":{}},"tags":{}}],["loadbalanc",{"_index":295,"title":{},"content":{"35":{},"39":{},"42":{},"49":{},"56":{}},"tags":{}}],["local",{"_index":186,"title":{},"content":{"19":{},"36":{}},"tags":{}}],["locat",{"_index":574,"title":{},"content":{"157":{}},"tags":{}}],["logic",{"_index":442,"title":{},"content":{"45":{}},"tags":{}}],["login",{"_index":552,"title":{},"content":{"155":{}},"tags":{}}],["make",{"_index":286,"title":{},"content":{"34":{}},"tags":{}}],["malici",{"_index":64,"title":{},"content":{"134":{}},"tags":{}}],["manag",{"_index":74,"title":{},"content":{"18":{},"19":{},"21":{},"134":{}},"tags":{}}],["mani",{"_index":149,"title":{},"content":{"17":{}},"tags":{}}],["manifest",{"_index":130,"title":{"26":{},"37":{},"40":{},"50":{},"51":{},"55":{},"57":{},"58":{},"59":{},"145":{}},"content":{"23":{},"24":{},"25":{},"26":{},"27":{},"38":{},"40":{},"41":{},"51":{},"52":{},"53":{},"54":{},"55":{},"58":{},"59":{},"60":{}},"tags":{}}],["manifest.json",{"_index":336,"title":{},"content":{"37":{},"50":{}},"tags":{}}],["map",{"_index":523,"title":{},"content":{"58":{}},"tags":{}}],["match",{"_index":415,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["mean",{"_index":505,"title":{},"content":{"53":{}},"tags":{}}],["mesh",{"_index":270,"title":{},"content":{"21":{},"41":{},"42":{},"52":{},"54":{},"56":{},"57":{},"59":{},"60":{}},"tags":{}}],["metal",{"_index":191,"title":{},"content":{"19":{}},"tags":{}}],["method",{"_index":346,"title":{},"content":{"39":{}},"tags":{}}],["micro",{"_index":15,"title":{},"content":{"133":{}},"tags":{}}],["microservic",{"_index":436,"title":{},"content":{"45":{}},"tags":{}}],["microsoft.containerservic",{"_index":562,"title":{},"content":{"156":{}},"tags":{}}],["minim",{"_index":80,"title":{},"content":{"21":{},"134":{}},"tags":{}}],["minut",{"_index":472,"title":{},"content":{"51":{},"156":{}},"tags":{}}],["mkdir",{"_index":309,"title":{},"content":{"36":{}},"tags":{}}],["mode",{"_index":204,"title":{},"content":{"19":{}},"tags":{}}],["more",{"_index":36,"title":{},"content":{"17":{},"18":{},"133":{},"136":{}},"tags":{}}],["motiv",{"_index":446,"title":{"46":{}},"content":{},"tags":{}}],["mountpath",{"_index":332,"title":{},"content":{"36":{}},"tags":{}}],["move",{"_index":91,"title":{},"content":{"135":{}},"tags":{}}],["mtl",{"_index":278,"title":{},"content":{"21":{},"52":{}},"tags":{}}],["multi",{"_index":104,"title":{},"content":{"135":{}},"tags":{}}],["mutual",{"_index":276,"title":{},"content":{"21":{}},"tags":{}}],["mv",{"_index":632,"title":{},"content":{"161":{}},"tags":{}}],["my_resource_dir",{"_index":310,"title":{},"content":{"36":{}},"tags":{}}],["my_servic",{"_index":379,"title":{},"content":{"42":{}},"tags":{}}],["name",{"_index":325,"title":{},"content":{"36":{},"42":{},"54":{},"57":{},"156":{},"157":{},"158":{},"159":{}},"tags":{}}],["namespac",{"_index":561,"title":{},"content":{"156":{}},"tags":{}}],["nativ",{"_index":253,"title":{},"content":{"21":{}},"tags":{}}],["need",{"_index":340,"title":{},"content":{"39":{},"53":{},"55":{},"156":{}},"tags":{}}],["nest",{"_index":194,"title":{},"content":{"19":{},"20":{}},"tags":{}}],["network",{"_index":128,"title":{"142":{}},"content":{"19":{},"137":{}},"tags":{}}],["new",{"_index":534,"title":{},"content":{"59":{},"60":{},"157":{},"159":{}},"tags":{}}],["next",{"_index":107,"title":{"136":{}},"content":{"39":{},"55":{},"59":{}},"tags":{}}],["node",{"_index":187,"title":{},"content":{"19":{},"20":{},"158":{},"159":{}},"tags":{}}],["nodepool",{"_index":602,"title":{},"content":{"158":{}},"tags":{}}],["nodepool1",{"_index":609,"title":{},"content":{"158":{}},"tags":{}}],["nodepool2",{"_index":603,"title":{},"content":{"158":{}},"tags":{}}],["none",{"_index":613,"title":{},"content":{"158":{}},"tags":{}}],["northeurop",{"_index":580,"title":{},"content":{"157":{}},"tags":{}}],["now",{"_index":481,"title":{},"content":{"52":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":343,"title":{},"content":{"39":{},"42":{},"51":{},"56":{}},"tags":{}}],["object",{"_index":158,"title":{},"content":{"18":{}},"tags":{}}],["oci",{"_index":168,"title":{},"content":{"18":{},"19":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"20":{},"21":{},"135":{}},"tags":{}}],["older",{"_index":539,"title":{},"content":{"59":{},"60":{}},"tags":{}}],["on",{"_index":157,"title":{},"content":{"18":{},"157":{}},"tags":{}}],["opa",{"_index":207,"title":{},"content":{"19":{}},"tags":{}}],["open",{"_index":206,"title":{},"content":{"19":{}},"tags":{}}],["openssl",{"_index":417,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"21":{},"134":{},"156":{}},"tags":{}}],["optim",{"_index":226,"title":{},"content":{"21":{}},"tags":{}}],["option",{"_index":184,"title":{"57":{}},"content":{"19":{}},"tags":{}}],["orchestr",{"_index":254,"title":{},"content":{"21":{}},"tags":{}}],["origin",{"_index":201,"title":{},"content":{"19":{},"36":{},"52":{}},"tags":{}}],["os",{"_index":594,"title":{},"content":{"158":{}},"tags":{}}],["out",{"_index":541,"title":{"60":{}},"content":{"60":{},"159":{}},"tags":{}}],["output",{"_index":568,"title":{},"content":{"156":{}},"tags":{}}],["output=jsonpath='{.status.loadbalanc",{"_index":385,"title":{},"content":{"42":{}},"tags":{}}],["over",{"_index":197,"title":{},"content":{"19":{},"54":{}},"tags":{}}],["owner",{"_index":365,"title":{},"content":{"41":{},"46":{}},"tags":{}}],["p",{"_index":380,"title":{},"content":{"42":{}},"tags":{}}],["part",{"_index":460,"title":{},"content":{"47":{},"52":{},"59":{}},"tags":{}}],["parti",{"_index":105,"title":{},"content":{"21":{},"135":{}},"tags":{}}],["patch",{"_index":378,"title":{},"content":{"42":{},"52":{},"59":{}},"tags":{}}],["path",{"_index":630,"title":{},"content":{"161":{}},"tags":{}}],["permiss",{"_index":554,"title":{},"content":{"155":{}},"tags":{}}],["perspect",{"_index":228,"title":{"53":{}},"content":{"21":{},"45":{}},"tags":{}}],["phase",{"_index":338,"title":{},"content":{"38":{}},"tags":{}}],["pki",{"_index":133,"title":{"31":{},"148":{}},"content":{"21":{},"31":{}},"tags":{}}],["plain",{"_index":491,"title":{},"content":{"52":{}},"tags":{}}],["platform",{"_index":237,"title":{},"content":{"21":{},"46":{}},"tags":{}}],["pleas",{"_index":459,"title":{},"content":{"47":{}},"tags":{}}],["pod",{"_index":12,"title":{"24":{},"146":{}},"content":{"17":{},"18":{},"19":{},"21":{},"23":{},"24":{},"25":{},"26":{},"27":{},"36":{},"39":{},"50":{},"133":{}},"tags":{}}],["polici",{"_index":132,"title":{"25":{},"37":{},"50":{},"147":{}},"content":{"19":{},"23":{},"24":{},"25":{},"26":{},"27":{},"37":{},"41":{},"50":{},"54":{},"55":{},"58":{}},"tags":{}}],["pool",{"_index":219,"title":{},"content":{"20":{},"158":{},"159":{}},"tags":{}}],["port",{"_index":344,"title":{},"content":{"39":{}},"tags":{}}],["potenti",{"_index":508,"title":{},"content":{"54":{},"55":{}},"tags":{}}],["pre",{"_index":223,"title":{},"content":{"20":{}},"tags":{}}],["prem",{"_index":94,"title":{},"content":{"135":{}},"tags":{}}],["prepar",{"_index":300,"title":{"36":{},"156":{}},"content":{},"tags":{}}],["prerequisit",{"_index":458,"title":{"47":{},"155":{}},"content":{"61":{},"63":{}},"tags":{}}],["prevent",{"_index":45,"title":{},"content":{"134":{}},"tags":{}}],["preview",{"_index":31,"title":{"20":{},"156":{}},"content":{"20":{},"47":{},"133":{},"156":{},"157":{},"161":{}},"tags":{}}],["primit",{"_index":154,"title":{},"content":{"17":{}},"tags":{}}],["privat",{"_index":487,"title":{},"content":{"52":{},"161":{}},"tags":{}}],["privileg",{"_index":55,"title":{},"content":{"134":{}},"tags":{}}],["process",{"_index":179,"title":{},"content":{"19":{},"34":{},"46":{}},"tags":{}}],["product",{"_index":225,"title":{"21":{}},"content":{},"tags":{}}],["project",{"_index":11,"title":{},"content":{"17":{},"133":{}},"tags":{}}],["protect",{"_index":455,"title":{},"content":{"46":{}},"tags":{}}],["protocol",{"_index":136,"title":{"16":{},"33":{}},"content":{"32":{},"33":{}},"tags":{}}],["prove",{"_index":453,"title":{},"content":{"46":{}},"tags":{}}],["provid",{"_index":17,"title":{},"content":{"17":{},"19":{},"20":{},"21":{},"46":{},"133":{},"134":{},"135":{},"156":{}},"tags":{}}],["provider'",{"_index":200,"title":{},"content":{"19":{}},"tags":{}}],["proxi",{"_index":283,"title":{},"content":{"21":{}},"tags":{}}],["public",{"_index":271,"title":{},"content":{"21":{},"39":{},"42":{},"56":{},"156":{}},"tags":{}}],["pull",{"_index":467,"title":{},"content":{"50":{},"60":{}},"tags":{}}],["r",{"_index":316,"title":{},"content":{"36":{}},"tags":{}}],["readi",{"_index":612,"title":{},"content":{"158":{}},"tags":{}}],["receiv",{"_index":533,"title":{},"content":{"59":{},"61":{},"62":{},"161":{}},"tags":{}}],["refer",{"_index":337,"title":{},"content":{"37":{},"41":{},"50":{},"51":{},"54":{}},"tags":{}}],["referenc",{"_index":370,"title":{},"content":{"41":{},"54":{},"55":{}},"tags":{}}],["refresh",{"_index":571,"title":{},"content":{"156":{}},"tags":{}}],["regardless",{"_index":497,"title":{},"content":{"53":{}},"tags":{}}],["regist",{"_index":558,"title":{},"content":{"156":{}},"tags":{}}],["registr",{"_index":564,"title":{},"content":{"156":{}},"tags":{}}],["regulatori",{"_index":102,"title":{},"content":{"135":{}},"tags":{}}],["relat",{"_index":623,"title":{},"content":{"159":{}},"tags":{}}],["relay",{"_index":352,"title":{},"content":{"39":{}},"tags":{}}],["releas",{"_index":291,"title":{},"content":{"35":{},"39":{},"161":{}},"tags":{}}],["release_nam",{"_index":313,"title":{},"content":{"36":{}},"tags":{}}],["remot",{"_index":188,"title":{},"content":{"19":{},"21":{},"53":{}},"tags":{}}],["remov",{"_index":49,"title":{},"content":{"134":{}},"tags":{}}],["replica",{"_index":294,"title":{},"content":{"35":{},"49":{}},"tags":{}}],["report",{"_index":215,"title":{},"content":{"19":{},"52":{}},"tags":{}}],["requir",{"_index":189,"title":{},"content":{"19":{},"34":{},"46":{},"156":{}},"tags":{}}],["resourc",{"_index":213,"title":{"36":{},"38":{},"157":{}},"content":{"19":{},"36":{},"37":{},"38":{},"39":{},"40":{},"157":{},"158":{},"159":{}},"tags":{}}],["resources/all.yml",{"_index":311,"title":{},"content":{"36":{}},"tags":{}}],["restart",{"_index":544,"title":{},"content":{"60":{}},"tags":{}}],["retriev",{"_index":486,"title":{},"content":{"52":{}},"tags":{}}],["return",{"_index":488,"title":{},"content":{"52":{},"54":{},"60":{}},"tags":{}}],["right",{"_index":113,"title":{},"content":{"136":{}},"tags":{}}],["role",{"_index":607,"title":{},"content":{"158":{}},"tags":{}}],["roll",{"_index":540,"title":{"60":{}},"content":{"60":{}},"tags":{}}],["rollout",{"_index":543,"title":{},"content":{"60":{}},"tags":{}}],["root",{"_index":368,"title":{},"content":{"41":{},"42":{},"54":{},"57":{},"59":{}},"tags":{}}],["root.pem",{"_index":372,"title":{},"content":{"42":{},"54":{},"56":{},"57":{},"59":{},"60":{}},"tags":{}}],["rotat",{"_index":530,"title":{},"content":{"59":{}},"tags":{}}],["run",{"_index":3,"title":{},"content":{"19":{},"34":{},"37":{},"46":{},"47":{},"50":{},"54":{},"133":{},"159":{}},"tags":{}}],["runc",{"_index":170,"title":{},"content":{"18":{}},"tags":{}}],["runsc",{"_index":171,"title":{},"content":{"18":{}},"tags":{}}],["runtim",{"_index":131,"title":{"25":{},"147":{}},"content":{"17":{},"18":{},"19":{},"23":{},"24":{},"25":{},"26":{},"27":{},"39":{},"50":{},"158":{}},"tags":{}}],["runtimeclass",{"_index":155,"title":{"18":{}},"content":{"18":{}},"tags":{}}],["runtimeclassnam",{"_index":319,"title":{},"content":{"36":{}},"tags":{}}],["s_client",{"_index":418,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["saa",{"_index":99,"title":{},"content":{"135":{}},"tags":{}}],["same",{"_index":511,"title":{},"content":{"54":{}},"tags":{}}],["san",{"_index":404,"title":{"57":{},"58":{}},"content":{"42":{},"57":{},"58":{}},"tags":{}}],["sandbox",{"_index":142,"title":{},"content":{"17":{}},"tags":{}}],["scale",{"_index":8,"title":{},"content":{"21":{},"53":{},"133":{}},"tags":{}}],["screenshot",{"_index":425,"title":{},"content":{"43":{},"44":{}},"tags":{}}],["seamlessli",{"_index":227,"title":{},"content":{"21":{}},"tags":{}}],["second",{"_index":601,"title":{},"content":{"158":{}},"tags":{}}],["secret",{"_index":449,"title":{},"content":{"46":{}},"tags":{}}],["section",{"_index":111,"title":{},"content":{"58":{},"136":{}},"tags":{}}],["secur",{"_index":86,"title":{"22":{}},"content":{"21":{},"42":{},"52":{},"56":{},"59":{},"135":{},"136":{}},"tags":{}}],["see",{"_index":34,"title":{},"content":{"34":{},"47":{},"133":{}},"tags":{}}],["select",{"_index":587,"title":{},"content":{"157":{},"158":{}},"tags":{}}],["send",{"_index":485,"title":{},"content":{"52":{}},"tags":{}}],["sensit",{"_index":92,"title":{},"content":{"46":{},"135":{}},"tags":{}}],["separ",{"_index":307,"title":{},"content":{"36":{}},"tags":{}}],["server",{"_index":192,"title":{},"content":{"19":{}},"tags":{}}],["servic",{"_index":217,"title":{"58":{}},"content":{"20":{},"21":{},"35":{},"41":{},"42":{},"46":{},"49":{},"56":{},"59":{},"60":{}},"tags":{}}],["service/${my_servic",{"_index":384,"title":{},"content":{"42":{}},"tags":{}}],["set",{"_index":288,"title":{"40":{},"51":{}},"content":{"34":{},"38":{},"40":{},"51":{},"52":{},"59":{},"60":{},"157":{}},"tags":{}}],["setup",{"_index":246,"title":{"63":{}},"content":{"21":{},"34":{},"47":{},"61":{}},"tags":{}}],["shield",{"_index":95,"title":{},"content":{"19":{},"21":{},"135":{}},"tags":{}}],["shift",{"_index":26,"title":{},"content":{"133":{}},"tags":{}}],["shim",{"_index":348,"title":{},"content":{"39":{}},"tags":{}}],["ship",{"_index":464,"title":{},"content":{"50":{}},"tags":{}}],["show",{"_index":566,"title":{},"content":{"156":{},"158":{}},"tags":{}}],["sidecar",{"_index":138,"title":{"32":{},"153":{}},"content":{"32":{},"33":{}},"tags":{}}],["signal",{"_index":466,"title":{},"content":{"50":{}},"tags":{}}],["simplifi",{"_index":101,"title":{},"content":{"21":{},"135":{}},"tags":{}}],["simul",{"_index":444,"title":{},"content":{"45":{}},"tags":{}}],["singl",{"_index":293,"title":{},"content":{"35":{},"49":{},"53":{}},"tags":{}}],["site",{"_index":549,"title":{},"content":{"60":{}},"tags":{}}],["size",{"_index":597,"title":{},"content":{"158":{}},"tags":{}}],["sku",{"_index":595,"title":{},"content":{"158":{}},"tags":{}}],["sleep",{"_index":388,"title":{},"content":{"42":{}},"tags":{}}],["socket",{"_index":198,"title":{},"content":{"19":{}},"tags":{}}],["spawn",{"_index":177,"title":{},"content":{"19":{}},"tags":{}}],["spec",{"_index":321,"title":{},"content":{"36":{},"42":{}},"tags":{}}],["specif",{"_index":273,"title":{},"content":{"21":{},"46":{}},"tags":{}}],["specifi",{"_index":317,"title":{},"content":{"36":{}},"tags":{}}],["ssh",{"_index":600,"title":{},"content":{"158":{}},"tags":{}}],["ssl",{"_index":414,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["stabl",{"_index":153,"title":{},"content":{"17":{}},"tags":{}}],["stack",{"_index":222,"title":{},"content":{"20":{}},"tags":{}}],["standard",{"_index":144,"title":{},"content":{"17":{}},"tags":{}}],["standard_dc4as_cc_v5",{"_index":598,"title":{},"content":{"158":{}},"tags":{}}],["start",{"_index":117,"title":{"61":{}},"content":{"40":{},"50":{},"136":{}},"tags":{}}],["state",{"_index":567,"title":{},"content":{"156":{}},"tags":{}}],["statement",{"_index":258,"title":{},"content":{"21":{}},"tags":{}}],["statu",{"_index":565,"title":{},"content":{"156":{},"158":{}},"tags":{}}],["step",{"_index":108,"title":{"48":{},"64":{},"136":{},"160":{}},"content":{"34":{},"39":{},"40":{},"53":{},"55":{},"61":{},"159":{}},"tags":{}}],["still",{"_index":151,"title":{},"content":{"17":{},"60":{}},"tags":{}}],["store",{"_index":510,"title":{},"content":{"54":{}},"tags":{}}],["straightforward",{"_index":248,"title":{},"content":{"21":{}},"tags":{}}],["strong",{"_index":18,"title":{},"content":{"133":{}},"tags":{}}],["subject",{"_index":392,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["submit",{"_index":445,"title":{},"content":{"45":{}},"tags":{}}],["subscript",{"_index":560,"title":{},"content":{"156":{}},"tags":{}}],["succe",{"_index":477,"title":{},"content":{"51":{},"54":{}},"tags":{}}],["success",{"_index":503,"title":{},"content":{"53":{}},"tags":{}}],["successfulli",{"_index":484,"title":{},"content":{"52":{},"54":{},"60":{}},"tags":{}}],["such",{"_index":169,"title":{},"content":{"18":{},"21":{},"156":{}},"tags":{}}],["support",{"_index":193,"title":{},"content":{"19":{},"21":{},"39":{},"47":{},"158":{}},"tags":{}}],["sure",{"_index":506,"title":{},"content":{"53":{}},"tags":{}}],["surround",{"_index":21,"title":{},"content":{"133":{}},"tags":{}}],["svc",{"_index":342,"title":{},"content":{"39":{},"42":{},"51":{},"56":{}},"tags":{}}],["switzerlandnorth",{"_index":581,"title":{},"content":{"157":{}},"tags":{}}],["system",{"_index":501,"title":{},"content":{"53":{}},"tags":{}}],["tabl",{"_index":569,"title":{},"content":{"156":{}},"tags":{}}],["take",{"_index":470,"title":{},"content":{"51":{},"156":{}},"tags":{}}],["talk",{"_index":490,"title":{},"content":{"52":{}},"tags":{}}],["tamper",{"_index":480,"title":{},"content":{"51":{}},"tags":{}}],["target",{"_index":29,"title":{},"content":{"42":{},"57":{},"133":{}},"tags":{}}],["task",{"_index":516,"title":{},"content":{"55":{}},"tags":{}}],["tcb",{"_index":51,"title":{},"content":{"134":{}},"tags":{}}],["templat",{"_index":312,"title":{},"content":{"36":{}},"tags":{}}],["tenant",{"_index":66,"title":{},"content":{"134":{}},"tags":{}}],["termin",{"_index":542,"title":{},"content":{"60":{}},"tags":{}}],["those",{"_index":454,"title":{},"content":{"46":{},"53":{}},"tags":{}}],["through",{"_index":62,"title":{},"content":{"19":{},"34":{},"45":{},"134":{}},"tags":{}}],["throw",{"_index":408,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["thu",{"_index":531,"title":{},"content":{"59":{}},"tags":{}}],["timeout",{"_index":381,"title":{},"content":{"42":{}},"tags":{}}],["tip",{"_index":33,"title":{},"content":{"133":{}},"tags":{}}],["tl",{"_index":277,"title":{},"content":{"21":{},"36":{},"40":{},"51":{},"54":{}},"tags":{}}],["togeth",{"_index":287,"title":{},"content":{"34":{}},"tags":{}}],["tool",{"_index":401,"title":{},"content":{"42":{},"57":{},"58":{}},"tags":{}}],["track",{"_index":356,"title":{},"content":{"39":{}},"tags":{}}],["traffic",{"_index":353,"title":{},"content":{"39":{},"45":{}},"tags":{}}],["transit",{"_index":500,"title":{},"content":{"53":{}},"tags":{}}],["transpar",{"_index":275,"title":{},"content":{"21":{}},"tags":{}}],["tri",{"_index":619,"title":{},"content":{"159":{}},"tags":{}}],["true",{"_index":557,"title":{},"content":{"156":{}},"tags":{}}],["trust",{"_index":50,"title":{},"content":{"42":{},"55":{},"56":{},"59":{},"134":{}},"tags":{}}],["trustworthi",{"_index":98,"title":{},"content":{"135":{}},"tags":{}}],["tunnel",{"_index":199,"title":{},"content":{"19":{}},"tags":{}}],["tutori",{"_index":428,"title":{},"content":{"45":{}},"tags":{}}],["two",{"_index":183,"title":{},"content":{"19":{},"158":{}},"tags":{}}],["type",{"_index":221,"title":{},"content":{"20":{},"42":{}},"tags":{}}],["uaenorth",{"_index":582,"title":{},"content":{"157":{}},"tags":{}}],["ui",{"_index":427,"title":{},"content":{"43":{},"44":{}},"tags":{}}],["unchang",{"_index":305,"title":{},"content":{"36":{}},"tags":{}}],["under",{"_index":146,"title":{},"content":{"17":{}},"tags":{}}],["underli",{"_index":203,"title":{},"content":{"19":{},"21":{}},"tags":{}}],["uniqu",{"_index":85,"title":{},"content":{"135":{}},"tags":{}}],["unmodifi",{"_index":24,"title":{},"content":{"133":{}},"tags":{}}],["unpack",{"_index":625,"title":{},"content":{"161":{}},"tags":{}}],["until",{"_index":339,"title":{},"content":{"38":{},"42":{}},"tags":{}}],["unzip",{"_index":627,"title":{},"content":{"161":{}},"tags":{}}],["up",{"_index":289,"title":{},"content":{"34":{},"51":{},"159":{}},"tags":{}}],["updat",{"_index":265,"title":{"57":{},"59":{},"60":{}},"content":{"21":{},"59":{},"60":{},"156":{},"158":{}},"tags":{}}],["upstream",{"_index":355,"title":{},"content":{"39":{}},"tags":{}}],["url",{"_index":551,"title":{},"content":{"61":{},"62":{},"161":{}},"tags":{}}],["us",{"_index":83,"title":{"135":{},"156":{}},"content":{"17":{},"18":{},"19":{},"21":{},"36":{},"39":{},"41":{},"42":{},"46":{},"50":{},"51":{},"52":{},"54":{},"56":{},"57":{},"60":{},"135":{},"157":{},"158":{}},"tags":{}}],["user",{"_index":364,"title":{},"content":{"41":{},"45":{},"46":{},"51":{}},"tags":{}}],["usr/local/bin/contrast",{"_index":633,"title":{},"content":{"161":{}},"tags":{}}],["usual",{"_index":167,"title":{},"content":{"18":{}},"tags":{}}],["v1.29.0",{"_index":615,"title":{},"content":{"158":{}},"tags":{}}],["v1.podspec",{"_index":327,"title":{},"content":{"36":{}},"tags":{}}],["valid",{"_index":269,"title":{},"content":{"21":{},"42":{},"45":{},"52":{},"56":{},"57":{},"60":{},"158":{}},"tags":{}}],["valu",{"_index":331,"title":{},"content":{"36":{},"37":{},"41":{},"50":{},"51":{},"54":{}},"tags":{}}],["verif",{"_index":504,"title":{},"content":{"53":{},"58":{}},"tags":{}}],["verifi",{"_index":259,"title":{"41":{},"53":{}},"content":{"21":{},"41":{},"53":{},"54":{},"55":{}},"tags":{}}],["verify/mesh",{"_index":411,"title":{},"content":{"42":{},"56":{},"57":{}},"tags":{}}],["verify_return_error",{"_index":420,"title":{},"content":{"42":{},"56":{}},"tags":{}}],["version",{"_index":489,"title":{},"content":{"52":{},"54":{},"155":{},"158":{}},"tags":{}}],["via",{"_index":354,"title":{},"content":{"39":{},"42":{},"52":{},"56":{},"57":{}},"tags":{}}],["view",{"_index":433,"title":{},"content":{"45":{}},"tags":{}}],["virtual",{"_index":195,"title":{},"content":{"19":{},"20":{}},"tags":{}}],["visit",{"_index":521,"title":{},"content":{"56":{}},"tags":{}}],["vm",{"_index":16,"title":{"24":{},"146":{}},"content":{"19":{},"20":{},"23":{},"24":{},"25":{},"26":{},"27":{},"133":{},"158":{}},"tags":{}}],["vmss000000",{"_index":611,"title":{},"content":{"158":{}},"tags":{}}],["volum",{"_index":334,"title":{},"content":{"36":{}},"tags":{}}],["volumemount",{"_index":324,"title":{},"content":{"36":{},"52":{}},"tags":{}}],["vote",{"_index":424,"title":{"44":{},"45":{}},"content":{"43":{},"45":{},"46":{},"53":{},"60":{}},"tags":{}}],["voter",{"_index":429,"title":{},"content":{"45":{},"53":{},"54":{},"55":{}},"tags":{}}],["voter'",{"_index":495,"title":{"53":{}},"content":{},"tags":{}}],["want",{"_index":304,"title":{},"content":{"36":{},"53":{},"157":{},"159":{}},"tags":{}}],["way",{"_index":537,"title":{},"content":{"59":{}},"tags":{}}],["we'r",{"_index":478,"title":{},"content":{"51":{},"52":{}},"tags":{}}],["web",{"_index":398,"title":{},"content":{"42":{},"45":{},"56":{},"57":{},"58":{}},"tags":{}}],["welcom",{"_index":1,"title":{},"content":{"133":{}},"tags":{}}],["westeurop",{"_index":583,"title":{},"content":{"157":{}},"tags":{}}],["westu",{"_index":584,"title":{},"content":{"157":{}},"tags":{}}],["whitepap",{"_index":35,"title":{},"content":{"133":{}},"tags":{}}],["wildcard",{"_index":395,"title":{},"content":{"42":{},"57":{}},"tags":{}}],["within",{"_index":245,"title":{},"content":{"21":{}},"tags":{}}],["without",{"_index":456,"title":{},"content":{"46":{}},"tags":{}}],["won't",{"_index":536,"title":{},"content":{"59":{},"60":{}},"tags":{}}],["work",{"_index":23,"title":{},"content":{"133":{}},"tags":{}}],["workflow",{"_index":71,"title":{},"content":{"134":{}},"tags":{}}],["workload",{"_index":93,"title":{"34":{},"42":{},"56":{}},"content":{"21":{},"36":{},"38":{},"40":{},"42":{},"46":{},"50":{},"52":{},"56":{},"59":{},"135":{},"158":{}},"tags":{}}],["write",{"_index":367,"title":{},"content":{"41":{},"52":{}},"tags":{}}],["written",{"_index":323,"title":{},"content":{"36":{},"41":{},"54":{},"55":{}},"tags":{}}],["yaml",{"_index":249,"title":{},"content":{"21":{},"36":{},"50":{}},"tags":{}}],["you'v",{"_index":621,"title":{},"content":{"159":{}},"tags":{}}]],"pipeline":["stemmer"]}} \ No newline at end of file diff --git a/pr-preview/pr-976/search-index-docs-default-0.6.json b/pr-preview/pr-976/search-index-docs-default-0.6.json new file mode 100644 index 0000000000..f830e2a01b --- /dev/null +++ b/pr-preview/pr-976/search-index-docs-default-0.6.json @@ -0,0 +1 @@ +{"documents":[{"id":162,"pageTitle":"Contrast","sectionTitle":"Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.6","type":"docs"},{"id":163,"pageTitle":"Contrast","sectionTitle":"Goal","sectionRoute":"/contrast/pr-preview/pr-976/0.6#goal","type":"docs"},{"id":164,"pageTitle":"Contrast","sectionTitle":"Use Cases","sectionRoute":"/contrast/pr-preview/pr-976/0.6#use-cases","type":"docs"},{"id":165,"pageTitle":"Contrast","sectionTitle":"Next steps","sectionRoute":"/contrast/pr-preview/pr-976/0.6#next-steps","type":"docs"},{"id":166,"pageTitle":"About","sectionTitle":"About","sectionRoute":"/contrast/pr-preview/pr-976/0.6/about","type":"docs"},{"id":167,"pageTitle":"About","sectionTitle":"📄️ Telemetry","sectionRoute":"/contrast/pr-preview/pr-976/0.6/about","type":"docs"},{"id":168,"pageTitle":"CLI telemetry","sectionTitle":"CLI telemetry","sectionRoute":"/contrast/pr-preview/pr-976/0.6/about/telemetry","type":"docs"},{"id":169,"pageTitle":"Architecture","sectionTitle":"Architecture","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture","type":"docs"},{"id":170,"pageTitle":"Architecture","sectionTitle":"📄️ Attestation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture","type":"docs"},{"id":171,"pageTitle":"Architecture","sectionTitle":"📄️ Certificate authority","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture","type":"docs"},{"id":172,"pageTitle":"Attestation in Contrast","sectionTitle":"Attestation in Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation","type":"docs"},{"id":173,"pageTitle":"Attestation in Contrast","sectionTitle":"Attestation architecture","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#attestation-architecture","type":"docs"},{"id":174,"pageTitle":"Attestation in Contrast","sectionTitle":"Components of Contrast's attestation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#components-of-contrasts-attestation","type":"docs"},{"id":175,"pageTitle":"Attestation in Contrast","sectionTitle":"Attester: Application Pods","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#attester-application-pods","type":"docs"},{"id":176,"pageTitle":"Attestation in Contrast","sectionTitle":"Verifier: Coordinator and CLI","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#verifier-coordinator-and-cli","type":"docs"},{"id":177,"pageTitle":"Attestation in Contrast","sectionTitle":"Relying Party: Data owner","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#relying-party-data-owner","type":"docs"},{"id":178,"pageTitle":"Attestation in Contrast","sectionTitle":"Evidence generation and appraisal","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#evidence-generation-and-appraisal","type":"docs"},{"id":179,"pageTitle":"Attestation in Contrast","sectionTitle":"Evidence types and formats","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#evidence-types-and-formats","type":"docs"},{"id":180,"pageTitle":"Attestation in Contrast","sectionTitle":"Appraisal policies for evidence","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#appraisal-policies-for-evidence","type":"docs"},{"id":181,"pageTitle":"Attestation in Contrast","sectionTitle":"Frequently asked questions about attestation in Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#frequently-asked-questions-about-attestation-in-contrast","type":"docs"},{"id":182,"pageTitle":"Attestation in Contrast","sectionTitle":"What's the purpose of remote attestation in Contrast?","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#whats-the-purpose-of-remote-attestation-in-contrast","type":"docs"},{"id":183,"pageTitle":"Attestation in Contrast","sectionTitle":"How does Contrast ensure the security of the attestation process?","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#how-does-contrast-ensure-the-security-of-the-attestation-process","type":"docs"},{"id":184,"pageTitle":"Attestation in Contrast","sectionTitle":"What security benefits does attestation provide?","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#what-security-benefits-does-attestation-provide","type":"docs"},{"id":185,"pageTitle":"Attestation in Contrast","sectionTitle":"How can you verify the authenticity of attestation results?","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#how-can-you-verify-the-authenticity-of-attestation-results","type":"docs"},{"id":186,"pageTitle":"Attestation in Contrast","sectionTitle":"How are attestation results used by relying parties?","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#how-are-attestation-results-used-by-relying-parties","type":"docs"},{"id":187,"pageTitle":"Attestation in Contrast","sectionTitle":"Summary","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/attestation#summary","type":"docs"},{"id":188,"pageTitle":"Certificate authority","sectionTitle":"Certificate authority","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/certificates","type":"docs"},{"id":189,"pageTitle":"Certificate authority","sectionTitle":"Public key infrastructure","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/certificates#public-key-infrastructure","type":"docs"},{"id":190,"pageTitle":"Certificate authority","sectionTitle":"Certificate rotation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/certificates#certificate-rotation","type":"docs"},{"id":191,"pageTitle":"Certificate authority","sectionTitle":"Usage of the different certificates","sectionRoute":"/contrast/pr-preview/pr-976/0.6/architecture/certificates#usage-of-the-different-certificates","type":"docs"},{"id":192,"pageTitle":"Confidential Containers","sectionTitle":"Confidential Containers","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers","type":"docs"},{"id":193,"pageTitle":"Confidential Containers","sectionTitle":"Kubernetes RuntimeClass","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers#kubernetes-runtimeclass","type":"docs"},{"id":194,"pageTitle":"Confidential Containers","sectionTitle":"Kata Containers","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers#kata-containers","type":"docs"},{"id":195,"pageTitle":"Confidential Containers","sectionTitle":"AKS CoCo preview","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/confidential-containers#aks-coco-preview","type":"docs"},{"id":196,"pageTitle":"Product features","sectionTitle":"Product features","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/features","type":"docs"},{"id":197,"pageTitle":"Contrast security overview","sectionTitle":"Contrast security overview","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits","type":"docs"},{"id":198,"pageTitle":"Contrast security overview","sectionTitle":"Confidential computing foundation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#confidential-computing-foundation","type":"docs"},{"id":199,"pageTitle":"Contrast security overview","sectionTitle":"Components of a Contrast deployment","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#components-of-a-contrast-deployment","type":"docs"},{"id":200,"pageTitle":"Contrast security overview","sectionTitle":"Personas in a Contrast deployment","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#personas-in-a-contrast-deployment","type":"docs"},{"id":201,"pageTitle":"Contrast security overview","sectionTitle":"Threat model and mitigations","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#threat-model-and-mitigations","type":"docs"},{"id":202,"pageTitle":"Contrast security overview","sectionTitle":"Possible attacks","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#possible-attacks","type":"docs"},{"id":203,"pageTitle":"Contrast security overview","sectionTitle":"Attack surfaces","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#attack-surfaces","type":"docs"},{"id":204,"pageTitle":"Contrast security overview","sectionTitle":"Threats and mitigations","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#threats-and-mitigations","type":"docs"},{"id":205,"pageTitle":"Contrast security overview","sectionTitle":"Examples of Contrast's threat model in practice","sectionRoute":"/contrast/pr-preview/pr-976/0.6/basics/security-benefits#examples-of-contrasts-threat-model-in-practice","type":"docs"},{"id":206,"pageTitle":"Components","sectionTitle":"Components","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components","type":"docs"},{"id":207,"pageTitle":"Components","sectionTitle":"The CLI (Command Line Interface)","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#the-cli-command-line-interface","type":"docs"},{"id":208,"pageTitle":"Components","sectionTitle":"The Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#the-coordinator","type":"docs"},{"id":209,"pageTitle":"Components","sectionTitle":"The Manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#the-manifest","type":"docs"},{"id":210,"pageTitle":"Components","sectionTitle":"Runtime policies","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#runtime-policies","type":"docs"},{"id":211,"pageTitle":"Components","sectionTitle":"The Initializer","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#the-initializer","type":"docs"},{"id":212,"pageTitle":"Components","sectionTitle":"The Contrast runtime","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components#the-contrast-runtime","type":"docs"},{"id":213,"pageTitle":"Policies","sectionTitle":"Policies","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies","type":"docs"},{"id":214,"pageTitle":"Policies","sectionTitle":"Structure","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies#structure","type":"docs"},{"id":215,"pageTitle":"Policies","sectionTitle":"Generation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies#generation","type":"docs"},{"id":216,"pageTitle":"Policies","sectionTitle":"Evaluation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies#evaluation","type":"docs"},{"id":217,"pageTitle":"Policies","sectionTitle":"Guarantees","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies#guarantees","type":"docs"},{"id":218,"pageTitle":"Policies","sectionTitle":"Trust","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/policies#trust","type":"docs"},{"id":219,"pageTitle":"Contrast Runtime","sectionTitle":"Contrast Runtime","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime","type":"docs"},{"id":220,"pageTitle":"Contrast Runtime","sectionTitle":"Node-level components","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#node-level-components","type":"docs"},{"id":221,"pageTitle":"Contrast Runtime","sectionTitle":"Containerd shim","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#containerd-shim","type":"docs"},{"id":222,"pageTitle":"Contrast Runtime","sectionTitle":"cloud-hypervisor virtual machine manager (VMM)","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#cloud-hypervisor-virtual-machine-manager-vmm","type":"docs"},{"id":223,"pageTitle":"Contrast Runtime","sectionTitle":"Tardev snapshotter","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#tardev-snapshotter","type":"docs"},{"id":224,"pageTitle":"Contrast Runtime","sectionTitle":"Pod-VM image","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#pod-vm-image","type":"docs"},{"id":225,"pageTitle":"Contrast Runtime","sectionTitle":"Node installer DaemonSet","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/runtime#node-installer-daemonset","type":"docs"},{"id":226,"pageTitle":"Service Mesh","sectionTitle":"Service Mesh","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/service-mesh","type":"docs"},{"id":227,"pageTitle":"Service Mesh","sectionTitle":"Configuring the Proxy","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/service-mesh#configuring-the-proxy","type":"docs"},{"id":228,"pageTitle":"Service Mesh","sectionTitle":"Ingress","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/service-mesh#ingress","type":"docs"},{"id":229,"pageTitle":"Service Mesh","sectionTitle":"Egress","sectionRoute":"/contrast/pr-preview/pr-976/0.6/components/service-mesh#egress","type":"docs"},{"id":230,"pageTitle":"Workload deployment","sectionTitle":"Workload deployment","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment","type":"docs"},{"id":231,"pageTitle":"Workload deployment","sectionTitle":"Deploy the Contrast runtime","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#deploy-the-contrast-runtime","type":"docs"},{"id":232,"pageTitle":"Workload deployment","sectionTitle":"Deploy the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#deploy-the-contrast-coordinator","type":"docs"},{"id":233,"pageTitle":"Workload deployment","sectionTitle":"Prepare your Kubernetes resources","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#prepare-your-kubernetes-resources","type":"docs"},{"id":234,"pageTitle":"Workload deployment","sectionTitle":"RuntimeClass and Initializer","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#runtimeclass-and-initializer","type":"docs"},{"id":235,"pageTitle":"Workload deployment","sectionTitle":"Handling TLS","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#handling-tls","type":"docs"},{"id":236,"pageTitle":"Workload deployment","sectionTitle":"Generate policy annotations and manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#generate-policy-annotations-and-manifest","type":"docs"},{"id":237,"pageTitle":"Workload deployment","sectionTitle":"Apply the resources","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#apply-the-resources","type":"docs"},{"id":238,"pageTitle":"Workload deployment","sectionTitle":"Connect to the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#connect-to-the-contrast-coordinator","type":"docs"},{"id":239,"pageTitle":"Workload deployment","sectionTitle":"Set the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#set-the-manifest","type":"docs"},{"id":240,"pageTitle":"Workload deployment","sectionTitle":"Verify the Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#verify-the-coordinator","type":"docs"},{"id":241,"pageTitle":"Workload deployment","sectionTitle":"Communicate with workloads","sectionRoute":"/contrast/pr-preview/pr-976/0.6/deployment#communicate-with-workloads","type":"docs"},{"id":242,"pageTitle":"Examples","sectionTitle":"Examples","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples","type":"docs"},{"id":243,"pageTitle":"Examples","sectionTitle":"📄️ Confidential emoji voting","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples","type":"docs"},{"id":244,"pageTitle":"Confidential emoji voting","sectionTitle":"Confidential emoji voting","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto","type":"docs"},{"id":245,"pageTitle":"Confidential emoji voting","sectionTitle":"Motivation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#motivation","type":"docs"},{"id":246,"pageTitle":"Confidential emoji voting","sectionTitle":"Prerequisites","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#prerequisites","type":"docs"},{"id":247,"pageTitle":"Confidential emoji voting","sectionTitle":"Steps to deploy emojivoto with Contrast","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#steps-to-deploy-emojivoto-with-contrast","type":"docs"},{"id":248,"pageTitle":"Confidential emoji voting","sectionTitle":"Downloading the deployment","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#downloading-the-deployment","type":"docs"},{"id":249,"pageTitle":"Confidential emoji voting","sectionTitle":"Deploy the Contrast runtime","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#deploy-the-contrast-runtime","type":"docs"},{"id":250,"pageTitle":"Confidential emoji voting","sectionTitle":"Deploy the Contrast Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#deploy-the-contrast-coordinator","type":"docs"},{"id":251,"pageTitle":"Confidential emoji voting","sectionTitle":"Generate policy annotations and manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#generate-policy-annotations-and-manifest","type":"docs"},{"id":252,"pageTitle":"Confidential emoji voting","sectionTitle":"Set the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#set-the-manifest","type":"docs"},{"id":253,"pageTitle":"Confidential emoji voting","sectionTitle":"Deploy emojivoto","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#deploy-emojivoto","type":"docs"},{"id":254,"pageTitle":"Confidential emoji voting","sectionTitle":"Voter's perspective: Verifying the ballot","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#voters-perspective-verifying-the-ballot","type":"docs"},{"id":255,"pageTitle":"Confidential emoji voting","sectionTitle":"Attest the Coordinator","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#attest-the-coordinator","type":"docs"},{"id":256,"pageTitle":"Confidential emoji voting","sectionTitle":"Manifest history and artifact audit","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#manifest-history-and-artifact-audit","type":"docs"},{"id":257,"pageTitle":"Confidential emoji voting","sectionTitle":"Confidential connection to the attested workload","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#confidential-connection-to-the-attested-workload","type":"docs"},{"id":258,"pageTitle":"Confidential emoji voting","sectionTitle":"Certificate SAN and manifest update (optional)","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#certificate-san-and-manifest-update-optional","type":"docs"},{"id":259,"pageTitle":"Confidential emoji voting","sectionTitle":"Configure the service SAN in the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#configure-the-service-san-in-the-manifest","type":"docs"},{"id":260,"pageTitle":"Confidential emoji voting","sectionTitle":"Update the manifest","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#update-the-manifest","type":"docs"},{"id":261,"pageTitle":"Confidential emoji voting","sectionTitle":"Rolling out the update","sectionRoute":"/contrast/pr-preview/pr-976/0.6/examples/emojivoto#rolling-out-the-update","type":"docs"},{"id":262,"pageTitle":"Getting started","sectionTitle":"Getting started","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started","type":"docs"},{"id":263,"pageTitle":"Getting started","sectionTitle":"📄️ Install","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started","type":"docs"},{"id":264,"pageTitle":"Getting started","sectionTitle":"📄️ Cluster setup","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started","type":"docs"},{"id":265,"pageTitle":"Create a cluster","sectionTitle":"Create a cluster","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup","type":"docs"},{"id":266,"pageTitle":"Create a cluster","sectionTitle":"Prerequisites","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup#prerequisites","type":"docs"},{"id":267,"pageTitle":"Create a cluster","sectionTitle":"Prepare using the AKS preview","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup#prepare-using-the-aks-preview","type":"docs"},{"id":268,"pageTitle":"Create a cluster","sectionTitle":"Create resource group","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup#create-resource-group","type":"docs"},{"id":269,"pageTitle":"Create a cluster","sectionTitle":"Create AKS cluster","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup#create-aks-cluster","type":"docs"},{"id":270,"pageTitle":"Create a cluster","sectionTitle":"Cleanup","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setup#cleanup","type":"docs"},{"id":271,"pageTitle":"Installation","sectionTitle":"Installation","sectionRoute":"/contrast/pr-preview/pr-976/0.6/getting-started/install","type":"docs"},{"id":272,"pageTitle":"Known Limitations","sectionTitle":"Known Limitations","sectionRoute":"/contrast/pr-preview/pr-976/0.6/known-limitations","type":"docs"},{"id":273,"pageTitle":"Known Limitations","sectionTitle":"Availability","sectionRoute":"/contrast/pr-preview/pr-976/0.6/known-limitations#availability","type":"docs"},{"id":274,"pageTitle":"Known Limitations","sectionTitle":"Kubernetes Features","sectionRoute":"/contrast/pr-preview/pr-976/0.6/known-limitations#kubernetes-features","type":"docs"},{"id":275,"pageTitle":"Known Limitations","sectionTitle":"Runtime Policies","sectionRoute":"/contrast/pr-preview/pr-976/0.6/known-limitations#runtime-policies","type":"docs"},{"id":276,"pageTitle":"Known Limitations","sectionTitle":"Tooling Integration","sectionRoute":"/contrast/pr-preview/pr-976/0.6/known-limitations#tooling-integration","type":"docs"}],"index":{"version":"2.3.9","fields":["title","content","tags"],"fieldVectors":[["title/162",[0,0.299]],["content/162",[0,0.393,1,4.629,2,2.372,3,1.746,4,1.472,5,1.508,6,0.729,7,1.74,8,3.068,9,3.197,10,2.014,11,3.246,12,1.355,13,3.068,14,2.558,15,3.068,16,2.143,17,1.261,18,4.629,19,2.372,20,3.068,21,4.629,22,1.655,23,3.727,24,4.629,25,4.629,26,4.629,27,3.727,28,2.29,29,3.246,30,2.664,31,2.783,32,2.214,33,4.629,34,3.068,35,4.086,36,2.461,37,2.29,38,2.29]],["tags/162",[]],["title/163",[39,5.064]],["content/163",[0,0.32,6,0.714,7,1.715,9,2.322,17,1.234,38,2.242,40,2.855,41,4,42,1.621,43,3.387,44,3.178,45,3.649,46,2.847,47,3.711,48,3.004,49,4,50,2.242,51,3.649,52,2.168,53,3.649,54,4,55,4.597,56,1.972,57,4.532,58,1.579,59,3.387,60,2.724,61,4.532,62,2.409,63,2.033,64,3.004,65,3.387,66,3.178,67,4.532,68,1.621,69,4.532,70,3.178,71,4.532,72,2.608,73,4,74,2.242,75,1.914,76,4,77,3.649,78,2.242,79,4.532,80,4,81,2.608,82,3.649]],["tags/163",[]],["title/164",[83,0.778,84,2.962]],["content/164",[0,0.27,4,0.968,5,0.991,17,1.412,38,3.326,42,2.405,56,2.255,58,1.806,59,3.874,83,0.858,84,3.265,85,5.184,86,2.405,87,2.756,88,3.436,89,4.174,90,5.934,91,5.184,92,3.265,93,1.09,94,5.184,95,3.635,96,3.436,97,4.174,98,3.635,99,4.575,100,3.635,101,4.174,102,4.575,103,4.174,104,4.575,105,2.479,106,5.184]],["tags/164",[]],["title/165",[107,3.515,108,2.41]],["content/165",[0,0.324,4,1.163,5,1.191,36,3.311,86,2.227,87,3.311,88,4.128,109,6.229,110,5.497,111,3.744,112,6.229,113,6.229,114,5.497,115,6.229,116,5.497,117,3.081]],["tags/165",[]],["title/166",[]],["content/166",[0,0.337,42,2.316,83,1.072,118,2.316,119,5.416,120,2.762,121,4.08,122,5.215,123,3.893,124,2.998]],["tags/166",[]],["title/167",[118,1.682,119,3.298]],["content/167",[0,0.344,42,2.363,83,1.093,119,4.634,120,2.796,121,4.163,122,5.321,123,3.973,124,3.059]],["tags/167",[]],["title/168",[119,3.298,120,1.682]],["content/168",[0,0.307,3,2.225,22,1.525,29,2.99,37,2.109,42,2.419,83,0.976,86,1.525,92,2.686,119,4.136,120,2.961,121,3.716,122,4.75,123,3.546,124,2.731,125,2.039,126,3.763,127,4.264,128,1.566,129,2.356,130,3.433,131,2.356,132,4.264,133,4.264,134,3.187,135,3.187,136,4.264,137,2.99,138,5.206,139,2.563,140,3.433,141,2.826,142,3.763,143,2.99,144,2.826,145,1.974,146,3.763,147,3.763,148,2.826,149,3.763,150,1.134,151,3.763,152,1.653,153,2.563,154,4.264,155,2.686]],["tags/168",[]],["title/169",[131,3.17]],["content/169",[0,0.301,2,2.964,93,1.216,118,2.578,131,3.196,148,3.834,156,1.365,157,3.196,158,3.075,159,2.678,160,3.643,161,3.834,162,3.834,163,3.834,164,1.963,165,3.694,166,1.275,167,3.477,168,2.594]],["tags/169",[]],["title/170",[118,1.682,156,0.817]],["content/170",[0,0.334,2,3.286,131,3.543,148,4.25,156,1.334,157,3.543,158,3.409,159,2.969,160,4.039,161,4.25,162,4.25,163,4.25]],["tags/170",[]],["title/171",[118,1.425,164,1.085,165,2.041]],["content/171",[93,1.448,164,1.876,165,3.53,166,1.518,167,4.141,168,3.09]],["tags/171",[]],["title/172",[0,0.245,156,0.817]],["content/172",[0,0.281,2,3.537,52,2.582,86,1.931,88,3.579,128,1.983,131,3.814,148,3.579,156,1.393,157,2.983,158,2.87,159,2.499,160,3.401,161,3.579,162,3.579,163,3.579,169,5.4,170,3.107,171,4.765,172,2.87,173,4.347,174,5.4,175,5.4,176,5.4,177,4.765,178,5.4,179,5.4]],["tags/172",[]],["title/173",[131,2.598,156,0.817]],["content/173",[0,0.179,17,0.934,52,1.641,62,2.684,68,1.227,83,0.568,98,2.405,105,3.37,128,1.26,131,2.79,141,2.274,145,2.338,150,1.758,156,1.358,158,1.823,161,2.274,162,2.274,163,2.274,165,1.758,180,2.405,181,2.564,182,2.321,183,4.438,184,2.762,185,2.564,186,3.431,187,3.431,188,5.05,189,4.202,190,2.762,191,1.448,192,3.514,193,3.431,194,5.05,195,2.684,196,1.539,197,3.027,198,5.05,199,2.79,200,4.438,201,1.294,202,3.973,203,3.186,204,3.431,205,3.431,206,3.027,207,2.161,208,2.062,209,4.457,210,1.641,211,1.08,212,2.405,213,2.762,214,3.027,215,2.161]],["tags/173",[]],["title/174",[156,0.692,172,2.118,216,1.682]],["content/174",[0,0.351,145,3.123,156,1.172,170,3.883,216,2.848,217,3.457,218,5.042,219,5.954]],["tags/174",[]],["title/175",[12,1.166,156,0.692,220,2.041]],["content/175",[0,0.129,3,1.488,4,1.138,5,1.068,6,0.621,7,0.693,9,1.273,10,1.081,12,1.898,14,1.373,16,2.586,17,1.074,19,1.273,22,1.998,28,1.229,37,1.229,48,1.647,52,2.346,68,0.889,77,2.001,82,2.001,111,1.494,150,1.808,156,1.059,160,1.565,162,1.647,163,1.647,170,1.43,172,2.097,182,0.782,184,2.001,192,3.749,200,1.565,201,1.85,211,0.782,216,1.049,219,2.193,221,1.857,222,2.193,223,1.647,224,2.969,225,3.44,226,4.498,227,2.001,228,2.193,229,1.57,230,2.485,231,1.647,232,1.229,233,2.823,234,2.766,235,1.618,236,1.43,237,2.001,238,1.529,239,2.001,240,1.857,241,2.193,242,2.193,243,1.15,244,1.494,245,1.565,246,3.666,247,2.193,248,3.945,249,2.949,250,1.742,251,1.647,252,1.019,253,2.948,254,2.001,255,3.251,256,2.71,257,1.647,258,2.485,259,1.857,260,2.193,261,1.565,262,2.485,263,2.18,264,2.485,265,1.15,266,1.565,267,0.889,268,2.001,269,1.857,270,1.857,271,1.647,272,2.485,273,3.176,274,2.27,275,1.565,276,2.001,277,1.742,278,1.742,279,2.001,280,2.193]],["tags/175",[]],["title/176",[120,1.425,166,0.878,182,1.255]],["content/176",[0,0.31,4,0.634,5,0.958,6,1.104,9,2.568,12,1.743,17,0.924,19,3.052,58,1.183,78,1.679,93,0.714,120,1.792,138,2.996,145,1.571,150,1.333,156,1.035,161,2.25,162,2.25,163,2.25,166,1.546,167,3.012,181,2.537,182,2.071,184,2.733,192,3.166,195,3.166,196,2.672,197,4.422,200,3.156,201,1.28,211,1.069,232,2.479,233,1.954,263,1.875,281,1.431,282,2.664,283,4.035,284,2.537,285,4.035,286,3.395,287,3.395,288,2.996,289,2.537,290,3.395,291,2.996,292,6.577,293,5.295,294,3.395,295,2.884,296,3.395,297,3.395,298,3.395,299,3.395,300,2.537,301,1.804,302,3.745,303,3.395,304,2.537]],["tags/176",[]],["title/177",[42,1.236,105,1.653,183,2.177,203,1.837]],["content/177",[0,0.281,42,1.931,62,2.87,63,3.096,83,1.142,105,3.639,120,1.931,156,0.938,164,1.88,168,3.096,172,2.87,183,4.792,202,4.149,203,2.87,213,4.347,220,3.537,305,3.786,306,4.765,307,4.765,308,2.671,309,2.499,310,2.093]],["tags/177",[]],["title/178",[192,2.118,200,2.509,201,1.503]],["content/178",[]],["tags/178",[]],["title/179",[192,2.118,241,3.516,311,3.208]],["content/179",[0,0.169,5,1.109,10,1.41,17,0.883,19,3.295,22,1.159,37,2.396,42,1.159,48,2.149,52,2.772,68,1.732,124,2.242,129,1.791,150,1.288,152,1.257,153,1.949,156,1.195,170,1.866,182,1.021,192,1.723,196,1.454,201,1.827,210,2.316,216,1.369,217,1.661,224,3.081,225,3.396,226,2.61,229,0.785,232,1.604,234,2.273,235,1.33,236,1.866,238,1.257,246,3.619,247,2.861,249,4.136,250,3.396,251,3.21,252,1.33,253,2.423,255,3.842,256,1.791,264,2.042,265,1.501,272,4.547,274,1.866,295,1.866,308,1.604,312,3.242,313,3.242,314,2.423,315,2.61,316,3.242,317,3.242,318,2.042,319,2.042,320,2.861,321,2.861,322,2.149,323,3.242,324,2.423,325,2.61,326,2.61,327,2.861,328,2.861,329,2.61,330,3.242,331,3.242,332,3.242,333,2.61,334,3.242,335,1.661,336,1.866,337,2.861,338,2.861,339,2.149,340,2.861]],["tags/179",[]],["title/180",[150,1.059,192,2.118,200,2.509]],["content/180",[0,0.212,6,0.642,12,1.193,19,2.929,52,1.95,62,2.167,68,1.458,72,2.346,83,0.674,96,2.702,120,1.458,125,1.95,141,2.702,144,2.702,145,1.887,150,2.004,152,1.58,156,0.993,166,0.898,192,2.167,195,3.039,196,2.961,200,3.601,212,2.859,216,2.414,225,2.859,229,1.384,233,2.346,249,2.451,252,1.672,255,2.702,272,4.159,281,1.165,300,3.047,302,3.047,304,4.273,318,2.568,335,2.929,337,3.598,341,4.077,342,2.451,343,3.282,344,4.077,345,2.089,346,4.077,347,3.159,348,4.077,349,4.077,350,3.598,351,2.252,352,3.047,353,3.598,354,2.346,355,2.568]],["tags/180",[]],["title/181",[0,0.159,156,0.53,177,2.693,356,3.051,357,2.693]],["content/181",[]],["tags/181",[]],["title/182",[0,0.159,147,2.693,156,0.53,159,1.412,358,3.051]],["content/182",[0,0.352,3,2.549,4,0.976,6,0.823,20,3.463,22,2.417,38,2.585,44,3.664,68,1.869,78,2.585,86,1.869,98,3.664,123,3.141,145,2.419,150,1.39,156,0.908,159,2.419,223,3.463,229,1.265,232,3.344,236,3.007,252,2.772,261,3.291,308,2.585,359,5.442,360,5.226,361,4.612,362,2.678,363,3.905,364,3.664]],["tags/182",[]],["title/183",[0,0.159,86,1.091,145,1.412,156,0.53,252,1.251]],["content/183",[0,0.361,6,0.857,12,1.593,19,2.79,28,2.693,86,1.947,87,2.894,150,1.448,165,2.79,180,3.818,182,1.715,192,3.689,200,3.429,201,2.054,210,2.604,211,1.715,221,4.069,223,3.609,224,2.894,265,2.52,268,4.384,269,4.069,270,4.069,282,2.894,355,3.429,365,5.445,366,3.273,367,4.384,368,3.008]],["tags/183",[]],["title/184",[17,0.941,86,1.236,88,2.29,156,0.6]],["content/184",[14,2.576,17,1.27,22,1.667,36,2.478,42,1.667,45,3.754,52,2.23,56,2.028,64,3.09,65,3.485,66,3.269,68,2.242,78,3.101,81,2.683,86,1.667,88,3.09,93,1.489,156,1.089,170,2.683,181,3.485,183,2.937,208,2.803,229,1.517,231,3.09,308,2.306,315,3.754,355,2.937,361,5.533,368,2.576,369,3.09,370,4.663,371,4.115,372,3.754,373,4.155,374,3.485,375,2.576,376,4.663,377,4.663,378,2.803,379,2.683,380,3.09,381,4.663,382,4.115]],["tags/184",[]],["title/185",[156,0.6,182,1.088,202,2.077,308,1.709]],["content/185",[0,0.27,19,3.445,50,2.564,83,0.858,96,4.456,141,3.436,156,1.168,172,2.756,182,2.117,192,2.756,201,1.955,202,4.042,217,2.656,221,3.874,252,2.126,285,4.174,300,3.874,302,3.874,308,2.564,322,3.436,354,2.983,364,3.635,383,5.184,384,5.934,385,3.635,386,2.756,387,3.874,388,5.184,389,5.184,390,4.174,391,4.174]],["tags/185",[]],["title/186",[83,0.505,105,1.459,156,0.53,183,1.922,202,1.834]],["content/186",[17,1.47,27,4.347,37,2.671,42,1.931,46,2.499,68,1.931,83,1.142,86,2.468,92,3.401,105,2.582,125,2.582,156,1.199,164,1.47,168,2.422,172,2.87,182,1.7,183,3.401,202,3.246,207,3.401,209,4.765,210,2.582,220,2.767,267,1.931,309,2.499,310,2.093,392,5.4,393,5.4,394,4.765,395,3.107]],["tags/186",[]],["title/187",[279,4.62]],["content/187",[0,0.293,6,0.887,17,1.534,27,4.536,86,2.536,98,3.95,125,2.694,148,3.734,156,0.979,161,3.734,172,2.995,215,3.549,216,2.379,252,2.31,279,4.536,321,4.972,347,3.113,354,3.242,396,4.536,397,5.634,398,3.113,399,5.634,400,4.972,401,3.734,402,4.972,403,2.887]],["tags/187",[]],["title/188",[164,1.281,165,2.41]],["content/188",[6,0.694,63,1.978,83,1.139,93,1.63,105,2.887,156,0.766,164,2.273,165,2.259,166,1.517,167,2.65,168,3.087,172,2.344,182,2.167,280,3.891,281,1.26,282,2.344,309,2.041,310,2.34,351,2.436,384,3.891,404,3.092,405,2.789,406,3.295,407,2.65,408,3.092,409,2.922,410,3.55,411,3.55,412,3.092,413,1.26,414,2.65,415,3.295,416,2.65]],["tags/188",[]],["title/189",[47,2.118,217,2.041,386,2.118]],["content/189",[5,0.805,47,2.237,83,0.696,93,0.885,152,1.632,164,2.355,166,1.288,168,3.759,217,3.907,224,3.107,281,1.67,322,3.874,324,5.423,386,2.237,405,2.528,414,2.53,416,2.53,417,3.389,418,4.209,419,2.951,420,5.534,421,4.209,422,3.715,423,3.146,424,4.209,425,3.146,426,3.146,427,2.325]],["tags/189",[]],["title/190",[164,1.281,426,3.515]],["content/190",[5,0.678,6,0.558,9,1.815,42,1.267,50,2.558,64,2.348,83,0.855,93,1.659,105,1.694,117,1.753,125,1.694,137,2.484,164,1.944,166,1.345,168,3.011,182,1.923,203,3.795,211,1.116,213,4.163,217,2.649,243,1.64,252,1.453,281,2.199,282,1.883,310,1.373,322,2.348,324,3.864,352,2.648,355,2.231,378,2.13,403,2.649,405,2.487,413,1.744,416,2.13,420,4.281,425,3.864,426,2.648,428,2.348,429,2.648,430,3.128,431,2.648,432,3.127,433,3.543,434,3.127,435,3.127,436,3.543,437,2.484,438,3.127,439,3.543,440,3.127]],["tags/190",[]],["title/191",[164,1.085,409,2.64,441,3.984]],["content/191",[2,1.457,5,0.544,12,0.832,37,1.407,42,2.15,50,1.407,72,1.637,81,1.637,83,0.995,84,1.791,93,1.504,152,1.103,156,0.494,164,2.352,166,1.512,168,3.398,182,2.386,189,1.994,203,3.453,224,2.844,233,1.637,235,1.166,265,2.03,281,1.718,307,2.51,322,1.885,404,1.994,405,2.926,413,1.528,416,1.71,420,1.994,427,3.322,430,2.247,437,3.075,442,3.999,443,2.126,444,2.126,445,1.317,446,2.51,447,2.844,448,2.906,449,3.87,450,2.523,451,2.51,452,1.71,453,1.994,454,2.51,455,2.51]],["tags/191",[]],["title/192",[4,0.878,5,0.899]],["content/192",[0,0.352,4,1.262,5,0.999,7,1.457,11,4.739,12,1.529,17,1.423,30,3.89,36,2.778,38,2.585,83,1.118,87,2.778,89,4.207,229,1.265,304,3.905,400,4.612,401,4.48,408,3.664,456,4.207,457,5.226,458,4.612,459,4.612,460,4.612,461,4.207,462,4.207,463,5.226,464,4.207,465,5.226,466,5.226,467,5.226]],["tags/192",[]],["title/193",[7,1.312,468,2.827]],["content/193",[4,0.931,5,1.401,7,1.39,9,2.554,10,2.168,12,1.459,36,2.65,38,2.466,63,2.236,74,2.466,83,0.825,84,3.14,139,3.94,210,2.384,229,1.883,271,3.304,278,3.495,336,2.869,468,4.401,469,4.985,470,4.399,471,3.725,472,4.399,473,2.869,474,4.985,475,3.495,476,4.985,477,4.985,478,4.014,479,4.014,480,4.985,481,4.985,482,4.985,483,3.304]],["tags/193",[]],["title/194",[5,0.899,10,2.046]],["content/194",[3,2.226,4,0.925,5,1.248,7,1.382,10,2.567,12,2.04,16,3.669,17,0.91,20,2.215,40,2.105,47,1.777,52,1.598,56,2.155,62,1.777,72,1.923,74,1.653,83,0.553,95,2.343,124,1.547,140,2.691,145,1.547,150,1.57,156,0.581,158,1.777,159,2.293,165,1.712,191,2.091,211,1.052,229,1.199,238,1.296,243,1.547,244,2.977,255,3.283,256,3.606,264,4.39,267,1.195,272,2.105,335,1.712,336,2.851,342,2.009,391,4.752,395,2.851,406,2.498,475,2.343,478,2.691,484,3.342,485,2.95,486,2.95,487,1.598,488,3.342,489,3.342,490,1.846,491,2.95,492,2.215,493,3.342,494,3.342,495,3.342,496,2.215,497,2.691,498,2.691,499,2.343,500,3.342,501,2.95,502,3.988,503,2.95]],["tags/194",[]],["title/195",[30,2.293,31,2.395,32,1.905]],["content/195",[0,0.279,6,0.843,7,1.493,16,3.178,17,1.458,30,4.362,31,3.219,32,3.284,58,1.866,75,2.261,100,3.755,180,3.755,244,3.219,311,4.312,367,4.312,375,3.793,413,1.53,483,3.549,487,3.284,491,4.726,498,4.312,504,5.131,505,5.528,506,4.726,507,4.002]],["tags/195",[]],["title/196",[87,2.5,508,4.703]],["content/196",[0,0.366,4,0.97,5,1.122,6,1.001,7,1.773,8,1.798,12,0.794,17,1.151,22,0.97,32,1.298,40,1.709,42,0.97,47,2.247,56,1.18,58,1.473,68,1.857,70,3.642,73,3.731,74,2.569,75,1.146,76,2.395,77,2.185,78,2.091,80,2.395,83,0.449,86,2.273,87,1.442,88,1.798,93,0.889,95,1.903,100,1.903,101,2.185,105,1.298,110,2.395,128,0.996,131,1.499,156,0.734,159,1.256,164,0.739,182,0.854,201,1.023,208,1.631,210,1.298,211,0.854,216,1.146,217,2.166,220,2.166,232,2.091,235,1.113,252,1.734,271,1.798,295,1.562,308,1.342,309,1.256,310,1.052,319,1.709,362,1.39,369,1.798,375,1.499,380,1.798,386,1.442,395,1.562,405,0.945,413,1.208,414,1.631,415,2.028,417,2.185,430,1.39,431,2.028,490,1.499,499,1.903,504,2.028,509,2.713,510,2.395,511,3.404,512,2.713,513,2.185,514,2.713,515,2.713,516,1.562,517,2.713,518,2.713,519,2.713,520,2.713,521,2.713,522,2.713,523,2.713,524,1.709,525,2.185,526,2.713,527,2.028,528,2.395,529,2.395,530,2.395,531,2.713,532,2.395,533,2.185,534,2.395,535,2.028,536,2.713,537,2.395,538,2.185,539,2.713,540,1.631,541,1.798,542,2.713,543,2.713,544,2.028,545,2.185]],["tags/196",[]],["title/197",[0,0.207,86,1.425,546,3.516]],["content/197",[0,0.35,2,2.157,4,0.786,6,0.663,7,1.174,9,2.157,17,1.146,19,2.157,37,2.892,40,2.651,42,1.505,47,3.107,50,2.082,56,3.157,74,2.082,78,2.082,86,2.091,92,3.682,93,0.885,95,2.951,103,3.389,125,2.013,189,2.951,210,2.013,220,2.157,225,2.951,295,2.422,318,2.651,375,2.325,379,2.422,386,2.237,413,1.202,414,2.53,462,3.389,483,2.79,499,2.951,547,3.389,548,4.209,549,3.715,550,5.159,551,4.209,552,4.209,553,5.159,554,4.209,555,4.209,556,3.715,557,3.715,558,3.715,559,4.209,560,4.209,561,3.389,562,2.79,563,4.209,564,4.209,565,2.951]],["tags/197",[]],["title/198",[4,0.744,38,1.971,566,3.984]],["content/198",[0,0.286,3,1.706,4,1.147,12,0.866,13,1.962,17,1.231,19,2.317,20,3.636,22,2.196,34,1.962,35,2.613,36,1.574,38,2.714,42,1.962,44,3.847,45,3.641,46,2.093,47,1.574,50,1.465,66,2.076,68,1.617,78,2.237,83,0.49,86,1.617,87,1.574,93,1.466,97,2.384,104,2.613,123,1.78,125,1.416,131,1.636,145,2.54,150,0.787,156,1.26,157,1.636,159,2.093,170,2.603,172,1.574,180,2.076,182,0.932,202,1.78,203,1.574,207,1.865,211,0.932,215,1.865,218,2.213,229,1.601,233,2.603,235,1.214,236,1.704,238,1.148,252,1.214,282,1.574,315,2.384,319,1.865,342,1.78,347,1.636,351,1.636,363,2.213,364,2.076,367,3.641,371,2.613,372,2.384,374,2.213,378,3.298,380,1.962,403,1.517,419,2.076,444,2.213,448,1.962,541,1.962,567,2.961,568,2.613,569,2.961,570,2.076,571,2.961,572,2.961,573,2.613,574,5.487,575,2.613,576,2.613,577,2.961]],["tags/198",[]],["title/199",[0,0.207,6,0.627,216,1.682]],["content/199",[0,0.232,3,1.323,4,1.328,5,1.446,6,0.891,7,1.432,9,2.278,11,1.506,12,1.301,15,2.947,16,2.058,17,1.211,19,1.797,20,2.325,22,2.023,38,1.735,47,1.142,49,1.895,50,1.735,51,5.379,52,1.678,53,1.729,56,0.934,58,1.222,60,1.291,62,1.142,68,1.254,83,0.736,87,1.142,93,1.079,118,0.768,128,1.288,130,1.729,150,1.365,156,0.983,159,2.058,160,1.353,166,0.773,167,1.291,180,1.506,182,1.4,195,1.865,196,1.573,202,1.291,208,1.291,210,1.678,211,0.676,215,1.353,216,2.167,220,1.1,226,3.58,228,1.895,229,1.469,231,1.423,232,1.735,233,1.236,235,0.881,238,0.833,249,1.291,261,1.353,264,2.21,265,1.624,268,1.729,269,1.605,275,1.353,281,1.616,282,1.142,295,2.019,320,3.096,335,1.1,345,1.1,347,1.187,380,1.423,387,1.605,403,1.1,405,0.748,413,1.27,516,1.236,533,1.729,535,1.605,570,1.506,575,1.895,578,2.148,579,2.148,580,1.729,581,2.148,582,2.148,583,3.508,584,1.506,585,1.895,586,1.506,587,1.506,588,1.729,589,2.148,590,2.148,591,3.508,592,2.148,593,2.148,594,2.148,595,2.148,596,2.148,597,2.148,598,2.148,599,2.148,600,1.142,601,2.148,602,1.895,603,1.291,604,1.729,605,3.096]],["tags/199",[]],["title/200",[0,0.207,6,0.627,606,3.516]],["content/200",[0,0.279,3,1.405,4,0.696,5,1.202,6,0.989,7,1.496,17,1.46,22,1.332,42,2.604,46,2.483,50,1.843,52,1.782,55,2.784,56,1.621,58,1.868,59,2.784,68,1.332,74,1.843,78,3.603,83,0.616,93,1.445,105,3.005,123,2.24,128,1.368,156,0.647,166,0.821,182,1.173,191,1.573,203,3.34,210,1.782,216,1.573,220,1.909,229,0.902,238,2.436,267,1.332,306,3.288,326,3,336,2.144,354,2.144,369,2.469,378,3.223,413,1.064,419,2.613,431,2.784,487,1.782,490,2.058,496,2.469,499,2.613,565,2.613,585,3.288,586,2.613,607,3.726,608,3,609,2.058,610,2.469,611,3.726,612,2.784,613,2.784,614,3.726]],["tags/200",[]],["title/201",[379,2.293,613,2.977,615,2.977]],["content/201",[0,0.272,2,2.678,4,0.976,19,2.678,38,2.585,46,2.419,60,5.051,96,3.463,111,3.141,128,1.919,157,2.887,210,3.583,220,2.678,379,3.007,385,3.664,413,1.493,450,3.007,507,3.905,587,3.664,615,3.905,616,4.612,617,4.612,618,5.226,619,5.226,620,4.612,621,4.207,622,2.778,623,4.612,624,4.207]],["tags/201",[]],["title/202",[60,2.827,625,4.15]],["content/202",[0,0.125,4,0.449,5,1.048,6,0.378,7,1.338,14,3.028,17,1.306,22,0.859,40,1.513,42,1.373,46,3.326,47,2.041,48,2.545,53,1.934,54,2.12,56,2.918,59,1.795,60,3.841,63,2.458,64,5.157,65,1.795,66,2.693,78,2.964,81,2.21,93,1.152,97,1.934,105,1.149,121,1.513,129,1.327,156,0.667,210,1.149,220,1.231,229,0.929,232,1.188,236,2.21,237,1.934,238,1.489,245,1.513,267,0.859,275,3.022,293,1.934,301,1.277,305,2.693,310,0.931,319,1.513,355,1.513,373,1.592,379,2.21,380,1.592,385,1.684,395,1.382,401,1.592,403,1.231,407,1.444,408,1.684,413,1.097,414,1.444,427,1.327,434,2.12,450,1.382,452,1.444,492,2.545,496,1.592,499,1.684,549,2.12,562,1.592,570,3.364,580,1.934,584,1.684,587,1.684,600,1.277,608,3.862,610,1.592,616,2.12,625,2.12,626,2.402,627,2.402,628,2.12,629,2.402,630,2.402,631,2.402,632,1.684,633,3.389,634,2.87,635,1.934,636,1.934,637,2.402,638,2.402,639,2.12,640,2.12,641,2.402,642,1.513,643,2.402,644,2.12,645,2.402,646,2.12,647,2.402,648,2.402,649,2.12,650,2.402,651,2.402,652,2.402,653,2.402,654,3.84,655,2.402,656,1.795,657,1.934,658,2.402,659,2.12]],["tags/202",[]],["title/203",[60,2.827,584,3.298]],["content/203",[4,1.238,5,1.498,6,0.412,7,1.145,14,3.662,17,0.712,22,0.935,29,1.834,52,1.251,56,3.351,60,4.316,63,1.173,78,3.279,81,1.505,83,0.433,93,1.725,128,0.96,153,1.572,156,1.085,157,1.445,166,0.576,210,1.251,229,0.994,232,2.032,236,2.364,238,1.592,301,1.39,310,1.014,336,1.505,339,1.733,340,2.308,351,1.445,407,1.572,413,1.449,444,1.954,452,1.572,496,2.722,537,2.308,556,2.308,570,2.88,584,2.88,587,4.03,588,3.307,622,1.39,634,4.295,635,2.105,646,5.512,656,1.954,659,2.308,660,1.954,661,2.308,662,2.615,663,3.556,664,4.107,665,4.107,666,3.307,667,1.647,668,2.615,669,2.615,670,1.39,671,2.615,672,1.733,673,2.615,674,2.308,675,2.105,676,2.615,677,2.615,678,2.615,679,2.308,680,2.308,681,2.615,682,2.615]],["tags/203",[]],["title/204",[379,2.706,615,3.515]],["content/204",[0,0.218,4,0.569,5,1.114,6,0.358,7,0.634,8,0.855,19,0.661,22,1.997,28,0.638,42,0.813,44,2.576,46,0.597,60,4.496,64,0.855,68,0.813,81,1.308,83,0.376,86,0.461,93,1.409,95,0.904,96,0.855,114,1.138,128,0.474,129,1.256,137,0.904,139,1.832,145,1.411,150,1.229,156,1.225,157,2.03,160,0.812,164,0.351,166,1.284,172,0.686,182,0.406,191,0.545,192,0.686,203,0.686,208,1.366,211,0.716,214,1.138,216,0.545,217,0.661,222,1.138,225,0.904,229,1.55,231,0.855,232,2.883,236,1.308,238,2.342,243,0.597,250,0.904,251,0.855,252,0.529,254,1.83,263,0.713,267,0.461,272,0.812,285,1.039,291,1.138,301,0.686,302,0.964,308,0.638,309,1.411,310,1.935,335,0.661,339,0.855,342,0.775,343,1.039,350,1.138,351,2.03,353,2.69,355,2.314,362,1.165,368,0.713,369,0.855,372,1.039,373,2.02,374,0.964,378,2.518,379,3.686,387,0.964,390,1.039,396,2.454,405,1.062,411,1.039,413,1.595,419,0.904,425,0.964,427,0.713,430,0.661,443,1.699,445,1.052,448,0.855,450,0.742,485,2.006,490,0.713,496,2.777,513,1.039,541,0.855,570,0.904,584,2.137,587,2.576,588,1.83,609,1.684,615,5.19,617,1.138,622,0.686,623,1.138,624,1.039,633,3.242,634,2.278,635,2.958,656,1.699,660,2.745,661,2.006,663,2.137,667,1.432,672,0.855,675,1.83,683,1.29,684,1.29,685,0.855,686,1.29,687,2.006,688,1.29,689,1.29,690,1.138,691,0.904,692,0.812,693,1.29,694,1.29,695,1.29,696,2.137,697,0.812,698,1.138,699,1.29,700,0.904,701,1.138,702,1.29,703,4.19,704,1.83,705,1.29,706,1.138,707,1.29,708,1.29,709,1.29,710,1.699,711,1.29,712,1.29,713,2.273,714,1.29,715,1.29,716,1.29,717,1.29,718,1.138,719,0.964,720,0.964,721,1.29,722,1.29,723,1.29,724,1.29,725,1.29,726,1.83,727,1.29,728,1.29,729,1.29]],["tags/204",[]],["title/205",[63,1.369,172,1.622,379,1.756,394,2.693,613,2.28]],["content/205",[0,0.11,2,1.079,4,0.393,6,0.543,9,1.769,11,2.421,14,1.164,17,0.573,20,2.288,22,1.234,36,1.119,39,1.859,40,1.326,42,2.688,46,1.598,47,1.835,52,1.651,56,2.616,63,1.548,64,2.288,65,1.574,66,1.477,74,2.17,78,3.28,83,0.571,84,2.174,86,1.234,90,1.859,92,2.174,93,1.394,98,2.421,99,3.046,100,1.477,101,1.696,102,1.859,103,3.532,105,2.098,125,1.007,128,0.773,139,1.266,145,0.975,149,1.859,155,1.326,156,0.366,157,1.164,167,1.266,182,0.663,183,2.763,189,1.477,203,2.332,207,1.326,215,1.326,216,0.889,218,1.574,220,1.079,231,1.396,233,1.212,238,0.816,243,0.975,252,1.799,278,1.477,282,1.119,283,1.696,288,1.859,305,3.557,347,1.164,359,1.696,368,1.164,379,2.524,382,1.859,396,1.696,407,1.266,408,2.421,411,1.696,419,2.421,445,0.975,459,1.859,483,2.288,506,1.859,510,1.859,516,1.212,550,3.871,553,1.859,562,1.396,573,1.859,606,1.859,609,1.164,613,3.278,649,1.859,660,1.574,680,1.859,720,1.574,730,1.859,731,4.387,732,3.452,733,3.452,734,3.452,735,3.046,736,2.106,737,2.106,738,2.106,739,2.106,740,1.696,741,2.106,742,2.106,743,1.266,744,2.106,745,2.106,746,2.106,747,2.106,748,3.452,749,2.106,750,1.477,751,3.452,752,2.106,753,3.046,754,1.696,755,2.106,756,3.452,757,1.859,758,4.387,759,2.106,760,2.106,761,3.452,762,2.106,763,1.859,764,1.859,765,2.106,766,2.106,767,2.106,768,1.859,769,2.106,770,2.106,771,2.106,772,2.106,773,2.106]],["tags/205",[]],["title/206",[216,2.423]],["content/206",[0,0.375,4,1.08,5,1.106,6,0.911,7,1.613,8,3.834,17,1.575,22,2.069,23,4.657,74,3.566,89,4.657,216,3.044,217,2.964,231,3.834,232,2.861,314,4.323,327,5.105,328,5.105,546,5.105,774,5.785,775,5.105]],["tags/206",[]],["title/207",[120,1.236,124,1.6,329,2.782,471,2.583]],["content/207",[0,0.397,6,1.057,7,1.174,17,1.146,40,2.651,58,1.466,62,2.237,68,1.505,72,2.422,74,2.892,75,2.468,78,2.082,120,2.595,125,2.013,150,1.555,156,1.016,159,1.948,166,1.288,182,1.325,201,2.737,211,2.115,229,1.415,232,2.082,243,1.948,263,2.325,281,1.67,283,3.389,295,2.422,308,2.082,314,3.146,345,2.157,354,2.422,403,2.995,410,3.389,524,2.651,525,3.389,604,3.389,743,3.514,764,3.715,776,4.209,777,3.389,778,2.951,779,4.209]],["tags/207",[]],["title/208",[166,1.264]],["content/208",[0,0.301,3,1.217,4,0.901,5,1.105,6,1.176,8,2.138,9,1.653,12,1.691,14,3.193,17,0.878,44,2.262,58,1.124,68,2.067,83,0.798,86,1.154,93,1.014,100,2.262,105,1.543,148,2.138,156,1.252,159,2.969,160,2.032,164,1.747,165,1.653,166,1.588,168,1.447,182,2.162,195,1.715,196,1.447,207,2.032,211,1.519,224,1.715,233,1.856,252,1.323,263,1.782,281,1.651,289,2.411,295,1.856,345,1.653,351,1.782,369,3.198,395,1.856,402,2.847,413,0.921,414,1.939,427,1.782,444,2.411,445,1.493,533,2.597,534,4.258,540,1.939,541,2.138,621,2.597,628,2.847,704,2.597,740,2.597,780,3.226,781,3.226,782,3.226,783,3.226,784,2.032,785,2.847,786,3.383,787,3.226,788,2.411,789,3.226,790,2.847,791,3.226]],["tags/208",[]],["title/209",[281,1.639]],["content/209",[0,0.245,4,1.176,6,0.992,10,2.043,12,1.843,15,3.113,16,2.174,22,1.679,28,2.323,72,2.703,83,0.777,93,0.987,120,1.679,128,1.724,150,1.675,156,0.816,159,2.174,166,1.035,195,3.349,196,2.826,201,1.771,211,1.479,217,2.406,229,1.525,249,2.823,265,2.174,281,1.8,282,2.496,308,2.323,325,3.781,326,3.781,345,2.406,369,3.113,386,2.496,398,2.595,412,3.293,430,2.406,656,3.51,792,4.696,793,4.696,794,4.145,795,4.696]],["tags/209",[]],["title/210",[150,1.251,229,1.138]],["content/210",[0,0.223,4,1.267,5,1.133,6,1.069,7,1.893,9,2.199,10,1.867,14,2.372,15,2.845,16,1.987,17,1.169,22,1.535,68,2.119,83,0.71,120,1.535,125,2.053,140,3.456,150,2.111,167,2.58,215,3.733,229,1.642,252,1.76,256,3.274,261,3.733,282,2.282,333,4.771,336,2.47,345,2.199,375,2.372,412,3.01,432,3.788,452,2.58,501,5.989,527,4.429,532,3.788,743,2.58,796,5.926,797,5.23,798,3.788]],["tags/210",[]],["title/211",[235,2.353]],["content/211",[0,0.293,3,2.125,5,1.356,17,1.931,93,1.765,117,2.787,155,3.549,156,0.979,159,2.608,164,1.931,235,2.908,405,1.963,413,1.609,541,3.734,603,3.386,620,4.972,799,3.95,800,4.972,801,4.21]],["tags/211",[]],["title/212",[0,0.245,229,1.138]],["content/212",[0,0.281,7,1.506,17,1.47,56,2.349,58,1.881,74,2.671,75,3.213,229,1.941,238,2.093,240,4.035,244,3.246,245,3.401,259,4.035,260,4.765,275,3.401,398,2.983,428,3.579,473,3.107,487,3.301,778,4.84,802,3.579,803,4.347,804,5.4,805,5.4,806,5.4]],["tags/212",[]],["title/213",[150,1.526]],["content/213",[0,0.341,4,1.368,5,0.953,6,0.785,7,1.39,10,2.168,12,1.918,16,2.308,31,2.996,32,2.384,68,1.783,93,1.54,150,1.947,164,1.357,166,1.098,167,2.996,211,1.57,229,1.206,234,3.495,265,2.308,281,1.872,318,3.14,335,2.554,354,2.869,368,2.754,404,3.495,453,3.495,561,4.014,794,4.399,807,4.399,808,3.725,809,4.985,810,4.985]],["tags/213",[]],["title/214",[811,5.738]],["content/214",[3,1.71,4,0.846,10,3.037,15,3.004,16,2.098,37,2.242,42,2.199,51,3.649,111,3.697,141,3.004,150,1.991,229,1.489,256,2.504,265,2.098,333,3.649,342,2.724,347,2.504,355,2.855,366,2.724,373,3.004,398,2.504,413,1.757,445,2.098,452,2.724,475,4.313,610,4.076,612,3.387,667,2.855,692,3.874,784,2.855,797,4,799,3.178,812,3.387,813,4.532,814,5.428,815,4.532,816,4,817,3.387,818,4,819,4.532,820,4,821,4]],["tags/214",[]],["title/215",[201,2.164]],["content/215",[0,0.215,5,1.103,7,1.609,10,1.796,12,1.945,17,1.124,22,1.476,37,2.042,42,2.063,48,2.736,68,1.476,83,0.683,120,2.377,124,1.911,150,1.098,152,1.601,153,2.482,158,2.195,201,2.176,221,3.086,229,1.396,238,2.577,250,2.895,251,2.736,256,2.281,276,4.644,281,1.648,329,3.324,342,2.482,347,2.281,362,2.115,366,2.482,478,4.644,502,5.352,503,5.09,610,2.736,612,3.086,639,3.644,696,2.895,697,2.601,719,3.086,740,3.324,818,3.644,821,3.644,822,4.129,823,4.129,824,4.129,825,4.129,826,3.644,827,3.324,828,3.644,829,4.129]],["tags/215",[]],["title/216",[830,4.62]],["content/216",[2,3.292,4,0.903,10,2.104,12,1.415,15,3.205,16,2.974,83,0.8,137,3.391,150,2.187,158,2.571,199,2.672,201,1.824,229,1.555,234,3.391,256,2.672,266,4.047,270,3.614,273,5.173,277,3.391,443,3.614,452,2.907,475,3.391,502,5.173,608,3.894,814,4.268,817,3.614,831,4.836,832,4.836,833,4.836,834,4.836,835,4.836,836,4.836,837,4.268,838,4.836,839,4.836]],["tags/216",[]],["title/217",[368,3.17]],["content/217",[5,1.373,12,1.201,13,2.719,17,1.117,22,2.054,28,2.029,42,1.467,48,3.806,68,1.467,93,0.863,117,2.029,121,2.584,124,1.899,128,1.506,139,2.466,145,1.899,150,1.908,152,1.59,153,3.452,201,2.166,224,2.181,234,2.877,238,2.226,239,3.303,254,3.303,267,1.467,295,2.361,335,2.102,339,2.719,366,3.452,368,2.267,435,3.621,460,3.621,516,3.305,538,3.303,557,3.621,609,3.173,696,2.877,784,2.584,827,3.303,828,3.621,830,3.303,840,4.103,841,4.103,842,4.103,843,3.303,844,4.103,845,5.742,846,4.103,847,3.621,848,3.621,849,3.303,850,3.303,851,3.621,852,4.103]],["tags/217",[]],["title/218",[50,2.839]],["content/218",[0,0.391,4,0.981,5,0.693,7,1.01,10,2.951,12,1.985,38,1.792,52,1.732,83,0.599,93,0.761,108,2.692,117,2.599,120,1.879,121,2.281,128,1.33,150,1.915,152,2.037,156,0.629,158,1.925,164,1.431,166,1.362,182,1.947,191,1.529,201,1.366,229,1.642,235,1.485,249,2.177,256,2.001,272,2.281,273,4.978,274,2.084,276,4.23,277,3.684,281,1.035,325,4.23,335,1.856,357,3.196,363,2.707,364,2.54,404,2.54,405,1.831,422,3.196,458,3.196,473,2.084,487,1.732,498,2.916,692,2.281,798,4.637,817,2.707,837,3.196,843,2.916,853,3.622,854,3.622,855,3.196,856,3.196,857,3.622]],["tags/218",[]],["title/219",[0,0.245,229,1.138]],["content/219",[0,0.39,4,0.973,5,0.997,6,0.564,7,0.999,12,2.098,23,2.884,83,1.186,117,1.772,118,2.676,134,3.895,139,2.153,190,2.884,229,1.869,244,2.153,245,2.256,265,1.658,267,1.281,274,3,282,1.904,318,2.256,416,2.153,445,1.658,468,3.133,471,2.677,473,3.536,479,2.884,778,5.028,784,3.283,808,2.677,858,3.454,859,3.582,860,3.457,861,2.677,862,4.947,863,4.197,864,3.582,865,2.884,866,4.592,867,3.536,868,6.144,869,2.677,870,2.512,871,3.582]],["tags/219",[]],["title/220",[216,1.682,401,2.64,487,1.905]],["content/220",[75,3.384,211,1.906,216,2.556,229,1.465,269,4.525,270,4.525,359,4.875,375,3.345,398,3.345,412,4.245,445,2.803,487,3.546,516,3.484,672,4.013,802,4.013,872,4.875]],["tags/220",[]],["title/221",[473,2.706,873,3.298]],["content/221",[0,0.286,2,2.813,7,1.531,36,2.919,83,0.908,139,3.3,141,3.639,157,3.034,170,3.16,274,3.16,468,3.3,473,4.644,475,3.85,479,4.421,675,4.421,750,3.85,803,4.421,855,4.846,862,4.421,867,3.16,869,4.104,870,3.85,873,4.892,874,4.421,875,4.846,876,4.421]],["tags/221",[]],["title/222",[56,1.188,74,1.351,244,1.642,245,1.72,275,1.72,877,2.411]],["content/222",[4,1.131,12,1.772,56,3.226,75,3.131,83,1.002,190,4.875,191,2.556,243,2.803,244,3.639,245,3.813,275,4.671,473,3.484,487,3.546,690,5.343,873,4.245]],["tags/222",[]],["title/223",[878,4.15,879,4.15]],["content/223",[0,0.307,5,1.516,10,1.855,12,1.248,16,1.974,17,1.161,36,2.267,37,2.109,68,1.525,83,1.119,93,0.897,125,2.039,150,1.799,156,0.741,216,2.491,229,1.032,238,3.072,246,3.187,249,2.563,250,4.136,251,3.91,255,2.826,256,2.356,261,2.686,264,2.686,265,2.731,284,3.187,293,3.433,335,2.185,339,2.826,375,2.356,378,2.563,398,2.356,456,3.433,473,2.454,663,2.99,784,2.686,878,5.206,879,5.969,880,4.264,881,4.264,882,3.763]],["tags/223",[]],["title/224",[12,1.166,16,1.844,238,1.544]],["content/224",[5,1.285,10,1.831,12,2.309,16,3.359,68,1.505,74,2.082,83,0.696,93,0.885,117,2.082,123,2.53,157,2.325,208,2.53,224,3.857,229,1.019,235,1.726,236,2.422,237,3.389,238,2.956,240,4.369,246,4.369,251,2.79,253,5.423,255,2.79,256,2.325,339,2.79,345,2.995,368,2.325,398,3.23,403,2.157,416,2.53,644,3.715,663,2.951,691,2.951,698,5.159,801,3.146,869,3.146,883,3.715,884,4.209,885,4.209,886,4.209,887,4.209]],["tags/224",[]],["title/225",[75,1.682,487,1.905,802,2.64]],["content/225",[0,0.371,6,0.634,7,1.581,12,1.658,16,2.623,56,1.751,74,1.992,75,3.375,108,2.063,128,1.478,207,2.536,224,2.14,229,1.372,238,1.561,239,3.242,240,3.009,244,2.42,245,2.536,253,3.009,267,1.44,271,2.669,274,2.317,275,2.536,301,2.14,336,2.317,345,2.063,347,2.224,401,2.669,427,2.224,450,2.317,468,3.406,473,4.096,487,3.136,634,3.009,657,3.242,663,2.823,672,2.669,778,3.974,802,2.669,803,4.563,808,3.009,862,3.242,867,2.317,873,3.974,875,3.553,877,3.553,888,4.026,889,3.553,890,4.026,891,3.553,892,3.553]],["tags/225",[]],["title/226",[405,1.639,413,1.343]],["content/226",[0,0.243,5,1.355,9,3.212,12,1.364,14,2.576,86,1.667,93,0.98,117,2.306,152,1.807,164,1.27,166,1.027,211,1.468,265,2.158,271,3.09,309,2.902,310,2.43,354,2.683,375,2.576,395,2.683,405,2.639,412,3.269,413,2.164,414,2.803,415,3.485,417,3.754,429,3.485,431,3.485,437,3.269,496,3.09,497,3.754,544,3.485,603,2.803,610,3.09,632,3.269,826,4.115,893,4.115,894,3.09,895,4.663,896,4.115,897,3.485]],["tags/226",[]],["title/227",[211,1.481,545,3.786]],["content/227",[5,1.277,22,2.388,83,1.105,153,4.013,211,2.103,405,2.326,413,1.907,898,5.376,899,5.376]],["tags/227",[]],["title/228",[900,4.62]],["content/228",[0,0.111,5,0.669,6,0.698,22,0.766,37,1.731,43,1.6,55,1.6,63,0.96,72,1.232,83,0.354,92,1.348,93,1.077,105,1.024,118,1.251,128,0.786,134,1.6,144,1.419,151,3.088,152,0.83,153,1.287,164,1.88,166,0.472,168,1.99,171,1.889,173,1.724,182,0.674,185,1.6,196,1.569,227,1.724,235,0.878,238,1.72,243,1.619,263,1.183,274,1.232,308,1.059,309,3.288,310,0.83,318,1.348,322,2.319,385,1.501,403,1.097,405,1.968,406,3.316,407,2.103,413,1.267,416,1.287,420,1.501,425,1.6,448,2.94,449,3.088,450,2.013,464,2.817,483,1.419,492,1.419,544,2.615,558,1.889,562,1.419,565,1.501,600,1.138,603,1.287,609,1.183,701,1.889,784,1.348,799,2.453,812,3.829,816,1.889,856,1.889,858,2.319,860,3.869,863,1.724,865,1.724,866,1.6,867,1.232,870,1.501,894,1.419,897,1.6,898,2.817,900,1.724,901,3.088,902,1.889,903,2.141,904,2.141,905,2.141,906,2.141,907,2.141,908,2.817,909,1.889,910,2.141,911,1.889,912,1.501,913,1.889,914,1.889,915,4.017,916,1.889,917,2.141,918,2.141,919,3.557,920,3.088,921,3.915,922,3.499,923,2.141,924,1.889,925,1.6,926,1.724,927,1.6,928,1.889,929,2.615,930,1.724,931,3.111,932,3.592,933,3.316,934,3.316,935,1.724,936,1.889,937,1.724,938,2.141,939,1.889,940,1.724,941,1.889,942,1.501,943,2.141,944,3.499,945,1.724]],["tags/228",[]],["title/229",[946,5.064]],["content/229",[0,0.129,4,0.462,5,0.473,6,0.619,12,0.724,14,1.368,43,1.85,55,1.85,62,1.316,63,1.11,83,0.651,93,1.172,118,1.407,128,0.909,134,1.85,143,3.431,144,3.243,152,0.96,159,1.146,164,1.763,166,0.545,168,1.764,182,0.78,185,1.85,196,1.764,211,1.239,227,1.993,235,1.015,238,1.897,265,1.146,278,1.736,309,3.142,310,1.897,318,1.559,342,1.488,362,1.268,405,1.705,407,1.488,409,1.641,413,0.707,420,1.736,437,2.758,448,2.607,461,3.167,483,1.641,492,1.641,544,3.657,565,1.736,600,1.316,603,1.488,609,1.368,785,2.185,858,2.607,860,3.889,863,1.993,865,1.993,866,1.85,867,1.425,894,2.607,899,3.167,900,1.993,902,2.185,908,1.993,909,2.185,911,2.185,912,1.736,913,3.471,914,2.185,915,4.031,916,2.185,919,1.559,924,2.185,925,1.85,926,1.993,927,1.85,928,2.185,929,2.939,930,1.993,931,3.431,932,3.909,933,3.657,934,3.657,935,1.993,936,2.185,937,1.993,939,2.185,940,1.993,941,2.185,945,1.993,946,3.471,947,2.475,948,2.475,949,2.475,950,2.475,951,2.475,952,2.475,953,2.475,954,2.475,955,3.471,956,2.475,957,4.894,958,2.475,959,2.475,960,2.475,961,2.475,962,2.475,963,2.475]],["tags/229",[]],["title/230",[6,0.74,93,0.989]],["content/230",[0,0.301,3,2.182,4,1.08,6,1.135,7,1.613,30,3.329,34,3.834,58,2.015,62,3.075,70,4.056,108,2.964,128,2.124,145,2.678,152,2.242,207,3.643,243,2.678,375,3.196,524,3.643,632,4.056,775,5.105,874,4.657,964,5.805]],["tags/230",[]],["title/231",[0,0.207,6,0.627,229,0.964]],["content/231",[0,0.39,4,0.976,6,0.823,7,1.457,58,1.821,75,2.854,93,1.099,108,2.678,129,2.887,166,1.151,199,2.887,229,1.265,243,2.419,267,1.869,347,2.887,351,2.887,398,2.887,423,3.905,428,3.463,445,2.419,468,4.063,487,2.499,670,2.778,672,3.463,750,3.664,802,3.463,867,3.007,872,4.207,965,4.612,966,4.612,967,3.463,968,4.612]],["tags/231",[]],["title/232",[0,0.207,6,0.627,166,0.878]],["content/232",[0,0.324,6,0.981,58,2.17,75,2.63,166,1.372,199,3.441,301,3.311,413,1.779,670,3.311,788,4.655,925,4.655,967,4.128,969,4.128,970,5.497,971,4.367,972,5.497]],["tags/232",[]],["title/233",[7,1.111,267,1.425,973,3.516]],["content/233",[3,2.395,4,1.186,5,1.215,7,1.771,62,3.376,81,3.655,111,3.817,145,2.94,267,2.271,374,4.746,445,2.94,547,5.113,777,5.113,964,5.113]],["tags/233",[]],["title/234",[235,1.929,468,2.827]],["content/234",[0,0.336,4,0.608,5,0.623,6,0.765,7,0.909,12,1.701,41,2.876,83,0.539,93,1.222,118,2.305,129,1.8,150,0.866,158,1.732,164,0.887,166,0.718,196,1.461,201,1.833,211,1.026,235,1.993,238,1.263,266,2.052,267,2.079,304,2.435,309,2.984,345,3.303,391,2.623,497,2.623,516,1.875,527,2.435,528,5.131,529,2.876,530,5.131,565,2.285,600,3.09,609,1.8,667,2.052,784,2.052,858,3.222,860,3.706,866,4.345,867,2.797,926,3.914,927,3.633,929,2.435,930,2.623,931,3.408,932,4.077,933,2.435,934,2.435,945,2.623,974,2.435,975,3.258,976,4.861,977,2.435,978,4.861,979,4.861,980,4.861,981,3.258,982,3.258,983,3.258,984,3.258,985,3.258,986,3.258,987,3.258,988,2.876,989,3.258]],["tags/234",[]],["title/235",[309,2.177,799,3.298]],["content/235",[0,0.177,2,1.058,3,0.779,4,0.386,5,0.828,7,0.576,34,1.369,36,1.098,37,1.022,43,1.544,46,0.956,63,1.524,68,0.739,81,1.189,83,0.716,93,1.054,111,1.242,118,2.572,128,1.841,135,1.544,137,1.448,158,1.098,164,1.856,165,1.058,168,0.927,170,1.955,196,1.524,211,1.579,220,2.839,235,0.847,238,0.801,243,2.321,252,0.847,305,1.448,308,2.948,309,2.916,310,1.317,343,1.663,385,1.448,405,2.195,406,1.544,407,3.331,413,1.583,423,1.544,428,1.369,437,2.382,454,1.823,507,1.544,513,1.663,524,1.301,535,1.544,568,1.823,586,1.448,600,1.098,603,3.014,609,1.141,685,1.369,750,1.448,786,4.179,799,2.382,820,1.823,850,1.663,858,1.369,860,2.569,882,1.823,893,1.823,898,1.663,899,1.663,901,2.999,915,2.252,920,1.823,921,1.823,927,1.544,929,1.544,931,1.448,932,3.035,933,1.544,934,1.544,935,1.663,937,1.663,988,1.823,990,2.066,991,2.066,992,2.066,993,2.066,994,2.066,995,2.066,996,2.066,997,2.066,998,2.066,999,2.066,1000,2.066,1001,2.066,1002,2.066,1003,2.066,1004,2.066,1005,1.823,1006,2.066,1007,2.066,1008,2.726,1009,3.398,1010,2.066,1011,2.066,1012,2.066,1013,4.454,1014,3.398,1015,5.014,1016,3.398,1017,3.398,1018,3.398,1019,3.398,1020,3.398,1021,3.398,1022,3.398,1023,3.398,1024,3.398,1025,2.066,1026,2.066,1027,2.066,1028,2.066]],["tags/235",[]],["title/236",[150,0.919,201,1.303,266,2.177,281,0.987]],["content/236",[0,0.27,3,1.955,5,0.991,6,1.059,13,3.436,28,3.326,34,3.436,36,2.756,63,2.325,117,2.564,124,2.4,150,1.788,170,2.983,191,2.189,195,2.756,196,2.325,201,2.815,229,1.255,266,3.265,267,1.854,345,2.656,368,2.864,600,2.756,642,3.265,710,3.874,847,4.575,848,4.575,849,4.174,892,4.575,1029,4.575,1030,4.575,1031,4.575]],["tags/236",[]],["title/237",[199,2.598,267,1.682]],["content/237",[58,2.191,93,1.322,152,2.438,166,1.386,199,4.193,235,2.579,267,2.714,281,1.796,456,5.063,576,5.55,670,3.343,967,4.168,1032,6.289]],["tags/237",[]],["title/238",[0,0.207,166,0.878,310,1.544]],["content/238",[4,0.829,5,1.16,6,0.699,10,1.931,12,1.299,30,2.555,46,2.055,52,2.123,83,1.143,107,3.318,108,2.275,158,2.36,166,1.522,229,1.074,263,2.453,267,1.588,301,2.36,310,1.721,386,2.36,445,2.055,471,3.318,472,3.918,490,2.453,540,2.668,670,3.224,691,3.113,700,3.113,710,3.318,817,3.318,873,3.113,876,3.574,894,2.942,915,5.15,942,3.113,971,3.113,1033,3.918,1034,3.318,1035,6.858,1036,3.318,1037,4.439,1038,4.439,1039,4.439,1040,4.439,1041,4.439]],["tags/238",[]],["title/239",[152,1.823,281,1.343]],["content/239",[0,0.304,5,1.116,93,1.658,108,2.99,117,3.586,152,2.81,156,1.014,164,1.589,166,1.597,257,3.868,267,2.087,281,1.667,309,2.702,540,3.508,800,5.151,801,4.362,932,4.093,1042,4.093]],["tags/239",[]],["title/240",[166,1.036,182,1.481]],["content/240",[0,0.35,6,0.816,42,1.854,83,1.112,120,2.405,124,2.4,150,1.379,156,0.901,164,1.412,166,1.142,173,4.174,182,2.487,195,2.756,196,2.325,203,2.756,212,3.635,224,2.756,257,3.436,281,1.921,403,2.656,405,1.806,413,1.481,516,2.983,666,4.174,667,3.265,861,3.874,977,5.025,1042,3.635,1043,4.174]],["tags/240",[]],["title/241",[93,0.989,395,2.706]],["content/241",[5,0.591,29,2.165,46,1.429,50,1.527,63,1.385,83,0.931,86,1.104,93,0.649,118,1.67,128,1.134,135,2.308,143,4.725,144,2.046,164,2.004,168,2.094,263,2.579,264,1.945,274,1.777,277,2.165,289,2.308,310,2.182,311,2.486,362,2.392,366,1.856,386,1.641,405,2.186,413,1.608,429,2.308,540,1.856,636,2.486,670,2.482,700,2.165,743,1.856,812,2.308,858,2.046,860,3.215,870,2.165,912,3.947,919,1.945,942,3.274,971,3.947,1008,3.952,1013,2.308,1034,2.308,1036,2.308,1044,2.725,1045,4.669,1046,3.088,1047,3.088,1048,3.088,1049,3.088,1050,3.088,1051,3.088,1052,2.486,1053,3.088,1054,4.968,1055,4.968,1056,2.725,1057,2.486,1058,1.945,1059,2.486,1060,4.159,1061,3.274,1062,2.725,1063,2.725,1064,3.759,1065,2.486,1066,2.725,1067,2.725,1068,2.486,1069,4.12,1070,2.725,1071,2.725,1072,2.725,1073,2.725,1074,2.725]],["tags/241",[]],["title/242",[63,2.574]],["content/242",[4,1.273,118,2.438,1075,5.095,1076,4.098,1077,6.016,1078,4.098,1079,6.016]],["tags/242",[]],["title/243",[4,0.645,118,1.236,1075,2.583,1076,2.077]],["content/243",[1077,6.28,1078,4.277,1079,6.28]],["tags/243",[]],["title/244",[4,0.744,1075,2.977,1076,2.395]],["content/244",[0,0.245,4,0.877,6,1.119,62,2.496,63,2.106,125,2.246,131,2.595,362,2.406,398,2.595,403,3.228,409,3.113,511,3.781,622,2.496,679,4.145,692,2.958,768,4.145,786,3.293,894,3.113,919,3.968,955,4.145,964,3.781,1005,5.56,1058,3.968,1075,5.313,1076,4.903,1078,3.787,1080,4.696,1081,3.51,1082,4.696,1083,6.3,1084,6.3,1085,4.696,1086,4.145,1087,4.696]],["tags/244",[]],["title/245",[1088,5.738]],["content/245",[3,1.91,4,0.945,17,1.379,22,1.81,38,2.504,42,1.81,83,1.095,92,3.189,93,1.392,145,2.344,156,0.88,203,2.691,208,3.043,243,3.065,319,3.189,352,3.784,378,3.043,403,3.392,413,1.446,535,3.784,562,3.355,696,3.55,786,3.55,1076,4.704,1089,5.063,1090,5.063,1091,5.843,1092,6.621,1093,4.468,1094,5.063,1095,5.063]],["tags/245",[]],["title/246",[1096,4.288]],["content/246",[0,0.318,3,2.305,4,1.141,5,1.169,34,4.05,58,2.804,75,3.149,120,2.185,128,2.244,191,2.58,490,3.376,524,3.849,874,6.005,1031,5.393]],["tags/246",[]],["title/247",[0,0.18,6,0.544,108,1.771,1078,2.077]],["content/247",[]],["tags/247",[]],["title/248",[6,0.74,697,2.962]],["content/248",[0,0.296,3,2.144,6,1.227,265,2.631,301,3.021,345,3.992,697,3.58,969,3.767,977,4.247,1060,3.767,1078,4.683,1097,5.683,1098,5.016,1099,5.683,1100,7.792,1101,7.13,1102,5.683]],["tags/248",[]],["title/249",[0,0.207,6,0.627,229,0.964]],["content/249",[0,0.39,4,0.976,6,0.823,7,1.457,58,1.821,75,2.854,93,1.099,108,2.678,129,2.887,166,1.151,199,2.887,229,1.265,243,2.419,267,1.869,347,2.887,351,2.887,398,2.887,423,3.905,428,3.463,445,2.419,468,4.063,487,2.499,670,2.778,672,3.463,750,3.664,802,3.463,867,3.007,872,4.207,965,4.612,966,4.612,967,3.463,968,4.612]],["tags/249",[]],["title/250",[0,0.207,6,0.627,166,0.878]],["content/250",[0,0.331,6,1.202,58,2.213,166,1.399,199,3.508,413,1.814,670,3.376,788,4.746,925,4.746,967,4.209,970,5.604,971,4.453,972,5.604]],["tags/250",[]],["title/251",[150,0.919,201,1.303,266,2.177,281,0.987]],["content/251",[0,0.389,3,2.119,4,0.743,5,1.075,6,1.176,12,1.164,13,2.636,17,1.083,83,0.658,93,1.181,117,1.967,124,1.841,150,1.058,155,2.505,156,0.691,164,1.083,191,1.679,195,2.114,196,1.784,201,2.457,211,2.051,216,1.679,229,1.36,235,2.304,266,2.505,271,3.724,284,2.972,345,2.879,351,2.197,378,2.39,390,3.202,395,2.289,405,1.957,409,2.636,413,1.605,516,2.289,525,3.202,527,4.199,541,2.636,545,3.202,600,2.114,602,3.51,778,3.939,801,2.972,867,2.289,889,3.51,1029,3.51,1059,3.202,1078,2.39,1103,3.202,1104,3.977,1105,3.977]],["tags/251",[]],["title/252",[152,1.823,281,1.343]],["content/252",[0,0.331,6,1.127,83,0.788,120,1.704,152,1.847,156,0.828,166,1.805,191,2.012,195,2.533,196,2.137,211,1.501,212,3.341,233,2.742,252,1.954,257,3.158,259,3.561,281,1.361,309,2.206,310,1.847,336,2.742,363,3.561,364,3.341,403,2.442,622,3.381,632,3.341,700,3.341,942,3.341,1033,4.205,1034,3.561,1036,3.561,1042,3.341,1052,3.837,1106,4.205,1107,4.205,1108,4.765,1109,4.765,1110,4.765,1111,4.205,1112,4.765]],["tags/252",[]],["title/253",[6,0.74,1078,2.827]],["content/253",[0,0.219,6,1.242,83,1.111,86,1.505,93,1.229,121,2.651,125,2.013,152,1.632,156,0.731,164,1.976,166,1.48,199,2.325,211,1.325,217,2.157,220,2.157,235,1.726,265,1.948,272,2.651,281,1.202,282,2.237,308,2.082,324,3.146,362,2.157,386,2.237,395,3.865,405,2.34,407,2.53,413,1.202,415,3.146,442,3.146,446,3.715,453,2.951,492,2.79,540,2.53,562,2.79,603,2.53,605,3.715,666,3.389,670,2.237,931,4.099,967,2.79,1058,2.651,1076,2.53,1078,2.53,1113,4.209,1114,5.846,1115,3.715]],["tags/253",[]],["title/254",[182,1.088,511,2.782,1091,3.05,1116,3.456]],["content/254",[0,0.26,4,0.931,6,1.153,8,3.304,108,2.554,123,2.996,155,3.14,156,1.351,159,3.034,166,1.614,182,2.306,206,4.399,211,1.57,261,3.14,281,1.424,352,3.725,354,2.869,443,3.725,445,2.308,561,4.014,624,4.014,704,4.014,763,4.399,788,3.725,974,3.725,1076,2.996,1081,3.725,1093,4.399,1103,4.014,1117,4.985,1118,4.985,1119,4.985]],["tags/254",[]],["title/255",[156,0.817,166,1.036]],["content/255",[0,0.311,3,1.641,4,0.812,6,0.942,22,1.556,37,2.152,38,2.152,83,0.989,96,2.883,120,2.139,124,2.768,129,2.403,146,3.839,150,1.157,156,0.756,164,1.185,166,1.506,182,2.43,195,2.312,196,1.951,211,1.37,212,3.05,224,2.312,257,2.883,281,1.708,309,2.014,335,3.064,373,2.883,405,2.084,414,2.615,416,2.615,442,3.251,453,3.05,492,2.883,516,2.503,621,3.502,667,2.74,860,2.229,861,3.251,977,4.47,1008,2.74,1042,3.05,1043,4.815,1081,3.251,1111,3.839]],["tags/255",[]],["title/256",[281,0.987,718,3.05,720,2.583,1043,2.782]],["content/256",[50,2.995,107,4.525,108,3.102,124,2.803,150,1.61,166,1.334,182,1.906,189,4.245,211,1.906,281,1.729,373,4.013,445,2.803,667,3.813,719,4.525,720,4.525,861,4.525,1081,4.525,1120,6.054,1121,6.054]],["tags/256",[]],["title/257",[4,0.645,93,0.727,156,0.6,310,1.34]],["content/257",[46,2.113,50,2.258,83,1.022,86,1.632,93,0.96,118,1.632,143,3.2,144,3.025,164,1.683,166,1.006,168,2.047,211,1.437,252,1.872,263,2.522,289,3.411,310,2.396,335,2.339,362,2.339,386,2.426,405,2.153,413,2.001,622,2.426,812,3.411,919,3.892,942,4.333,971,3.2,1008,4.413,1034,3.411,1052,3.675,1058,3.892,1064,3.675,1069,5.454,1070,4.028,1071,4.028,1072,4.028,1073,4.028,1074,4.028,1122,4.564,1123,4.564,1124,4.564,1125,4.564,1126,4.564]],["tags/257",[]],["title/258",[164,0.831,281,0.872,430,1.563,486,2.693,1061,2.139]],["content/258",[5,0.826,29,3.03,46,2,63,1.938,83,0.715,118,1.545,128,1.587,135,3.229,143,4.775,164,2.096,168,1.938,263,2.387,264,2.722,274,2.487,277,3.03,310,1.675,362,2.214,366,2.597,405,2.074,540,2.597,636,3.479,700,3.03,743,2.597,860,3.49,870,3.03,912,4.775,919,2.722,1008,2.722,1013,3.229,1036,3.229,1054,5.254,1055,5.254,1056,3.814,1057,3.479,1058,2.722,1059,3.479,1060,4.864,1061,4.174,1062,3.814,1063,3.814,1064,3.479,1065,3.479,1066,3.814,1067,3.814,1068,3.479]],["tags/258",[]],["title/259",[211,1.088,281,0.987,413,0.987,1061,2.423]],["content/259",[5,0.976,111,3.067,118,3.084,150,2.087,164,1.389,249,3.067,281,1.458,354,2.936,375,2.819,600,2.712,692,4.192,730,4.503,743,3.067,912,3.578,919,4.665,1057,4.108,1058,3.214,1060,3.382,1061,3.578,1068,4.108,1103,4.108,1127,5.102,1128,5.102,1129,5.102,1130,5.102,1131,5.102]],["tags/259",[]],["title/260",[281,1.343,430,2.41]],["content/260",[0,0.352,6,1.149,50,2.109,81,2.454,86,1.525,93,0.897,107,3.187,152,2.287,155,2.686,164,2.158,165,2.185,166,1.3,168,3.033,252,1.749,257,2.826,265,3.131,281,1.932,380,2.826,401,2.826,404,4.136,405,2.055,410,3.433,413,1.218,426,3.187,427,3.259,430,3.739,448,3.91,540,4.065,640,3.763,843,3.433,1008,2.686,1042,2.99,1044,3.763,1132,5.206,1133,4.264,1134,3.763]],["tags/260",[]],["title/261",[430,2.041,450,2.293,1135,3.516]],["content/261",[0,0.219,2,2.157,5,0.805,82,3.389,83,1.111,152,1.632,156,0.731,164,1.829,165,2.157,166,0.927,235,2.397,281,1.67,284,3.146,310,1.632,362,2.157,405,1.466,409,2.79,413,1.202,427,3.23,430,3.441,440,6.404,442,3.146,450,3.364,453,2.951,464,3.389,670,3.857,786,2.951,891,6.404,897,3.146,1008,2.651,1013,3.146,1058,2.651,1060,3.874,1065,3.389,1076,2.53,1086,3.715,1132,3.715,1134,3.715,1135,5.159,1136,4.209,1137,5.846,1138,4.209,1139,4.209,1140,4.209]],["tags/261",[]],["title/262",[116,4.15,117,2.326]],["content/262",[0,0.341,58,2.279,75,2.762,118,2.779,120,2.34,301,3.478,524,4.121,697,4.121,969,4.336,1096,4.889]],["tags/262",[]],["title/263",[75,1.986,118,1.682]],["content/263",[0,0.363,120,2.49,301,3.702,697,4.386,969,4.615]],["tags/263",[]],["title/264",[58,1.388,118,1.425,524,2.509]],["content/264",[1096,5.438]],["tags/264",[]],["title/265",[58,1.639,191,1.986]],["content/265",[]],["tags/265",[]],["title/266",[1096,4.288]],["content/266",[13,4.168,32,3.008,58,2.191,75,2.655,120,2.249,129,3.474,191,2.655,445,2.911,504,4.7,612,4.7,969,4.168,1141,7.589,1142,6.289,1143,4.41]],["tags/266",[]],["title/267",[31,2.077,32,1.653,83,0.572,973,3.05]],["content/267",[17,1.431,28,1.792,30,2.084,31,4.515,32,2.957,46,1.677,58,1.262,78,1.792,87,3.287,118,2.939,120,1.295,124,2.432,125,2.957,128,1.929,191,1.529,210,1.732,223,2.4,243,1.677,259,2.707,366,2.177,386,1.925,430,1.856,445,1.677,455,5.986,586,3.684,600,2.793,660,2.707,808,5.069,860,3.475,940,4.23,1106,3.196,1107,3.196,1143,5.267,1144,3.622,1145,3.622,1146,6.183,1147,6.183,1148,5.254,1149,6.183,1150,3.196,1151,3.622,1152,3.622,1153,3.622,1154,3.622]],["tags/267",[]],["title/268",[191,1.682,267,1.425,685,2.64]],["content/268",[28,2.357,30,2.742,31,2.864,32,2.279,70,3.341,83,1.052,118,2.561,124,2.206,128,2.336,152,1.847,191,2.686,267,2.275,278,3.341,427,2.633,622,2.533,657,3.837,685,4.746,692,3.001,754,3.837,860,3.26,974,3.561,1143,3.341,1155,7.161,1156,4.765,1157,4.765,1158,4.765,1159,4.765,1160,4.765,1161,4.765,1162,4.765,1163,4.765,1164,4.765,1165,4.765,1166,4.765,1167,4.765,1168,3.837,1169,4.765]],["tags/268",[]],["title/269",[32,1.905,58,1.388,191,1.682]],["content/269",[7,0.841,16,2.123,30,1.736,32,3.492,46,1.396,58,2.16,83,0.499,93,0.634,118,3.033,129,2.534,130,3.692,181,2.254,185,3.427,191,1.936,201,1.138,217,1.545,229,0.73,267,1.984,342,1.813,362,1.545,429,2.254,430,1.545,487,3.598,490,1.666,505,2.428,580,3.692,586,2.115,600,2.438,622,1.603,670,2.438,685,3.678,692,1.9,754,2.428,860,3.599,1115,4.047,1143,3.891,1150,2.662,1168,4.468,1170,3.016,1171,4.897,1172,3.016,1173,4.586,1174,4.586,1175,4.586,1176,4.586,1177,3.016,1178,3.016,1179,3.016,1180,4.586,1181,3.016,1182,3.016,1183,3.016,1184,3.016,1185,3.016,1186,3.016,1187,4.586,1188,4.586,1189,4.586,1190,3.016,1191,4.586,1192,3.016,1193,3.016]],["tags/269",[]],["title/270",[1194,5.064]],["content/270",[0,0.25,3,1.811,32,3.057,56,2.088,58,2.227,84,3.024,108,2.46,118,2.57,191,2.699,267,2.854,427,2.652,450,2.763,487,2.296,505,3.865,632,3.366,685,5.29,687,4.237,860,3.276,974,3.588,1143,4.483,1168,5.147,1171,4.237,1194,4.237,1195,4.801,1196,4.801,1197,4.801,1198,7.981]],["tags/270",[]],["title/271",[75,2.423]],["content/271",[0,0.432,75,3.095,120,2.622,301,3.159,697,3.744,969,3.939,1060,3.939,1098,5.245,1199,5.943,1200,5.943,1201,5.943,1202,5.943,1203,5.943,1204,5.943,1205,5.943,1206,5.943]],["tags/271",[]],["title/272",[642,2.962,1207,4.15]],["content/272",[0,0.301,11,4.056,17,1.575,28,3.566,72,3.329,111,3.477,126,5.105,223,3.834,300,4.323,314,4.323,335,2.964,408,5.055,461,4.657,462,4.657,547,4.657,642,3.643,757,5.105,790,5.105,1207,5.105,1208,5.785,1209,5.785,1210,5.785]],["tags/272",[]],["title/273",[622,3.05]],["content/273",[0,0.307,4,1.1,5,1.126,31,3.54,32,3.487,47,3.131,56,2.562,319,4.592,490,4.028,504,4.401,622,3.875,735,5.198,753,5.198,777,4.742,908,4.742,1211,5.89,1212,5.89,1213,5.89]],["tags/273",[]],["title/274",[7,1.312,87,2.5]],["content/274",[4,0.976,5,1.433,6,0.823,10,2.273,28,3.344,32,2.499,70,3.664,83,0.865,87,2.778,199,2.887,218,3.905,232,2.585,236,3.89,267,1.869,452,3.141,490,3.734,609,2.887,642,4.719,691,3.664,726,4.207,869,3.905,915,4.48,1035,5.965,1214,6.759,1215,5.226,1216,5.226]],["tags/274",[]],["title/275",[150,1.251,229,1.138]],["content/275",[0,0.165,3,1.193,5,1.215,6,0.498,12,0.926,22,1.131,28,2.825,68,1.7,72,1.82,84,1.992,86,1.131,93,1.335,117,1.565,139,1.901,142,2.791,150,1.689,153,1.901,155,2.994,201,1.193,208,1.901,210,2.274,215,1.992,223,2.096,232,1.565,242,2.791,243,1.464,252,2.342,261,2.994,295,1.82,305,2.218,309,2.201,310,1.843,336,1.82,338,2.791,351,1.747,366,2.858,368,2.627,387,2.364,405,2.213,413,1.814,438,2.791,451,2.791,452,1.901,470,2.791,490,1.747,507,2.364,538,2.547,603,3.433,604,2.547,609,2.627,610,2.096,642,1.992,674,2.791,691,2.218,696,2.218,706,2.791,710,3.553,719,2.364,726,2.547,807,2.791,827,2.547,830,2.547,849,4.599,850,2.547,851,4.196,894,2.096,896,2.791,897,2.364,1030,2.791,1217,3.163,1218,4.754,1219,3.163,1220,6.352,1221,3.163,1222,3.163,1223,2.791,1224,3.163,1225,3.163,1226,3.163]],["tags/275",[]],["title/276",[68,1.682,743,2.827]],["content/276",[28,3.111,120,2.714,319,3.961,428,4.168,622,4.034,642,3.961,743,3.78,876,5.063,883,5.55,915,4.168,1223,5.55,1227,6.289,1228,6.289]],["tags/276",[]]],"invertedIndex":[["",{"_index":118,"title":{"167":{},"170":{},"171":{},"243":{},"263":{},"264":{}},"content":{"166":{},"169":{},"199":{},"219":{},"228":{},"229":{},"234":{},"235":{},"241":{},"242":{},"257":{},"258":{},"259":{},"262":{},"267":{},"268":{},"269":{},"270":{}},"tags":{}}],["1",{"_index":185,"title":{},"content":{"173":{},"228":{},"229":{},"269":{}},"tags":{}}],["1.29",{"_index":1172,"title":{},"content":{"269":{}},"tags":{}}],["127.0.0.0/8",{"_index":947,"title":{},"content":{"229":{}},"tags":{}}],["127.0.0.2:4001",{"_index":1003,"title":{},"content":{"235":{}},"tags":{}}],["2",{"_index":77,"title":{},"content":{"163":{},"175":{},"196":{}},"tags":{}}],["203.0.113.34",{"_index":1068,"title":{},"content":{"241":{},"258":{},"259":{}},"tags":{}}],["3",{"_index":299,"title":{},"content":{"176":{}},"tags":{}}],["32049705",{"_index":1186,"title":{},"content":{"269":{}},"tags":{}}],["32238657",{"_index":1192,"title":{},"content":{"269":{}},"tags":{}}],["3rd",{"_index":923,"title":{},"content":{"228":{}},"tags":{}}],["45",{"_index":1193,"title":{},"content":{"269":{}},"tags":{}}],["60",{"_index":1066,"title":{},"content":{"241":{},"258":{}},"tags":{}}],["7890",{"_index":922,"title":{},"content":{"228":{}},"tags":{}}],["8001",{"_index":996,"title":{},"content":{"235":{}},"tags":{}}],["8080",{"_index":920,"title":{},"content":{"228":{},"235":{}},"tags":{}}],["9334",{"_index":163,"title":{},"content":{"169":{},"170":{},"172":{},"173":{},"175":{},"176":{}},"tags":{}}],["99dd77cbd7fe2c4e1f29511014c14054a21a376f7d58a48d50e9e036f4522f6b",{"_index":1131,"title":{},"content":{"259":{}},"tags":{}}],["9m47",{"_index":1190,"title":{},"content":{"269":{}},"tags":{}}],["_",{"_index":1015,"title":{},"content":{"235":{}},"tags":{}}],["abcdef",{"_index":868,"title":{},"content":{"219":{}},"tags":{}}],["abov",{"_index":657,"title":{},"content":{"202":{},"225":{},"268":{}},"tags":{}}],["absenc",{"_index":1222,"title":{},"content":{"275":{}},"tags":{}}],["accept",{"_index":485,"title":{},"content":{"194":{},"204":{}},"tags":{}}],["access",{"_index":46,"title":{},"content":{"163":{},"186":{},"198":{},"200":{},"201":{},"202":{},"204":{},"205":{},"235":{},"238":{},"241":{},"257":{},"258":{},"267":{},"269":{}},"tags":{}}],["accommod",{"_index":522,"title":{},"content":{"196":{}},"tags":{}}],["accompani",{"_index":599,"title":{},"content":{"199":{}},"tags":{}}],["account",{"_index":1142,"title":{},"content":{"266":{}},"tags":{}}],["accur",{"_index":388,"title":{},"content":{"185":{}},"tags":{}}],["achiev",{"_index":751,"title":{},"content":{"205":{}},"tags":{}}],["acknowledg",{"_index":729,"title":{},"content":{"204":{}},"tags":{}}],["acquir",{"_index":205,"title":{},"content":{"173":{}},"tags":{}}],["act",{"_index":167,"title":{},"content":{"169":{},"171":{},"176":{},"188":{},"199":{},"205":{},"210":{},"213":{}},"tags":{}}],["action",{"_index":114,"title":{},"content":{"165":{},"204":{}},"tags":{}}],["activ",{"_index":462,"title":{},"content":{"192":{},"197":{},"272":{}},"tags":{}}],["actual",{"_index":602,"title":{},"content":{"199":{},"251":{}},"tags":{}}],["ad",{"_index":271,"title":{},"content":{"175":{},"193":{},"196":{},"225":{},"226":{},"251":{}},"tags":{}}],["adapt",{"_index":779,"title":{},"content":{"207":{}},"tags":{}}],["add",{"_index":600,"title":{},"content":{"199":{},"202":{},"228":{},"229":{},"234":{},"235":{},"236":{},"251":{},"259":{},"267":{},"269":{}},"tags":{}}],["addit",{"_index":516,"title":{},"content":{"196":{},"199":{},"205":{},"217":{},"220":{},"234":{},"240":{},"251":{},"255":{}},"tags":{}}],["addition",{"_index":886,"title":{},"content":{"224":{}},"tags":{}}],["address",{"_index":144,"title":{},"content":{"168":{},"180":{},"228":{},"229":{},"241":{},"257":{}},"tags":{}}],["adher",{"_index":148,"title":{},"content":{"168":{},"169":{},"170":{},"172":{},"187":{},"208":{}},"tags":{}}],["admin",{"_index":57,"title":{},"content":{"163":{}},"tags":{}}],["administr",{"_index":59,"title":{},"content":{"163":{},"164":{},"200":{},"202":{}},"tags":{}}],["adopt",{"_index":564,"title":{},"content":{"197":{}},"tags":{}}],["advanc",{"_index":649,"title":{},"content":{"202":{},"205":{}},"tags":{}}],["affect",{"_index":1226,"title":{},"content":{"275":{}},"tags":{}}],["aforement",{"_index":683,"title":{},"content":{"204":{}},"tags":{}}],["afterward",{"_index":1152,"title":{},"content":{"267":{}},"tags":{}}],["ag",{"_index":1184,"title":{},"content":{"269":{}},"tags":{}}],["against",{"_index":355,"title":{},"content":{"180":{},"183":{},"184":{},"190":{},"202":{},"204":{},"214":{}},"tags":{}}],["agent",{"_index":256,"title":{},"content":{"175":{},"179":{},"194":{},"210":{},"214":{},"215":{},"216":{},"218":{},"223":{},"224":{}},"tags":{}}],["agent'",{"_index":836,"title":{},"content":{"216":{}},"tags":{}}],["agentservic",{"_index":814,"title":{},"content":{"214":{},"216":{}},"tags":{}}],["aim",{"_index":459,"title":{},"content":{"192":{},"205":{}},"tags":{}}],["ak",{"_index":32,"title":{"195":{},"267":{},"269":{}},"content":{"162":{},"195":{},"196":{},"213":{},"266":{},"267":{},"268":{},"269":{},"270":{},"273":{},"274":{}},"tags":{}}],["algorithm",{"_index":739,"title":{},"content":{"205":{}},"tags":{}}],["align",{"_index":346,"title":{},"content":{"180":{}},"tags":{}}],["allow",{"_index":125,"title":{},"content":{"168":{},"180":{},"186":{},"187":{},"190":{},"197":{},"198":{},"205":{},"207":{},"210":{},"223":{},"244":{},"253":{},"267":{}},"tags":{}}],["along",{"_index":593,"title":{},"content":{"199":{}},"tags":{}}],["alreadi",{"_index":1103,"title":{},"content":{"251":{},"254":{},"259":{}},"tags":{}}],["altern",{"_index":1055,"title":{},"content":{"241":{},"258":{}},"tags":{}}],["altogeth",{"_index":917,"title":{},"content":{"228":{}},"tags":{}}],["alway",{"_index":43,"title":{},"content":{"163":{},"228":{},"229":{},"235":{}},"tags":{}}],["amd",{"_index":268,"title":{},"content":{"175":{},"183":{},"199":{}},"tags":{}}],["amidst",{"_index":746,"title":{},"content":{"205":{}},"tags":{}}],["analog",{"_index":654,"title":{},"content":{"202":{}},"tags":{}}],["analyt",{"_index":761,"title":{},"content":{"205":{}},"tags":{}}],["annot",{"_index":266,"title":{"236":{},"251":{}},"content":{"175":{},"216":{},"234":{},"236":{},"251":{}},"tags":{}}],["anoth",{"_index":640,"title":{},"content":{"202":{},"260":{}},"tags":{}}],["answer",{"_index":175,"title":{},"content":{"172":{}},"tags":{}}],["anyth",{"_index":664,"title":{},"content":{"203":{}},"tags":{}}],["api",{"_index":336,"title":{},"content":{"179":{},"193":{},"194":{},"200":{},"203":{},"210":{},"225":{},"252":{},"275":{}},"tags":{}}],["apiserv",{"_index":859,"title":{},"content":{"219":{}},"tags":{}}],["apivers",{"_index":863,"title":{},"content":{"219":{},"228":{},"229":{}},"tags":{}}],["app",{"_index":786,"title":{},"content":{"208":{},"235":{},"244":{},"245":{},"261":{}},"tags":{}}],["app'",{"_index":791,"title":{},"content":{"208":{}},"tags":{}}],["appli",{"_index":199,"title":{"237":{}},"content":{"173":{},"216":{},"231":{},"232":{},"237":{},"249":{},"250":{},"253":{},"274":{}},"tags":{}}],["applic",{"_index":220,"title":{"175":{}},"content":{"177":{},"186":{},"196":{},"197":{},"199":{},"200":{},"201":{},"202":{},"205":{},"235":{},"253":{}},"tags":{}}],["apprais",{"_index":200,"title":{"178":{},"180":{}},"content":{"173":{},"175":{},"176":{},"180":{},"183":{}},"tags":{}}],["approach",{"_index":27,"title":{},"content":{"162":{},"186":{},"187":{}},"tags":{}}],["appropri",{"_index":476,"title":{},"content":{"193":{}},"tags":{}}],["approv",{"_index":573,"title":{},"content":{"198":{},"205":{}},"tags":{}}],["apps/v1",{"_index":924,"title":{},"content":{"228":{},"229":{}},"tags":{}}],["architectur",{"_index":131,"title":{"169":{},"173":{}},"content":{"168":{},"169":{},"170":{},"172":{},"173":{},"196":{},"198":{},"244":{}},"tags":{}}],["aren't",{"_index":387,"title":{},"content":{"185":{},"199":{},"204":{},"275":{}},"tags":{}}],["argument",{"_index":828,"title":{},"content":{"215":{},"217":{}},"tags":{}}],["aris",{"_index":1227,"title":{},"content":{"276":{}},"tags":{}}],["around",{"_index":313,"title":{},"content":{"179":{}},"tags":{}}],["artifact",{"_index":718,"title":{"256":{}},"content":{"204":{}},"tags":{}}],["ask",{"_index":357,"title":{"181":{}},"content":{"218":{}},"tags":{}}],["aspect",{"_index":598,"title":{},"content":{"199":{}},"tags":{}}],["assess",{"_index":198,"title":{},"content":{"173":{}},"tags":{}}],["assign",{"_index":188,"title":{},"content":{"173":{}},"tags":{}}],["associ",{"_index":773,"title":{},"content":{"205":{}},"tags":{}}],["assum",{"_index":693,"title":{},"content":{"204":{}},"tags":{}}],["assur",{"_index":402,"title":{},"content":{"187":{},"208":{}},"tags":{}}],["attach",{"_index":853,"title":{},"content":{"218":{}},"tags":{}}],["attack",{"_index":60,"title":{"202":{},"203":{}},"content":{"163":{},"199":{},"201":{},"202":{},"203":{},"204":{}},"tags":{}}],["attacker'",{"_index":665,"title":{},"content":{"203":{}},"tags":{}}],["attempt",{"_index":636,"title":{},"content":{"202":{},"241":{},"258":{}},"tags":{}}],["attest",{"_index":156,"title":{"170":{},"172":{},"173":{},"174":{},"175":{},"181":{},"182":{},"183":{},"184":{},"185":{},"186":{},"255":{},"257":{}},"content":{"169":{},"170":{},"172":{},"173":{},"174":{},"175":{},"176":{},"177":{},"179":{},"180":{},"182":{},"184":{},"185":{},"186":{},"187":{},"188":{},"191":{},"194":{},"196":{},"198":{},"199":{},"200":{},"202":{},"203":{},"204":{},"205":{},"207":{},"208":{},"209":{},"211":{},"218":{},"223":{},"239":{},"240":{},"245":{},"251":{},"252":{},"253":{},"254":{},"255":{},"261":{}},"tags":{}}],["attestation’",{"_index":539,"title":{},"content":{"196":{}},"tags":{}}],["attribut",{"_index":669,"title":{},"content":{"203":{}},"tags":{}}],["audit",{"_index":720,"title":{"256":{}},"content":{"204":{},"205":{},"256":{}},"tags":{}}],["authent",{"_index":308,"title":{"185":{}},"content":{"177":{},"179":{},"182":{},"184":{},"185":{},"196":{},"204":{},"207":{},"209":{},"228":{},"235":{},"253":{}},"tags":{}}],["author",{"_index":165,"title":{"171":{},"188":{}},"content":{"169":{},"171":{},"173":{},"183":{},"188":{},"194":{},"208":{},"235":{},"260":{},"261":{}},"tags":{}}],["automat",{"_index":412,"title":{},"content":{"188":{},"209":{},"210":{},"220":{},"226":{}},"tags":{}}],["avail",{"_index":622,"title":{"273":{}},"content":{"201":{},"203":{},"204":{},"244":{},"252":{},"257":{},"268":{},"269":{},"273":{},"276":{}},"tags":{}}],["aw",{"_index":517,"title":{},"content":{"196":{}},"tags":{}}],["awar",{"_index":892,"title":{},"content":{"225":{},"236":{}},"tags":{}}],["az",{"_index":1143,"title":{},"content":{"266":{},"267":{},"268":{},"269":{},"270":{}},"tags":{}}],["azclusternam",{"_index":1171,"title":{},"content":{"269":{},"270":{}},"tags":{}}],["azclustername=\"contrastdemo",{"_index":1170,"title":{},"content":{"269":{}},"tags":{}}],["azloc",{"_index":1169,"title":{},"content":{"268":{}},"tags":{}}],["azlocation=\"westu",{"_index":1167,"title":{},"content":{"268":{}},"tags":{}}],["azresourcegroup",{"_index":1168,"title":{},"content":{"268":{},"269":{},"270":{}},"tags":{}}],["azresourcegroup=\"contrastdemo",{"_index":1166,"title":{},"content":{"268":{}},"tags":{}}],["azur",{"_index":504,"title":{},"content":{"195":{},"196":{},"266":{},"273":{}},"tags":{}}],["azurelinux",{"_index":1174,"title":{},"content":{"269":{}},"tags":{}}],["b",{"_index":230,"title":{},"content":{"175":{}},"tags":{}}],["backdoor",{"_index":682,"title":{},"content":{"203":{}},"tags":{}}],["backend",{"_index":1005,"title":{},"content":{"235":{},"244":{}},"tags":{}}],["backend#127.0.0.2:4001#backend.default:4001",{"_index":1002,"title":{},"content":{"235":{}},"tags":{}}],["backend.default:4001",{"_index":999,"title":{},"content":{"235":{}},"tags":{}}],["balanc",{"_index":1036,"title":{},"content":{"238":{},"241":{},"252":{},"258":{}},"tags":{}}],["ballot",{"_index":1091,"title":{"254":{}},"content":{"245":{}},"tags":{}}],["bare",{"_index":488,"title":{},"content":{"194":{}},"tags":{}}],["base",{"_index":9,"title":{},"content":{"162":{},"163":{},"175":{},"176":{},"190":{},"193":{},"197":{},"199":{},"205":{},"208":{},"210":{},"226":{}},"tags":{}}],["base64",{"_index":831,"title":{},"content":{"216":{}},"tags":{}}],["basi",{"_index":826,"title":{},"content":{"215":{},"226":{}},"tags":{}}],["be",{"_index":1108,"title":{},"content":{"252":{}},"tags":{}}],["becom",{"_index":601,"title":{},"content":{"199":{}},"tags":{}}],["befor",{"_index":155,"title":{},"content":{"168":{},"205":{},"211":{},"251":{},"254":{},"260":{},"275":{}},"tags":{}}],["begin",{"_index":521,"title":{},"content":{"196":{}},"tags":{}}],["below",{"_index":219,"title":{},"content":{"174":{},"175":{}},"tags":{}}],["benefici",{"_index":558,"title":{},"content":{"197":{},"228":{}},"tags":{}}],["benefit",{"_index":88,"title":{"184":{}},"content":{"164":{},"165":{},"172":{},"184":{},"196":{}},"tags":{}}],["between",{"_index":351,"title":{},"content":{"180":{},"188":{},"198":{},"203":{},"204":{},"208":{},"231":{},"249":{},"251":{},"275":{}},"tags":{}}],["beyond",{"_index":514,"title":{},"content":{"196":{}},"tags":{}}],["bill",{"_index":956,"title":{},"content":{"229":{}},"tags":{}}],["billing#127.137.0.1:8081#bil",{"_index":959,"title":{},"content":{"229":{}},"tags":{}}],["binari",{"_index":690,"title":{},"content":{"204":{},"222":{}},"tags":{}}],["blind",{"_index":847,"title":{},"content":{"217":{},"236":{}},"tags":{}}],["block",{"_index":456,"title":{},"content":{"192":{},"223":{},"237":{}},"tags":{}}],["board",{"_index":1084,"title":{},"content":{"244":{}},"tags":{}}],["bot",{"_index":1086,"title":{},"content":{"244":{},"261":{}},"tags":{}}],["both",{"_index":535,"title":{},"content":{"196":{},"199":{},"235":{},"245":{}},"tags":{}}],["bound",{"_index":307,"title":{},"content":{"177":{},"191":{}},"tags":{}}],["breach",{"_index":749,"title":{},"content":{"205":{}},"tags":{}}],["break",{"_index":647,"title":{},"content":{"202":{}},"tags":{}}],["bring",{"_index":721,"title":{},"content":{"204":{}},"tags":{}}],["browser",{"_index":1126,"title":{},"content":{"257":{}},"tags":{}}],["bug",{"_index":1215,"title":{},"content":{"274":{}},"tags":{}}],["build",{"_index":304,"title":{},"content":{"176":{},"180":{},"192":{},"234":{}},"tags":{}}],["built",{"_index":300,"title":{},"content":{"176":{},"180":{},"185":{},"272":{}},"tags":{}}],["c",{"_index":257,"title":{},"content":{"175":{},"239":{},"240":{},"252":{},"255":{},"260":{}},"tags":{}}],["ca",{"_index":168,"title":{},"content":{"169":{},"171":{},"177":{},"186":{},"188":{},"189":{},"190":{},"191":{},"208":{},"228":{},"229":{},"235":{},"241":{},"257":{},"258":{},"260":{}},"tags":{}}],["ca.pem",{"_index":1008,"title":{},"content":{"235":{},"241":{},"255":{},"257":{},"258":{},"260":{},"261":{}},"tags":{}}],["cacert",{"_index":1013,"title":{},"content":{"235":{},"241":{},"258":{},"261":{}},"tags":{}}],["cacerts.appendcertsfrompem(cacert",{"_index":1018,"title":{},"content":{"235":{}},"tags":{}}],["cafil",{"_index":1071,"title":{},"content":{"241":{},"257":{}},"tags":{}}],["calcul",{"_index":834,"title":{},"content":{"216":{}},"tags":{}}],["call",{"_index":475,"title":{},"content":{"193":{},"194":{},"214":{},"216":{},"221":{}},"tags":{}}],["can't",{"_index":710,"title":{},"content":{"204":{},"236":{},"238":{},"275":{}},"tags":{}}],["capabl",{"_index":483,"title":{},"content":{"193":{},"195":{},"197":{},"205":{},"228":{},"229":{}},"tags":{}}],["care",{"_index":260,"title":{},"content":{"175":{},"212":{}},"tags":{}}],["carri",{"_index":888,"title":{},"content":{"225":{}},"tags":{}}],["cart",{"_index":958,"title":{},"content":{"229":{}},"tags":{}}],["case",{"_index":84,"title":{"164":{}},"content":{"164":{},"191":{},"193":{},"205":{},"270":{},"275":{}},"tags":{}}],["categori",{"_index":686,"title":{},"content":{"204":{}},"tags":{}}],["cc",{"_index":867,"title":{},"content":{"219":{},"221":{},"225":{},"228":{},"229":{},"231":{},"234":{},"249":{},"251":{}},"tags":{}}],["central",{"_index":780,"title":{},"content":{"208":{}},"tags":{}}],["centralindia",{"_index":1156,"title":{},"content":{"268":{}},"tags":{}}],["cert",{"_index":932,"title":{},"content":{"228":{},"229":{},"234":{},"235":{},"239":{}},"tags":{}}],["certain",{"_index":1223,"title":{},"content":{"275":{},"276":{}},"tags":{}}],["certchain.pem",{"_index":1007,"title":{},"content":{"235":{}},"tags":{}}],["certif",{"_index":164,"title":{"171":{},"188":{},"190":{},"191":{},"258":{}},"content":{"169":{},"171":{},"177":{},"186":{},"188":{},"189":{},"190":{},"191":{},"196":{},"204":{},"208":{},"211":{},"213":{},"218":{},"226":{},"228":{},"229":{},"234":{},"235":{},"239":{},"240":{},"241":{},"251":{},"253":{},"255":{},"257":{},"258":{},"259":{},"260":{},"261":{}},"tags":{}}],["certifi",{"_index":360,"title":{},"content":{"182":{}},"tags":{}}],["cfg",{"_index":1022,"title":{},"content":{"235":{}},"tags":{}}],["chain",{"_index":448,"title":{},"content":{"191":{},"198":{},"204":{},"228":{},"229":{},"260":{}},"tags":{}}],["challeng",{"_index":556,"title":{},"content":{"197":{},"203":{}},"tags":{}}],["chang",{"_index":81,"title":{},"content":{"163":{},"184":{},"191":{},"202":{},"203":{},"204":{},"233":{},"235":{},"260":{}},"tags":{}}],["channel",{"_index":621,"title":{},"content":{"201":{},"208":{},"255":{}},"tags":{}}],["chapter",{"_index":882,"title":{},"content":{"223":{},"235":{}},"tags":{}}],["chart",{"_index":529,"title":{},"content":{"196":{},"234":{}},"tags":{}}],["chart_nam",{"_index":982,"title":{},"content":{"234":{}},"tags":{}}],["check",{"_index":366,"title":{},"content":{"183":{},"214":{},"215":{},"217":{},"241":{},"258":{},"267":{},"275":{}},"tags":{}}],["checksum",{"_index":502,"title":{},"content":{"194":{},"215":{},"216":{}},"tags":{}}],["chip",{"_index":317,"title":{},"content":{"179":{}},"tags":{}}],["choos",{"_index":913,"title":{},"content":{"228":{},"229":{}},"tags":{}}],["cidr",{"_index":948,"title":{},"content":{"229":{}},"tags":{}}],["claim",{"_index":286,"title":{},"content":{"176":{}},"tags":{}}],["clariti",{"_index":1012,"title":{},"content":{"235":{}},"tags":{}}],["class",{"_index":778,"title":{},"content":{"207":{},"212":{},"219":{},"225":{},"251":{}},"tags":{}}],["clean",{"_index":1196,"title":{},"content":{"270":{}},"tags":{}}],["cleanup",{"_index":1194,"title":{"270":{}},"content":{"270":{}},"tags":{}}],["clear",{"_index":1210,"title":{},"content":{"272":{}},"tags":{}}],["cli",{"_index":120,"title":{"168":{},"176":{},"207":{}},"content":{"166":{},"167":{},"168":{},"176":{},"177":{},"180":{},"207":{},"209":{},"210":{},"215":{},"218":{},"240":{},"246":{},"252":{},"255":{},"262":{},"263":{},"266":{},"267":{},"271":{},"276":{}},"tags":{}}],["cli'",{"_index":348,"title":{},"content":{"180":{}},"tags":{}}],["client",{"_index":407,"title":{},"content":{"188":{},"202":{},"203":{},"205":{},"228":{},"229":{},"235":{},"253":{}},"tags":{}}],["clientauth",{"_index":1026,"title":{},"content":{"235":{}},"tags":{}}],["clientca",{"_index":1028,"title":{},"content":{"235":{}},"tags":{}}],["cloud",{"_index":56,"title":{"222":{}},"content":{"163":{},"164":{},"184":{},"194":{},"196":{},"197":{},"199":{},"200":{},"202":{},"203":{},"205":{},"212":{},"222":{},"225":{},"270":{},"273":{}},"tags":{}}],["cluster",{"_index":58,"title":{"264":{},"265":{},"269":{}},"content":{"163":{},"164":{},"176":{},"195":{},"196":{},"199":{},"200":{},"207":{},"208":{},"212":{},"230":{},"231":{},"232":{},"237":{},"246":{},"249":{},"250":{},"262":{},"266":{},"267":{},"269":{},"270":{}},"tags":{}}],["cmdline",{"_index":248,"title":{},"content":{"175":{}},"tags":{}}],["cncf",{"_index":457,"title":{},"content":{"192":{}},"tags":{}}],["co",{"_index":65,"title":{},"content":{"163":{},"184":{},"202":{},"205":{}},"tags":{}}],["coco",{"_index":30,"title":{"195":{}},"content":{"162":{},"192":{},"195":{},"230":{},"238":{},"267":{},"268":{},"269":{}},"tags":{}}],["coco'",{"_index":482,"title":{},"content":{"193":{}},"tags":{}}],["code",{"_index":96,"title":{},"content":{"164":{},"180":{},"185":{},"201":{},"204":{},"255":{}},"tags":{}}],["collabor",{"_index":106,"title":{},"content":{"164":{}},"tags":{}}],["collect",{"_index":138,"title":{},"content":{"168":{},"176":{}},"tags":{}}],["combin",{"_index":740,"title":{},"content":{"205":{},"208":{},"215":{}},"tags":{}}],["come",{"_index":61,"title":{},"content":{"163":{}},"tags":{}}],["command",{"_index":124,"title":{"207":{}},"content":{"166":{},"167":{},"168":{},"179":{},"194":{},"215":{},"217":{},"236":{},"240":{},"251":{},"255":{},"256":{},"267":{},"268":{}},"tags":{}}],["commandlin",{"_index":885,"title":{},"content":{"224":{}},"tags":{}}],["common",{"_index":176,"title":{},"content":{"172":{}},"tags":{}}],["commun",{"_index":395,"title":{"241":{}},"content":{"186":{},"194":{},"196":{},"202":{},"208":{},"226":{},"251":{},"253":{}},"tags":{}}],["compani",{"_index":742,"title":{},"content":{"205":{}},"tags":{}}],["compat",{"_index":73,"title":{},"content":{"163":{},"196":{}},"tags":{}}],["complex",{"_index":676,"title":{},"content":{"203":{}},"tags":{}}],["complianc",{"_index":103,"title":{},"content":{"164":{},"197":{},"205":{}},"tags":{}}],["compon",{"_index":216,"title":{"174":{},"199":{},"206":{},"220":{}},"content":{"174":{},"175":{},"179":{},"180":{},"187":{},"196":{},"199":{},"200":{},"204":{},"205":{},"206":{},"220":{},"223":{},"251":{}},"tags":{}}],["compos",{"_index":774,"title":{},"content":{"206":{}},"tags":{}}],["composit",{"_index":292,"title":{},"content":{"176":{}},"tags":{}}],["comprehens",{"_index":321,"title":{},"content":{"179":{},"187":{}},"tags":{}}],["compris",{"_index":970,"title":{},"content":{"232":{},"250":{}},"tags":{}}],["compromis",{"_index":380,"title":{},"content":{"184":{},"196":{},"198":{},"199":{},"202":{},"260":{}},"tags":{}}],["comput",{"_index":38,"title":{"198":{}},"content":{"162":{},"163":{},"164":{},"182":{},"192":{},"193":{},"198":{},"199":{},"201":{},"218":{},"245":{},"255":{}},"tags":{}}],["concept",{"_index":110,"title":{},"content":{"165":{},"196":{}},"tags":{}}],["conceptu",{"_index":186,"title":{},"content":{"173":{}},"tags":{}}],["concern",{"_index":748,"title":{},"content":{"205":{}},"tags":{}}],["concis",{"_index":533,"title":{},"content":{"196":{},"199":{},"208":{}},"tags":{}}],["concret",{"_index":684,"title":{},"content":{"204":{}},"tags":{}}],["confidenti",{"_index":4,"title":{"192":{},"198":{},"243":{},"244":{},"257":{}},"content":{"162":{},"164":{},"165":{},"175":{},"176":{},"182":{},"192":{},"193":{},"194":{},"196":{},"197":{},"198":{},"199":{},"200":{},"201":{},"202":{},"203":{},"204":{},"205":{},"206":{},"208":{},"209":{},"210":{},"213":{},"214":{},"216":{},"218":{},"219":{},"222":{},"229":{},"230":{},"231":{},"233":{},"234":{},"235":{},"238":{},"242":{},"244":{},"245":{},"246":{},"249":{},"251":{},"254":{},"255":{},"273":{},"274":{}},"tags":{}}],["config",{"_index":934,"title":{},"content":{"228":{},"229":{},"234":{},"235":{}},"tags":{}}],["config/certchain.pem",{"_index":1020,"title":{},"content":{"235":{}},"tags":{}}],["config/key.pem",{"_index":1021,"title":{},"content":{"235":{}},"tags":{}}],["config/mesh",{"_index":1017,"title":{},"content":{"235":{}},"tags":{}}],["configmap",{"_index":827,"title":{},"content":{"215":{},"217":{},"275":{}},"tags":{}}],["configur",{"_index":211,"title":{"227":{},"259":{}},"content":{"173":{},"175":{},"176":{},"183":{},"190":{},"194":{},"196":{},"198":{},"199":{},"204":{},"207":{},"208":{},"209":{},"213":{},"220":{},"226":{},"227":{},"229":{},"234":{},"235":{},"251":{},"252":{},"253":{},"254":{},"255":{},"256":{},"257":{}},"tags":{}}],["confin",{"_index":766,"title":{},"content":{"205":{}},"tags":{}}],["confirm",{"_index":361,"title":{},"content":{"182":{},"184":{}},"tags":{}}],["connect",{"_index":310,"title":{"238":{},"257":{}},"content":{"177":{},"186":{},"188":{},"190":{},"196":{},"202":{},"203":{},"204":{},"226":{},"228":{},"229":{},"235":{},"238":{},"241":{},"252":{},"257":{},"258":{},"261":{},"275":{}},"tags":{}}],["consequ",{"_index":438,"title":{},"content":{"190":{},"275":{}},"tags":{}}],["consid",{"_index":1089,"title":{},"content":{"245":{}},"tags":{}}],["consist",{"_index":398,"title":{},"content":{"187":{},"209":{},"212":{},"214":{},"220":{},"223":{},"224":{},"231":{},"244":{},"249":{}},"tags":{}}],["constitut",{"_index":829,"title":{},"content":{"215":{}},"tags":{}}],["constrain",{"_index":641,"title":{},"content":{"202":{}},"tags":{}}],["contain",{"_index":5,"title":{"192":{},"194":{}},"content":{"162":{},"164":{},"165":{},"175":{},"176":{},"179":{},"189":{},"190":{},"191":{},"192":{},"193":{},"194":{},"196":{},"199":{},"200":{},"202":{},"203":{},"204":{},"206":{},"208":{},"210":{},"211":{},"213":{},"215":{},"217":{},"218":{},"219":{},"223":{},"224":{},"226":{},"227":{},"228":{},"229":{},"233":{},"234":{},"235":{},"236":{},"238":{},"239":{},"241":{},"246":{},"251":{},"258":{},"259":{},"261":{},"273":{},"274":{},"275":{}},"tags":{}}],["container'",{"_index":254,"title":{},"content":{"175":{},"204":{},"217":{}},"tags":{}}],["containerd",{"_index":473,"title":{"221":{}},"content":{"193":{},"212":{},"218":{},"219":{},"221":{},"222":{},"223":{},"225":{}},"tags":{}}],["containerport",{"_index":944,"title":{},"content":{"228":{}},"tags":{}}],["containers/issues/1693",{"_index":1041,"title":{},"content":{"238":{}},"tags":{}}],["containers/kata",{"_index":1040,"title":{},"content":{"238":{}},"tags":{}}],["containerservic",{"_index":1154,"title":{},"content":{"267":{}},"tags":{}}],["contamin",{"_index":572,"title":{},"content":{"198":{}},"tags":{}}],["content",{"_index":237,"title":{},"content":{"175":{},"202":{},"224":{}},"tags":{}}],["context",{"_index":590,"title":{},"content":{"199":{}},"tags":{}}],["contractor",{"_index":629,"title":{},"content":{"202":{}},"tags":{}}],["contrast",{"_index":0,"title":{"162":{},"172":{},"181":{},"182":{},"183":{},"197":{},"199":{},"200":{},"212":{},"219":{},"231":{},"232":{},"238":{},"247":{},"249":{},"250":{}},"content":{"162":{},"163":{},"164":{},"165":{},"166":{},"167":{},"168":{},"169":{},"170":{},"172":{},"173":{},"174":{},"175":{},"176":{},"177":{},"179":{},"180":{},"182":{},"183":{},"185":{},"187":{},"192":{},"195":{},"196":{},"197":{},"198":{},"199":{},"200":{},"201":{},"202":{},"204":{},"205":{},"206":{},"207":{},"208":{},"209":{},"210":{},"211":{},"212":{},"213":{},"215":{},"218":{},"219":{},"221":{},"223":{},"225":{},"226":{},"228":{},"229":{},"230":{},"231":{},"232":{},"234":{},"235":{},"236":{},"239":{},"240":{},"244":{},"246":{},"248":{},"249":{},"250":{},"251":{},"252":{},"253":{},"254":{},"255":{},"260":{},"261":{},"262":{},"263":{},"270":{},"271":{},"272":{},"273":{},"275":{}},"tags":{}}],["contrast'",{"_index":172,"title":{"174":{},"205":{}},"content":{"172":{},"175":{},"177":{},"185":{},"186":{},"187":{},"188":{},"198":{},"204":{}},"tags":{}}],["control",{"_index":587,"title":{},"content":{"199":{},"201":{},"202":{},"203":{},"204":{}},"tags":{}}],["convers",{"_index":962,"title":{},"content":{"229":{}},"tags":{}}],["convey",{"_index":296,"title":{},"content":{"176":{}},"tags":{}}],["coordin",{"_index":166,"title":{"176":{},"208":{},"232":{},"238":{},"240":{},"250":{},"255":{}},"content":{"169":{},"171":{},"176":{},"180":{},"188":{},"189":{},"190":{},"191":{},"199":{},"200":{},"203":{},"204":{},"207":{},"208":{},"209":{},"213":{},"218":{},"226":{},"228":{},"229":{},"231":{},"232":{},"234":{},"237":{},"238":{},"239":{},"240":{},"249":{},"250":{},"252":{},"253":{},"254":{},"255":{},"256":{},"257":{},"260":{},"261":{}},"tags":{}}],["coordinator'",{"_index":289,"title":{},"content":{"176":{},"208":{},"241":{},"257":{}},"tags":{}}],["coordinator:1313",{"_index":1109,"title":{},"content":{"252":{}},"tags":{}}],["coordinator=$(kubectl",{"_index":1033,"title":{},"content":{"238":{},"252":{}},"tags":{}}],["coordinator_host",{"_index":930,"title":{},"content":{"228":{},"229":{},"234":{}},"tags":{}}],["coordinator}:1313",{"_index":1042,"title":{},"content":{"239":{},"240":{},"252":{},"255":{},"260":{}},"tags":{}}],["coordinator’",{"_index":349,"title":{},"content":{"180":{}},"tags":{}}],["copi",{"_index":976,"title":{},"content":{"234":{}},"tags":{}}],["core",{"_index":89,"title":{},"content":{"164":{},"192":{},"206":{}},"tags":{}}],["correct",{"_index":840,"title":{},"content":{"217":{}},"tags":{}}],["correspond",{"_index":239,"title":{},"content":{"175":{},"217":{},"225":{}},"tags":{}}],["count",{"_index":1176,"title":{},"content":{"269":{}},"tags":{}}],["counter",{"_index":548,"title":{},"content":{"197":{}},"tags":{}}],["cover",{"_index":1218,"title":{},"content":{"275":{}},"tags":{}}],["coverag",{"_index":1217,"title":{},"content":{"275":{}},"tags":{}}],["cp",{"_index":983,"title":{},"content":{"234":{}},"tags":{}}],["cpu",{"_index":226,"title":{},"content":{"175":{},"179":{},"199":{}},"tags":{}}],["cpu'",{"_index":323,"title":{},"content":{"179":{}},"tags":{}}],["creat",{"_index":191,"title":{"265":{},"268":{},"269":{}},"content":{"173":{},"194":{},"200":{},"204":{},"218":{},"222":{},"236":{},"246":{},"251":{},"252":{},"266":{},"267":{},"268":{},"269":{},"270":{}},"tags":{}}],["credenti",{"_index":1115,"title":{},"content":{"253":{},"269":{}},"tags":{}}],["cri",{"_index":472,"title":{},"content":{"193":{},"238":{}},"tags":{}}],["critic",{"_index":315,"title":{},"content":{"179":{},"184":{},"198":{}},"tags":{}}],["cross",{"_index":571,"title":{},"content":{"198":{}},"tags":{}}],["crucial",{"_index":338,"title":{},"content":{"179":{},"275":{}},"tags":{}}],["crun",{"_index":481,"title":{},"content":{"193":{}},"tags":{}}],["crypto",{"_index":677,"title":{},"content":{"203":{}},"tags":{}}],["cryptograph",{"_index":221,"title":{},"content":{"175":{},"183":{},"185":{},"215":{}},"tags":{}}],["csp",{"_index":630,"title":{},"content":{"202":{}},"tags":{}}],["curl",{"_index":1060,"title":{},"content":{"241":{},"248":{},"258":{},"259":{},"261":{},"271":{}},"tags":{}}],["currenc",{"_index":961,"title":{},"content":{"229":{}},"tags":{}}],["current",{"_index":28,"title":{},"content":{"162":{},"175":{},"183":{},"204":{},"209":{},"217":{},"236":{},"267":{},"268":{},"272":{},"274":{},"275":{},"276":{}},"tags":{}}],["custom",{"_index":750,"title":{},"content":{"205":{},"221":{},"231":{},"235":{},"249":{}},"tags":{}}],["cvm",{"_index":498,"title":{},"content":{"194":{},"195":{},"218":{}},"tags":{}}],["daemonset",{"_index":802,"title":{"225":{}},"content":{"212":{},"220":{},"225":{},"231":{},"249":{}},"tags":{}}],["data",{"_index":42,"title":{"177":{}},"content":{"163":{},"164":{},"166":{},"167":{},"168":{},"177":{},"179":{},"184":{},"186":{},"190":{},"191":{},"196":{},"197":{},"198":{},"200":{},"202":{},"204":{},"205":{},"214":{},"215":{},"217":{},"240":{},"245":{}},"tags":{}}],["datacent",{"_index":53,"title":{},"content":{"163":{},"199":{},"202":{}},"tags":{}}],["day",{"_index":76,"title":{},"content":{"163":{},"196":{}},"tags":{}}],["decid",{"_index":763,"title":{},"content":{"205":{},"254":{}},"tags":{}}],["decis",{"_index":209,"title":{},"content":{"173":{},"186":{}},"tags":{}}],["decreas",{"_index":579,"title":{},"content":{"199":{}},"tags":{}}],["default",{"_index":870,"title":{},"content":{"219":{},"221":{},"228":{},"241":{},"258":{}},"tags":{}}],["defend",{"_index":626,"title":{},"content":{"202":{}},"tags":{}}],["defens",{"_index":680,"title":{},"content":{"203":{},"205":{}},"tags":{}}],["defin",{"_index":282,"title":{},"content":{"176":{},"183":{},"188":{},"190":{},"198":{},"199":{},"205":{},"209":{},"210":{},"219":{},"253":{}},"tags":{}}],["definit",{"_index":158,"title":{},"content":{"169":{},"170":{},"172":{},"173":{},"194":{},"215":{},"216":{},"218":{},"234":{},"235":{},"238":{}},"tags":{}}],["deleg",{"_index":1120,"title":{},"content":{"256":{}},"tags":{}}],["delet",{"_index":1198,"title":{},"content":{"270":{}},"tags":{}}],["demand",{"_index":760,"title":{},"content":{"205":{}},"tags":{}}],["demo",{"_index":1059,"title":{},"content":{"241":{},"251":{},"258":{}},"tags":{}}],["demo.zip",{"_index":1100,"title":{},"content":{"248":{}},"tags":{}}],["denial",{"_index":623,"title":{},"content":{"201":{},"204":{}},"tags":{}}],["depend",{"_index":428,"title":{},"content":{"190":{},"212":{},"231":{},"235":{},"249":{},"276":{}},"tags":{}}],["depict",{"_index":591,"title":{},"content":{"199":{}},"tags":{}}],["deploy",{"_index":6,"title":{"199":{},"200":{},"230":{},"231":{},"232":{},"247":{},"248":{},"249":{},"250":{},"253":{}},"content":{"162":{},"163":{},"175":{},"176":{},"180":{},"182":{},"183":{},"187":{},"188":{},"190":{},"195":{},"196":{},"197":{},"199":{},"200":{},"202":{},"203":{},"204":{},"205":{},"206":{},"207":{},"208":{},"209":{},"210":{},"213":{},"219":{},"225":{},"228":{},"229":{},"230":{},"231":{},"232":{},"234":{},"236":{},"238":{},"240":{},"244":{},"248":{},"249":{},"250":{},"251":{},"252":{},"253":{},"254":{},"255":{},"260":{},"274":{},"275":{}},"tags":{}}],["deployment'",{"_index":782,"title":{},"content":{"208":{}},"tags":{}}],["deployment/emoji",{"_index":1136,"title":{},"content":{"261":{}},"tags":{}}],["deployment/vot",{"_index":1137,"title":{},"content":{"261":{}},"tags":{}}],["deployment/web",{"_index":1138,"title":{},"content":{"261":{}},"tags":{}}],["depth",{"_index":736,"title":{},"content":{"205":{}},"tags":{}}],["deriv",{"_index":503,"title":{},"content":{"194":{},"215":{}},"tags":{}}],["describ",{"_index":157,"title":{},"content":{"169":{},"170":{},"172":{},"198":{},"201":{},"203":{},"204":{},"205":{},"221":{},"224":{}},"tags":{}}],["descript",{"_index":171,"title":{},"content":{"172":{},"228":{}},"tags":{}}],["design",{"_index":40,"title":{},"content":{"163":{},"194":{},"196":{},"197":{},"202":{},"205":{},"207":{}},"tags":{}}],["destin",{"_index":904,"title":{},"content":{"228":{}},"tags":{}}],["detail",{"_index":170,"title":{},"content":{"172":{},"174":{},"175":{},"179":{},"184":{},"198":{},"221":{},"235":{},"236":{}},"tags":{}}],["detect",{"_index":372,"title":{},"content":{"184":{},"198":{},"204":{}},"tags":{}}],["dev/nul",{"_index":1074,"title":{},"content":{"241":{},"257":{}},"tags":{}}],["develop",{"_index":408,"title":{},"content":{"188":{},"192":{},"202":{},"205":{},"272":{}},"tags":{}}],["devic",{"_index":293,"title":{},"content":{"176":{},"202":{},"223":{}},"tags":{}}],["diagram",{"_index":585,"title":{},"content":{"199":{},"200":{}},"tags":{}}],["dictat",{"_index":334,"title":{},"content":{"179":{}},"tags":{}}],["differ",{"_index":409,"title":{"191":{}},"content":{"188":{},"229":{},"244":{},"251":{},"261":{}},"tags":{}}],["digest",{"_index":325,"title":{},"content":{"179":{},"209":{},"218":{}},"tags":{}}],["direct",{"_index":772,"title":{},"content":{"205":{}},"tags":{}}],["directli",{"_index":507,"title":{},"content":{"195":{},"201":{},"235":{},"275":{}},"tags":{}}],["directori",{"_index":977,"title":{},"content":{"234":{},"240":{},"248":{},"255":{}},"tags":{}}],["disabl",{"_index":151,"title":{},"content":{"168":{},"228":{}},"tags":{}}],["discrep",{"_index":350,"title":{},"content":{"180":{},"204":{}},"tags":{}}],["disk",{"_index":634,"title":{},"content":{"202":{},"203":{},"204":{},"225":{}},"tags":{}}],["dispatch",{"_index":474,"title":{},"content":{"193":{}},"tags":{}}],["distribut",{"_index":704,"title":{},"content":{"204":{},"208":{},"254":{}},"tags":{}}],["distrust",{"_index":614,"title":{},"content":{"200":{}},"tags":{}}],["dm",{"_index":250,"title":{},"content":{"175":{},"179":{},"204":{},"215":{},"223":{}},"tags":{}}],["dn",{"_index":1057,"title":{},"content":{"241":{},"258":{},"259":{}},"tags":{}}],["do",{"_index":624,"title":{},"content":{"201":{},"204":{},"254":{}},"tags":{}}],["do_not_track=1",{"_index":154,"title":{},"content":{"168":{}},"tags":{}}],["document",{"_index":2,"title":{},"content":{"162":{},"169":{},"170":{},"172":{},"191":{},"197":{},"201":{},"205":{},"216":{},"221":{},"235":{},"261":{}},"tags":{}}],["doesn't",{"_index":137,"title":{},"content":{"168":{},"190":{},"204":{},"216":{},"235":{}},"tags":{}}],["don't",{"_index":538,"title":{},"content":{"196":{},"217":{},"275":{}},"tags":{}}],["done",{"_index":542,"title":{},"content":{"196":{}},"tags":{}}],["down",{"_index":722,"title":{},"content":{"204":{}},"tags":{}}],["download",{"_index":697,"title":{"248":{}},"content":{"204":{},"215":{},"248":{},"262":{},"263":{},"271":{}},"tags":{}}],["drop",{"_index":992,"title":{},"content":{"235":{}},"tags":{}}],["dual",{"_index":290,"title":{},"content":{"176":{}},"tags":{}}],["dump",{"_index":662,"title":{},"content":{"203":{}},"tags":{}}],["dure",{"_index":233,"title":{},"content":{"175":{},"176":{},"180":{},"191":{},"198":{},"199":{},"205":{},"208":{},"252":{}},"tags":{}}],["e.g",{"_index":1204,"title":{},"content":{"271":{}},"tags":{}}],["each",{"_index":347,"title":{},"content":{"180":{},"187":{},"198":{},"199":{},"205":{},"214":{},"215":{},"225":{},"231":{},"249":{}},"tags":{}}],["earli",{"_index":1208,"title":{},"content":{"272":{}},"tags":{}}],["easi",{"_index":789,"title":{},"content":{"208":{}},"tags":{}}],["easili",{"_index":724,"title":{},"content":{"204":{}},"tags":{}}],["eastu",{"_index":1157,"title":{},"content":{"268":{}},"tags":{}}],["eastus2euap",{"_index":1158,"title":{},"content":{"268":{}},"tags":{}}],["eavesdrop",{"_index":709,"title":{},"content":{"204":{}},"tags":{}}],["echo",{"_index":1052,"title":{},"content":{"241":{},"252":{},"257":{}},"tags":{}}],["edg",{"_index":1219,"title":{},"content":{"275":{}},"tags":{}}],["edg_egress_proxy_config",{"_index":899,"title":{},"content":{"227":{},"229":{},"235":{}},"tags":{}}],["edg_ingress_proxy_config",{"_index":898,"title":{},"content":{"227":{},"228":{},"235":{}},"tags":{}}],["edgeless",{"_index":122,"title":{},"content":{"166":{},"167":{},"168":{}},"tags":{}}],["edit",{"_index":1127,"title":{},"content":{"259":{}},"tags":{}}],["editor",{"_index":1129,"title":{},"content":{"259":{}},"tags":{}}],["effect",{"_index":231,"title":{},"content":{"175":{},"184":{},"199":{},"204":{},"205":{},"206":{}},"tags":{}}],["egress",{"_index":946,"title":{"229":{}},"content":{"229":{}},"tags":{}}],["ek",{"_index":518,"title":{},"content":{"196":{}},"tags":{}}],["element",{"_index":582,"title":{},"content":{"199":{}},"tags":{}}],["embed",{"_index":212,"title":{},"content":{"173":{},"180":{},"240":{},"252":{},"255":{}},"tags":{}}],["emoji",{"_index":1075,"title":{"243":{},"244":{}},"content":{"242":{},"244":{}},"tags":{}}],["emojivoto",{"_index":1078,"title":{"247":{},"253":{}},"content":{"242":{},"243":{},"244":{},"248":{},"251":{},"253":{}},"tags":{}}],["employ",{"_index":512,"title":{},"content":{"196":{}},"tags":{}}],["employe",{"_index":54,"title":{},"content":{"163":{},"202":{}},"tags":{}}],["emptydir",{"_index":945,"title":{},"content":{"228":{},"229":{},"234":{}},"tags":{}}],["enabl",{"_index":375,"title":{},"content":{"184":{},"195":{},"196":{},"197":{},"210":{},"220":{},"223":{},"226":{},"230":{},"259":{}},"tags":{}}],["encapsul",{"_index":242,"title":{},"content":{"175":{},"275":{}},"tags":{}}],["encod",{"_index":832,"title":{},"content":{"216":{}},"tags":{}}],["encompass",{"_index":337,"title":{},"content":{"179":{},"180":{}},"tags":{}}],["encrypt",{"_index":44,"title":{},"content":{"163":{},"182":{},"198":{},"204":{},"208":{}},"tags":{}}],["end",{"_index":173,"title":{},"content":{"172":{},"228":{},"240":{}},"tags":{}}],["endors",{"_index":197,"title":{},"content":{"173":{},"176":{}},"tags":{}}],["endpoint",{"_index":437,"title":{},"content":{"190":{},"191":{},"226":{},"229":{},"235":{}},"tags":{}}],["enforc",{"_index":261,"title":{},"content":{"175":{},"182":{},"199":{},"210":{},"223":{},"254":{},"275":{}},"tags":{}}],["engin",{"_index":715,"title":{},"content":{"204":{}},"tags":{}}],["enhanc",{"_index":735,"title":{},"content":{"205":{},"273":{}},"tags":{}}],["ensur",{"_index":252,"title":{"183":{}},"content":{"175":{},"179":{},"180":{},"182":{},"185":{},"187":{},"190":{},"196":{},"198":{},"204":{},"205":{},"208":{},"210":{},"235":{},"252":{},"257":{},"260":{},"275":{}},"tags":{}}],["entir",{"_index":295,"title":{},"content":{"176":{},"179":{},"196":{},"197":{},"199":{},"207":{},"208":{},"217":{},"275":{}},"tags":{}}],["entiti",{"_index":189,"title":{},"content":{"173":{},"191":{},"197":{},"205":{},"256":{}},"tags":{}}],["entri",{"_index":912,"title":{},"content":{"228":{},"229":{},"241":{},"258":{},"259":{}},"tags":{}}],["env",{"_index":929,"title":{},"content":{"228":{},"229":{},"234":{},"235":{}},"tags":{}}],["environ",{"_index":22,"title":{},"content":{"162":{},"168":{},"175":{},"179":{},"182":{},"184":{},"196":{},"198":{},"199":{},"200":{},"202":{},"203":{},"204":{},"205":{},"206":{},"209":{},"210":{},"215":{},"217":{},"227":{},"228":{},"245":{},"255":{},"275":{}},"tags":{}}],["envoy",{"_index":544,"title":{},"content":{"196":{},"226":{},"228":{},"229":{}},"tags":{}}],["equip",{"_index":771,"title":{},"content":{"205":{}},"tags":{}}],["error",{"_index":135,"title":{},"content":{"168":{},"235":{},"241":{},"258":{}},"tags":{}}],["escal",{"_index":67,"title":{},"content":{"163":{}},"tags":{}}],["especi",{"_index":737,"title":{},"content":{"205":{}},"tags":{}}],["essenti",{"_index":328,"title":{},"content":{"179":{},"206":{}},"tags":{}}],["establish",{"_index":414,"title":{},"content":{"188":{},"189":{},"196":{},"197":{},"202":{},"208":{},"226":{},"255":{}},"tags":{}}],["etc",{"_index":985,"title":{},"content":{"234":{}},"tags":{}}],["evalu",{"_index":830,"title":{"216":{}},"content":{"217":{},"275":{}},"tags":{}}],["even",{"_index":97,"title":{},"content":{"164":{},"198":{},"202":{}},"tags":{}}],["event",{"_index":1220,"title":{},"content":{"275":{}},"tags":{}}],["everyon",{"_index":695,"title":{},"content":{"204":{}},"tags":{}}],["everyth",{"_index":655,"title":{},"content":{"202":{}},"tags":{}}],["evid",{"_index":192,"title":{"178":{},"179":{},"180":{}},"content":{"173":{},"175":{},"176":{},"179":{},"180":{},"183":{},"185":{},"204":{}},"tags":{}}],["exampl",{"_index":63,"title":{"205":{},"242":{}},"content":{"163":{},"177":{},"188":{},"193":{},"202":{},"203":{},"205":{},"228":{},"229":{},"235":{},"236":{},"241":{},"244":{},"258":{}},"tags":{}}],["exclus",{"_index":753,"title":{},"content":{"205":{},"273":{}},"tags":{}}],["exec",{"_index":671,"title":{},"content":{"203":{}},"tags":{}}],["execut",{"_index":13,"title":{},"content":{"162":{},"198":{},"217":{},"236":{},"251":{},"266":{}},"tags":{}}],["exist",{"_index":70,"title":{},"content":{"163":{},"196":{},"230":{},"268":{},"274":{}},"tags":{}}],["expand",{"_index":637,"title":{},"content":{"202":{}},"tags":{}}],["expans",{"_index":1211,"title":{},"content":{"273":{}},"tags":{}}],["expect",{"_index":335,"title":{},"content":{"179":{},"180":{},"194":{},"199":{},"204":{},"213":{},"217":{},"218":{},"223":{},"255":{},"257":{},"272":{}},"tags":{}}],["explain",{"_index":991,"title":{},"content":{"235":{}},"tags":{}}],["explicitli",{"_index":728,"title":{},"content":{"204":{}},"tags":{}}],["exploit",{"_index":712,"title":{},"content":{"204":{}},"tags":{}}],["expos",{"_index":812,"title":{},"content":{"214":{},"228":{},"241":{},"257":{}},"tags":{}}],["extend",{"_index":469,"title":{},"content":{"193":{}},"tags":{}}],["extens",{"_index":455,"title":{},"content":{"191":{},"267":{}},"tags":{}}],["extern",{"_index":537,"title":{},"content":{"196":{},"203":{}},"tags":{}}],["extract",{"_index":1102,"title":{},"content":{"248":{}},"tags":{}}],["f",{"_index":967,"title":{},"content":{"231":{},"232":{},"237":{},"249":{},"250":{},"253":{}},"tags":{}}],["face",{"_index":605,"title":{},"content":{"199":{},"253":{}},"tags":{}}],["facilit",{"_index":525,"title":{},"content":{"196":{},"207":{},"251":{}},"tags":{}}],["fail",{"_index":1062,"title":{},"content":{"241":{},"258":{}},"tags":{}}],["fair",{"_index":1093,"title":{},"content":{"245":{},"254":{}},"tags":{}}],["faq",{"_index":174,"title":{},"content":{"172":{}},"tags":{}}],["favorit",{"_index":1128,"title":{},"content":{"259":{}},"tags":{}}],["featur",{"_index":87,"title":{"196":{},"274":{}},"content":{"164":{},"165":{},"183":{},"192":{},"196":{},"198":{},"199":{},"267":{},"274":{}},"tags":{}}],["fetch",{"_index":800,"title":{},"content":{"211":{},"239":{}},"tags":{}}],["few",{"_index":1106,"title":{},"content":{"252":{},"267":{}},"tags":{}}],["field",{"_index":274,"title":{},"content":{"175":{},"179":{},"218":{},"219":{},"221":{},"225":{},"228":{},"241":{},"258":{}},"tags":{}}],["figur",{"_index":184,"title":{},"content":{"173":{},"175":{},"176":{}},"tags":{}}],["file",{"_index":345,"title":{},"content":{"180":{},"199":{},"207":{},"208":{},"209":{},"210":{},"224":{},"225":{},"234":{},"236":{},"248":{},"251":{}},"tags":{}}],["filesystem",{"_index":253,"title":{},"content":{"175":{},"179":{},"224":{},"225":{}},"tags":{}}],["filesystem'",{"_index":332,"title":{},"content":{"179":{}},"tags":{}}],["final",{"_index":1182,"title":{},"content":{"269":{}},"tags":{}}],["find",{"_index":1006,"title":{},"content":{"235":{}},"tags":{}}],["firewal",{"_index":645,"title":{},"content":{"202":{}},"tags":{}}],["firm",{"_index":734,"title":{},"content":{"205":{}},"tags":{}}],["first",{"_index":429,"title":{},"content":{"190":{},"226":{},"241":{},"269":{}},"tags":{}}],["fit",{"_index":1122,"title":{},"content":{"257":{}},"tags":{}}],["five",{"_index":627,"title":{},"content":{"202":{}},"tags":{}}],["flag",{"_index":1144,"title":{},"content":{"267":{}},"tags":{}}],["flo",{"_index":1098,"title":{},"content":{"248":{},"271":{}},"tags":{}}],["flow",{"_index":82,"title":{},"content":{"163":{},"175":{},"261":{}},"tags":{}}],["fluentli",{"_index":69,"title":{},"content":{"163":{}},"tags":{}}],["flux",{"_index":465,"title":{},"content":{"192":{}},"tags":{}}],["follow",{"_index":128,"title":{},"content":{"168":{},"172":{},"173":{},"196":{},"199":{},"200":{},"201":{},"203":{},"204":{},"205":{},"209":{},"217":{},"218":{},"225":{},"228":{},"229":{},"230":{},"235":{},"241":{},"246":{},"258":{},"267":{},"268":{}},"tags":{}}],["foothold",{"_index":651,"title":{},"content":{"202":{}},"tags":{}}],["for=jsonpath='{.status.loadbalancer.ingress",{"_index":1049,"title":{},"content":{"241":{}},"tags":{}}],["form",{"_index":752,"title":{},"content":{"205":{}},"tags":{}}],["format",{"_index":241,"title":{"179":{}},"content":{"175":{}},"tags":{}}],["forward",{"_index":1035,"title":{},"content":{"238":{},"274":{}},"tags":{}}],["found",{"_index":381,"title":{},"content":{"184":{}},"tags":{}}],["foundat",{"_index":566,"title":{"198":{}},"content":{},"tags":{}}],["frequent",{"_index":356,"title":{"181":{}},"content":{},"tags":{}}],["fresh",{"_index":439,"title":{},"content":{"190":{}},"tags":{}}],["frontend",{"_index":1058,"title":{},"content":{"241":{},"244":{},"253":{},"257":{},"258":{},"259":{},"261":{}},"tags":{}}],["frontendip",{"_index":1130,"title":{},"content":{"259":{}},"tags":{}}],["frontendip=$(kubectl",{"_index":1123,"title":{},"content":{"257":{}},"tags":{}}],["frontendip}:443",{"_index":1073,"title":{},"content":{"241":{},"257":{}},"tags":{}}],["full",{"_index":608,"title":{},"content":{"200":{},"202":{},"216":{}},"tags":{}}],["fulli",{"_index":706,"title":{},"content":{"204":{},"275":{}},"tags":{}}],["function",{"_index":604,"title":{},"content":{"199":{},"207":{},"275":{}},"tags":{}}],["further",{"_index":390,"title":{},"content":{"185":{},"204":{},"251":{}},"tags":{}}],["furthermor",{"_index":954,"title":{},"content":{"229":{}},"tags":{}}],["futur",{"_index":443,"title":{},"content":{"191":{},"204":{},"216":{},"254":{}},"tags":{}}],["gener",{"_index":201,"title":{"178":{},"215":{},"236":{},"251":{}},"content":{"173":{},"175":{},"176":{},"179":{},"183":{},"185":{},"196":{},"207":{},"209":{},"215":{},"216":{},"217":{},"218":{},"234":{},"236":{},"251":{},"269":{},"275":{}},"tags":{}}],["germanywestcentr",{"_index":1159,"title":{},"content":{"268":{}},"tags":{}}],["get",{"_index":116,"title":{"262":{}},"content":{"165":{}},"tags":{}}],["ghcr.io/edgelesssys/contrast/initializer:latest",{"_index":989,"title":{},"content":{"234":{}},"tags":{}}],["ghcr.io/edgelesssys/contrast/initializer@sha256",{"_index":928,"title":{},"content":{"228":{},"229":{}},"tags":{}}],["ghcr.io/edgelesssys/contrast/servic",{"_index":935,"title":{},"content":{"228":{},"229":{},"235":{}},"tags":{}}],["ghcr.io/edgelesssys/conversion:v1.2.3",{"_index":963,"title":{},"content":{"229":{}},"tags":{}}],["ghcr.io/edgelesssys/frontend:v1.2.3",{"_index":943,"title":{},"content":{"228":{}},"tags":{}}],["give",{"_index":169,"title":{},"content":{"172":{}},"tags":{}}],["given",{"_index":227,"title":{},"content":{"175":{},"228":{},"229":{}},"tags":{}}],["gke",{"_index":520,"title":{},"content":{"196":{}},"tags":{}}],["go",{"_index":513,"title":{},"content":{"196":{},"204":{},"235":{}},"tags":{}}],["goal",{"_index":39,"title":{"163":{}},"content":{"205":{}},"tags":{}}],["goarch",{"_index":133,"title":{},"content":{"168":{}},"tags":{}}],["goe",{"_index":631,"title":{},"content":{"202":{}},"tags":{}}],["golang",{"_index":1011,"title":{},"content":{"235":{}},"tags":{}}],["goo",{"_index":132,"title":{},"content":{"168":{}},"tags":{}}],["googl",{"_index":519,"title":{},"content":{"196":{}},"tags":{}}],["govern",{"_index":341,"title":{},"content":{"180":{}},"tags":{}}],["grant",{"_index":767,"title":{},"content":{"205":{}},"tags":{}}],["graphic",{"_index":228,"title":{},"content":{"175":{},"199":{}},"tags":{}}],["green",{"_index":592,"title":{},"content":{"199":{}},"tags":{}}],["group",{"_index":685,"title":{"268":{}},"content":{"204":{},"235":{},"268":{},"269":{},"270":{}},"tags":{}}],["grow",{"_index":747,"title":{},"content":{"205":{}},"tags":{}}],["grpc",{"_index":1085,"title":{},"content":{"244":{}},"tags":{}}],["guarante",{"_index":368,"title":{"217":{}},"content":{"183":{},"184":{},"204":{},"205":{},"213":{},"217":{},"224":{},"236":{},"275":{}},"tags":{}}],["guest",{"_index":255,"title":{},"content":{"175":{},"179":{},"180":{},"194":{},"223":{},"224":{}},"tags":{}}],["guest'",{"_index":643,"title":{},"content":{"202":{}},"tags":{}}],["guid",{"_index":964,"title":{},"content":{"230":{},"233":{},"244":{}},"tags":{}}],["guidelin",{"_index":397,"title":{},"content":{"187":{}},"tags":{}}],["hacker",{"_index":646,"title":{},"content":{"202":{},"203":{}},"tags":{}}],["hand",{"_index":449,"title":{},"content":{"191":{},"228":{}},"tags":{}}],["handl",{"_index":799,"title":{"235":{}},"content":{"211":{},"214":{},"228":{},"235":{}},"tags":{}}],["handler",{"_index":862,"title":{},"content":{"219":{},"221":{},"225":{}},"tags":{}}],["handov",{"_index":769,"title":{},"content":{"205":{}},"tags":{}}],["handshak",{"_index":1110,"title":{},"content":{"252":{}},"tags":{}}],["happen",{"_index":1224,"title":{},"content":{"275":{}},"tags":{}}],["har",{"_index":543,"title":{},"content":{"196":{}},"tags":{}}],["hard",{"_index":993,"title":{},"content":{"235":{}},"tags":{}}],["hardwar",{"_index":19,"title":{},"content":{"162":{},"175":{},"176":{},"179":{},"180":{},"183":{},"185":{},"197":{},"198":{},"199":{},"201":{},"204":{}},"tags":{}}],["harm",{"_index":659,"title":{},"content":{"202":{},"203":{}},"tags":{}}],["hash",{"_index":249,"title":{},"content":{"175":{},"179":{},"180":{},"199":{},"209":{},"218":{},"223":{},"259":{}},"tags":{}}],["hasn't",{"_index":363,"title":{},"content":{"182":{},"198":{},"218":{},"252":{}},"tags":{}}],["have",{"_index":703,"title":{},"content":{"204":{}},"tags":{}}],["haven't",{"_index":1228,"title":{},"content":{"276":{}},"tags":{}}],["head",{"_index":115,"title":{},"content":{"165":{}},"tags":{}}],["healthcar",{"_index":765,"title":{},"content":{"205":{}},"tags":{}}],["healthsecur",{"_index":756,"title":{},"content":{"205":{}},"tags":{}}],["heavi",{"_index":678,"title":{},"content":{"203":{}},"tags":{}}],["heavili",{"_index":995,"title":{},"content":{"235":{}},"tags":{}}],["helm",{"_index":528,"title":{},"content":{"196":{},"234":{}},"tags":{}}],["help",{"_index":617,"title":{},"content":{"201":{},"204":{}},"tags":{}}],["henc",{"_index":755,"title":{},"content":{"205":{}},"tags":{}}],["here",{"_index":382,"title":{},"content":{"184":{},"205":{}},"tags":{}}],["high",{"_index":400,"title":{},"content":{"187":{},"192":{}},"tags":{}}],["highli",{"_index":1090,"title":{},"content":{"245":{}},"tags":{}}],["hijack",{"_index":702,"title":{},"content":{"204":{}},"tags":{}}],["hindsight",{"_index":179,"title":{},"content":{"172":{}},"tags":{}}],["histori",{"_index":1043,"title":{"256":{}},"content":{"240":{},"255":{}},"tags":{}}],["hold",{"_index":418,"title":{},"content":{"189":{}},"tags":{}}],["host",{"_index":264,"title":{},"content":{"175":{},"179":{},"194":{},"199":{},"223":{},"241":{},"258":{}},"tags":{}}],["hostdata",{"_index":273,"title":{},"content":{"175":{},"216":{},"218":{}},"tags":{}}],["hostnam",{"_index":952,"title":{},"content":{"229":{}},"tags":{}}],["html",{"_index":1139,"title":{},"content":{"261":{}},"tags":{}}],["http",{"_index":1200,"title":{},"content":{"271":{}},"tags":{}}],["https://$frontendip",{"_index":1124,"title":{},"content":{"257":{}},"tags":{}}],["https://${frontendip}:443",{"_index":1065,"title":{},"content":{"241":{},"258":{},"261":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/contrast",{"_index":1202,"title":{},"content":{"271":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/coordinator.yml",{"_index":972,"title":{},"content":{"232":{},"250":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/emojivoto",{"_index":1099,"title":{},"content":{"248":{}},"tags":{}}],["https://github.com/edgelesssys/contrast/releases/latest/download/runtime.yml",{"_index":968,"title":{},"content":{"231":{},"249":{}},"tags":{}}],["https://github.com/kata",{"_index":1039,"title":{},"content":{"238":{}},"tags":{}}],["hypervisor",{"_index":275,"title":{"222":{}},"content":{"175":{},"199":{},"202":{},"212":{},"222":{},"225":{}},"tags":{}}],["ident",{"_index":369,"title":{},"content":{"184":{},"196":{},"200":{},"204":{},"208":{},"209":{}},"tags":{}}],["identifi",{"_index":318,"title":{},"content":{"179":{},"180":{},"197":{},"213":{},"219":{},"228":{},"229":{}},"tags":{}}],["igvm",{"_index":240,"title":{},"content":{"175":{},"212":{},"224":{},"225":{}},"tags":{}}],["imag",{"_index":238,"title":{"224":{}},"content":{"175":{},"179":{},"194":{},"198":{},"199":{},"200":{},"202":{},"203":{},"204":{},"205":{},"212":{},"215":{},"217":{},"223":{},"224":{},"225":{},"228":{},"229":{},"234":{},"235":{}},"tags":{}}],["imperson",{"_index":711,"title":{},"content":{"204":{}},"tags":{}}],["implement",{"_index":139,"title":{},"content":{"168":{},"193":{},"204":{},"205":{},"217":{},"219":{},"221":{},"275":{}},"tags":{}}],["impli",{"_index":596,"title":{},"content":{"199":{}},"tags":{}}],["import",{"_index":824,"title":{},"content":{"215":{}},"tags":{}}],["impos",{"_index":79,"title":{},"content":{"163":{}},"tags":{}}],["improv",{"_index":127,"title":{},"content":{"168":{}},"tags":{}}],["inaccess",{"_index":569,"title":{},"content":{"198":{}},"tags":{}}],["inc",{"_index":733,"title":{},"content":{"205":{}},"tags":{}}],["includ",{"_index":52,"title":{},"content":{"163":{},"172":{},"173":{},"175":{},"179":{},"180":{},"184":{},"194":{},"199":{},"200":{},"203":{},"205":{},"218":{},"238":{}},"tags":{}}],["incom",{"_index":856,"title":{},"content":{"218":{},"228":{}},"tags":{}}],["incorpor",{"_index":331,"title":{},"content":{"179":{}},"tags":{}}],["incorrectli",{"_index":1216,"title":{},"content":{"274":{}},"tags":{}}],["increas",{"_index":90,"title":{},"content":{"164":{},"205":{}},"tags":{}}],["individu",{"_index":515,"title":{},"content":{"196":{}},"tags":{}}],["infect",{"_index":1133,"title":{},"content":{"260":{}},"tags":{}}],["inform",{"_index":37,"title":{},"content":{"162":{},"168":{},"175":{},"179":{},"186":{},"191":{},"197":{},"214":{},"215":{},"223":{},"228":{},"235":{},"255":{}},"tags":{}}],["infrastructur",{"_index":47,"title":{"189":{}},"content":{"163":{},"189":{},"194":{},"196":{},"197":{},"198":{},"199":{},"202":{},"205":{},"273":{}},"tags":{}}],["ingress",{"_index":900,"title":{"228":{}},"content":{"228":{},"229":{}},"tags":{}}],["init",{"_index":801,"title":{},"content":{"211":{},"224":{},"239":{},"251":{}},"tags":{}}],["initcontain",{"_index":927,"title":{},"content":{"228":{},"229":{},"234":{},"235":{}},"tags":{}}],["initi",{"_index":235,"title":{"211":{},"234":{}},"content":{"175":{},"179":{},"191":{},"196":{},"198":{},"199":{},"211":{},"218":{},"224":{},"228":{},"229":{},"234":{},"235":{},"237":{},"251":{},"253":{},"261":{}},"tags":{}}],["initramf",{"_index":247,"title":{},"content":{"175":{},"179":{}},"tags":{}}],["initrd",{"_index":884,"title":{},"content":{"224":{}},"tags":{}}],["input",{"_index":846,"title":{},"content":{"217":{}},"tags":{}}],["insid",{"_index":14,"title":{},"content":{"162":{},"175":{},"184":{},"202":{},"203":{},"205":{},"208":{},"210":{},"226":{},"229":{}},"tags":{}}],["inspect",{"_index":719,"title":{},"content":{"204":{},"215":{},"256":{},"275":{}},"tags":{}}],["instal",{"_index":75,"title":{"225":{},"263":{},"271":{}},"content":{"163":{},"195":{},"196":{},"207":{},"212":{},"220":{},"222":{},"225":{},"231":{},"232":{},"246":{},"249":{},"262":{},"266":{},"271":{}},"tags":{}}],["instanc",{"_index":444,"title":{},"content":{"191":{},"198":{},"203":{},"208":{}},"tags":{}}],["instanti",{"_index":844,"title":{},"content":{"217":{}},"tags":{}}],["instead",{"_index":869,"title":{},"content":{"219":{},"221":{},"224":{},"274":{}},"tags":{}}],["instruct",{"_index":874,"title":{},"content":{"221":{},"230":{},"246":{}},"tags":{}}],["insuffici",{"_index":619,"title":{},"content":{"201":{}},"tags":{}}],["integr",{"_index":68,"title":{"276":{}},"content":{"163":{},"173":{},"175":{},"179":{},"180":{},"182":{},"184":{},"186":{},"196":{},"198":{},"199":{},"200":{},"204":{},"207":{},"208":{},"210":{},"213":{},"215":{},"217":{},"223":{},"224":{},"235":{},"275":{}},"tags":{}}],["intel",{"_index":594,"title":{},"content":{"199":{}},"tags":{}}],["inter",{"_index":1114,"title":{},"content":{"253":{}},"tags":{}}],["interact",{"_index":306,"title":{},"content":{"177":{},"200":{}},"tags":{}}],["intercept",{"_index":635,"title":{},"content":{"202":{},"203":{},"204":{}},"tags":{}}],["interest",{"_index":1092,"title":{},"content":{"245":{}},"tags":{}}],["interfac",{"_index":471,"title":{"207":{}},"content":{"193":{},"219":{},"238":{}},"tags":{}}],["intermedi",{"_index":420,"title":{},"content":{"189":{},"190":{},"191":{},"228":{},"229":{}},"tags":{}}],["intern",{"_index":536,"title":{},"content":{"196":{}},"tags":{}}],["intra",{"_index":673,"title":{},"content":{"203":{}},"tags":{}}],["introduc",{"_index":434,"title":{},"content":{"190":{},"202":{}},"tags":{}}],["invok",{"_index":855,"title":{},"content":{"218":{},"221":{}},"tags":{}}],["involv",{"_index":218,"title":{},"content":{"174":{},"198":{},"205":{},"274":{}},"tags":{}}],["ip",{"_index":143,"title":{},"content":{"168":{},"229":{},"241":{},"257":{},"258":{}},"tags":{}}],["ip>::###fals",{"_index":910,"title":{},"content":{"228":{}},"tags":{}}],["name>##tru",{"_index":918,"title":{},"content":{"228":{}},"tags":{}}],["namespac",{"_index":1146,"title":{},"content":{"267":{}},"tags":{}}],["nativ",{"_index":531,"title":{},"content":{"196":{}},"tags":{}}],["necessari",{"_index":777,"title":{},"content":{"207":{},"233":{},"273":{}},"tags":{}}],["need",{"_index":445,"title":{},"content":{"191":{},"204":{},"205":{},"208":{},"214":{},"219":{},"220":{},"231":{},"233":{},"238":{},"249":{},"254":{},"256":{},"266":{},"267":{}},"tags":{}}],["nest",{"_index":491,"title":{},"content":{"194":{},"195":{}},"tags":{}}],["net_admin",{"_index":941,"title":{},"content":{"228":{},"229":{}},"tags":{}}],["network",{"_index":496,"title":{},"content":{"194":{},"200":{},"202":{},"203":{},"204":{},"226":{}},"tags":{}}],["new",{"_index":427,"title":{},"content":{"189":{},"191":{},"202":{},"204":{},"208":{},"225":{},"260":{},"261":{},"268":{},"270":{}},"tags":{}}],["next",{"_index":107,"title":{"165":{}},"content":{"238":{},"256":{},"260":{}},"tags":{}}],["node",{"_index":487,"title":{"220":{},"225":{}},"content":{"194":{},"195":{},"200":{},"212":{},"218":{},"220":{},"222":{},"225":{},"231":{},"249":{},"269":{},"270":{}},"tags":{}}],["node.k8s.io/v1",{"_index":864,"title":{},"content":{"219":{}},"tags":{}}],["nodepool",{"_index":1179,"title":{},"content":{"269":{}},"tags":{}}],["nodepool1",{"_index":1185,"title":{},"content":{"269":{}},"tags":{}}],["nodepool2",{"_index":1180,"title":{},"content":{"269":{}},"tags":{}}],["non",{"_index":701,"title":{},"content":{"204":{},"228":{}},"tags":{}}],["none",{"_index":1189,"title":{},"content":{"269":{}},"tags":{}}],["northeurop",{"_index":1161,"title":{},"content":{"268":{}},"tags":{}}],["notabl",{"_index":330,"title":{},"content":{"179":{}},"tags":{}}],["note",{"_index":597,"title":{},"content":{"199":{}},"tags":{}}],["now",{"_index":1113,"title":{},"content":{"253":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1034,"title":{},"content":{"238":{},"241":{},"252":{},"257":{}},"tags":{}}],["object",{"_index":470,"title":{},"content":{"193":{},"275":{}},"tags":{}}],["observ",{"_index":842,"title":{},"content":{"217":{}},"tags":{}}],["obtain",{"_index":213,"title":{},"content":{"173":{},"177":{},"190":{}},"tags":{}}],["occur",{"_index":136,"title":{},"content":{"168":{}},"tags":{}}],["oci",{"_index":478,"title":{},"content":{"193":{},"194":{},"215":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"164":{},"195":{},"196":{},"205":{},"208":{}},"tags":{}}],["offlin",{"_index":303,"title":{},"content":{"176":{}},"tags":{}}],["older",{"_index":1134,"title":{},"content":{"260":{},"261":{}},"tags":{}}],["omit",{"_index":850,"title":{},"content":{"217":{},"235":{},"275":{}},"tags":{}}],["on",{"_index":278,"title":{},"content":{"175":{},"193":{},"205":{},"229":{},"268":{}},"tags":{}}],["onc",{"_index":966,"title":{},"content":{"231":{},"249":{}},"tags":{}}],["opa",{"_index":501,"title":{},"content":{"194":{},"210":{}},"tags":{}}],["open",{"_index":140,"title":{},"content":{"168":{},"194":{},"210":{}},"tags":{}}],["openssl",{"_index":1069,"title":{},"content":{"241":{},"257":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"163":{},"176":{},"182":{},"184":{},"196":{},"197":{},"198":{},"200":{},"202":{},"203":{},"205":{},"207":{},"267":{}},"tags":{}}],["optim",{"_index":509,"title":{},"content":{"196":{}},"tags":{}}],["option",{"_index":486,"title":{"258":{}},"content":{"194":{}},"tags":{}}],["orchestr",{"_index":532,"title":{},"content":{"196":{},"210":{}},"tags":{}}],["order",{"_index":849,"title":{},"content":{"217":{},"236":{},"275":{}},"tags":{}}],["origin",{"_index":497,"title":{},"content":{"194":{},"226":{},"234":{}},"tags":{}}],["os",{"_index":130,"title":{},"content":{"168":{},"199":{},"269":{}},"tags":{}}],["os.readfile(\"/tl",{"_index":1016,"title":{},"content":{"235":{}},"tags":{}}],["otherwis",{"_index":839,"title":{},"content":{"216":{}},"tags":{}}],["out",{"_index":450,"title":{"261":{}},"content":{"191":{},"201":{},"202":{},"204":{},"225":{},"228":{},"261":{},"270":{}},"tags":{}}],["outlin",{"_index":547,"title":{},"content":{"197":{},"233":{},"272":{}},"tags":{}}],["output",{"_index":1151,"title":{},"content":{"267":{}},"tags":{}}],["outsid",{"_index":816,"title":{},"content":{"214":{},"228":{}},"tags":{}}],["over",{"_index":492,"title":{},"content":{"194":{},"202":{},"228":{},"229":{},"253":{},"255":{}},"tags":{}}],["overview",{"_index":546,"title":{"197":{}},"content":{"206":{}},"tags":{}}],["own",{"_index":611,"title":{},"content":{"200":{}},"tags":{}}],["owner",{"_index":203,"title":{"177":{}},"content":{"173":{},"177":{},"190":{},"191":{},"198":{},"200":{},"204":{},"205":{},"240":{},"245":{}},"tags":{}}],["owner'",{"_index":794,"title":{},"content":{"209":{},"213":{}},"tags":{}}],["ownership",{"_index":554,"title":{},"content":{"197":{}},"tags":{}}],["owners—to",{"_index":377,"title":{},"content":{"184":{}},"tags":{}}],["p",{"_index":1046,"title":{},"content":{"241":{}},"tags":{}}],["packet",{"_index":907,"title":{},"content":{"228":{}},"tags":{}}],["page",{"_index":327,"title":{},"content":{"179":{},"206":{}},"tags":{}}],["paramet",{"_index":818,"title":{},"content":{"214":{},"215":{}},"tags":{}}],["pars",{"_index":713,"title":{},"content":{"204":{}},"tags":{}}],["part",{"_index":265,"title":{},"content":{"175":{},"179":{},"183":{},"191":{},"199":{},"209":{},"213":{},"214":{},"219":{},"223":{},"226":{},"229":{},"248":{},"253":{},"260":{}},"tags":{}}],["parti",{"_index":105,"title":{"177":{},"186":{}},"content":{"164":{},"173":{},"177":{},"186":{},"188":{},"190":{},"196":{},"200":{},"202":{},"205":{},"208":{},"228":{}},"tags":{}}],["particip",{"_index":809,"title":{},"content":{"213":{}},"tags":{}}],["particular",{"_index":1225,"title":{},"content":{"275":{}},"tags":{}}],["particularli",{"_index":557,"title":{},"content":{"197":{},"217":{}},"tags":{}}],["parties—such",{"_index":376,"title":{},"content":{"184":{}},"tags":{}}],["partit",{"_index":698,"title":{},"content":{"204":{},"224":{}},"tags":{}}],["pass",{"_index":262,"title":{},"content":{"175":{}},"tags":{}}],["passiv",{"_index":708,"title":{},"content":{"204":{}},"tags":{}}],["patch",{"_index":1044,"title":{},"content":{"241":{},"260":{}},"tags":{}}],["path",{"_index":1203,"title":{},"content":{"271":{}},"tags":{}}],["patient",{"_index":758,"title":{},"content":{"205":{}},"tags":{}}],["peer",{"_index":1009,"title":{},"content":{"235":{}},"tags":{}}],["pend",{"_index":1213,"title":{},"content":{"273":{}},"tags":{}}],["per",{"_index":895,"title":{},"content":{"226":{}},"tags":{}}],["perform",{"_index":672,"title":{},"content":{"203":{},"204":{},"220":{},"225":{},"231":{},"249":{}},"tags":{}}],["period",{"_index":653,"title":{},"content":{"202":{}},"tags":{}}],["perman",{"_index":650,"title":{},"content":{"202":{}},"tags":{}}],["permiss",{"_index":612,"title":{},"content":{"200":{},"214":{},"215":{},"266":{}},"tags":{}}],["permit",{"_index":798,"title":{},"content":{"210":{},"218":{}},"tags":{}}],["persist",{"_index":726,"title":{},"content":{"204":{},"274":{},"275":{}},"tags":{}}],["person",{"_index":551,"title":{},"content":{"197":{}},"tags":{}}],["persona",{"_index":606,"title":{"200":{}},"content":{"205":{}},"tags":{}}],["perspect",{"_index":511,"title":{"254":{}},"content":{"196":{},"244":{}},"tags":{}}],["phase",{"_index":576,"title":{},"content":{"198":{},"237":{}},"tags":{}}],["physic",{"_index":570,"title":{},"content":{"198":{},"199":{},"202":{},"203":{},"204":{}},"tags":{}}],["piec",{"_index":316,"title":{},"content":{"179":{}},"tags":{}}],["pii",{"_index":552,"title":{},"content":{"197":{}},"tags":{}}],["pki",{"_index":417,"title":{},"content":{"189":{},"196":{},"226":{}},"tags":{}}],["placehold",{"_index":986,"title":{},"content":{"234":{}},"tags":{}}],["plain",{"_index":997,"title":{},"content":{"235":{}},"tags":{}}],["plan",{"_index":1212,"title":{},"content":{"273":{}},"tags":{}}],["plane",{"_index":588,"title":{},"content":{"199":{},"203":{},"204":{}},"tags":{}}],["platform",{"_index":319,"title":{},"content":{"179":{},"196":{},"198":{},"202":{},"245":{},"273":{},"276":{}},"tags":{}}],["platform'",{"_index":745,"title":{},"content":{"205":{}},"tags":{}}],["play",{"_index":370,"title":{},"content":{"184":{}},"tags":{}}],["pleas",{"_index":1031,"title":{},"content":{"236":{},"246":{}},"tags":{}}],["plugin",{"_index":803,"title":{},"content":{"212":{},"221":{},"225":{}},"tags":{}}],["pod",{"_index":12,"title":{"175":{},"224":{}},"content":{"162":{},"175":{},"176":{},"180":{},"183":{},"191":{},"192":{},"193":{},"194":{},"196":{},"198":{},"199":{},"208":{},"209":{},"213":{},"215":{},"216":{},"217":{},"218":{},"219":{},"222":{},"223":{},"224":{},"225":{},"226":{},"229":{},"234":{},"238":{},"251":{},"275":{}},"tags":{}}],["pod'",{"_index":280,"title":{},"content":{"175":{},"188":{}},"tags":{}}],["podspec",{"_index":821,"title":{},"content":{"214":{},"215":{}},"tags":{}}],["podvm",{"_index":804,"title":{},"content":{"212":{}},"tags":{}}],["pod’",{"_index":365,"title":{},"content":{"183":{}},"tags":{}}],["point",{"_index":340,"title":{},"content":{"179":{},"203":{}},"tags":{}}],["polici",{"_index":150,"title":{"180":{},"210":{},"213":{},"236":{},"251":{},"275":{}},"content":{"168":{},"173":{},"175":{},"176":{},"179":{},"180":{},"182":{},"183":{},"194":{},"198":{},"199":{},"204":{},"207":{},"209":{},"210":{},"213":{},"214":{},"215":{},"216":{},"217":{},"218":{},"223":{},"234":{},"236":{},"240":{},"251":{},"255":{},"256":{},"259":{},"275":{}},"tags":{}}],["policy'",{"_index":276,"title":{},"content":{"175":{},"215":{},"218":{}},"tags":{}}],["pool",{"_index":505,"title":{},"content":{"195":{},"269":{},"270":{}},"tags":{}}],["popul",{"_index":820,"title":{},"content":{"214":{},"235":{}},"tags":{}}],["port",{"_index":915,"title":{},"content":{"228":{},"229":{},"235":{},"238":{},"274":{},"276":{}},"tags":{}}],["port>#::###fals",{"_index":952,"title":{},"content":{"131":{}},"tags":{}}],["name>##tru",{"_index":959,"title":{},"content":{"131":{}},"tags":{}}],["namespac",{"_index":1205,"title":{},"content":{"323":{}},"tags":{}}],["nativ",{"_index":586,"title":{},"content":{"99":{}},"tags":{}}],["necessari",{"_index":824,"title":{},"content":{"110":{},"284":{},"287":{},"314":{}},"tags":{}}],["need",{"_index":448,"title":{},"content":{"91":{},"107":{},"108":{},"111":{},"117":{},"122":{},"123":{},"282":{},"284":{},"289":{},"300":{},"305":{},"307":{},"322":{},"323":{},"325":{}},"tags":{}}],["nest",{"_index":547,"title":{},"content":{"97":{},"98":{}},"tags":{}}],["net_admin",{"_index":977,"title":{},"content":{"131":{}},"tags":{}}],["network",{"_index":552,"title":{},"content":{"97":{},"103":{},"105":{},"106":{},"107":{},"129":{}},"tags":{}}],["new",{"_index":430,"title":{},"content":{"89":{},"91":{},"93":{},"105":{},"107":{},"111":{},"128":{},"311":{},"312":{},"324":{},"326":{}},"tags":{}}],["newmeshcert",{"_index":496,"title":{},"content":{"93":{}},"tags":{}}],["next",{"_index":107,"title":{"280":{}},"content":{"289":{},"307":{},"311":{}},"tags":{}}],["node",{"_index":543,"title":{"123":{},"128":{}},"content":{"97":{},"98":{},"103":{},"115":{},"121":{},"123":{},"125":{},"128":{},"282":{},"300":{},"325":{},"326":{}},"tags":{}}],["node.k8s.io/v1",{"_index":904,"title":{},"content":{"122":{}},"tags":{}}],["nodepool",{"_index":1238,"title":{},"content":{"325":{}},"tags":{}}],["nodepool1",{"_index":1242,"title":{},"content":{"325":{}},"tags":{}}],["nodepool2",{"_index":1239,"title":{},"content":{"325":{}},"tags":{}}],["non",{"_index":750,"title":{},"content":{"107":{},"131":{},"325":{}},"tags":{}}],["none",{"_index":1249,"title":{},"content":{"325":{}},"tags":{}}],["northeurop",{"_index":1219,"title":{},"content":{"324":{}},"tags":{}}],["notabl",{"_index":333,"title":{},"content":{"75":{}},"tags":{}}],["note",{"_index":648,"title":{},"content":{"102":{},"131":{}},"tags":{}}],["now",{"_index":1154,"title":{},"content":{"304":{},"325":{}},"tags":{}}],["number",{"_index":484,"title":{},"content":{"93":{}},"tags":{}}],["numer",{"_index":464,"title":{},"content":{"92":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1078,"title":{},"content":{"289":{},"292":{},"303":{},"308":{}},"tags":{}}],["object",{"_index":528,"title":{},"content":{"96":{},"129":{},"130":{},"316":{}},"tags":{}}],["observ",{"_index":169,"title":{"87":{},"92":{}},"content":{"84":{},"120":{}},"tags":{}}],["obtain",{"_index":216,"title":{},"content":{"69":{},"73":{},"90":{}},"tags":{}}],["occur",{"_index":136,"title":{},"content":{"67":{}},"tags":{}}],["oci",{"_index":534,"title":{},"content":{"96":{},"97":{},"118":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"98":{},"99":{},"108":{},"111":{},"279":{}},"tags":{}}],["offlin",{"_index":306,"title":{},"content":{"72":{}},"tags":{}}],["older",{"_index":1175,"title":{},"content":{"311":{},"312":{}},"tags":{}}],["omit",{"_index":891,"title":{},"content":{"120":{},"286":{},"316":{}},"tags":{}}],["on",{"_index":281,"title":{},"content":{"71":{},"93":{},"96":{},"108":{},"132":{},"324":{}},"tags":{}}],["onc",{"_index":1004,"title":{},"content":{"282":{},"300":{}},"tags":{}}],["opa",{"_index":557,"title":{},"content":{"97":{},"113":{}},"tags":{}}],["open",{"_index":140,"title":{},"content":{"67":{},"97":{},"113":{}},"tags":{}}],["openssl",{"_index":1112,"title":{},"content":{"292":{},"308":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"72":{},"78":{},"80":{},"94":{},"99":{},"100":{},"101":{},"103":{},"105":{},"106":{},"108":{},"110":{},"278":{},"323":{}},"tags":{}}],["optim",{"_index":565,"title":{},"content":{"99":{}},"tags":{}}],["option",{"_index":542,"title":{"309":{}},"content":{"97":{},"325":{}},"tags":{}}],["orchestr",{"_index":587,"title":{},"content":{"99":{},"113":{}},"tags":{}}],["order",{"_index":890,"title":{},"content":{"120":{},"287":{},"316":{}},"tags":{}}],["origin",{"_index":553,"title":{},"content":{"97":{},"129":{},"285":{}},"tags":{}}],["os",{"_index":130,"title":{},"content":{"67":{},"102":{},"325":{}},"tags":{}}],["os.readfile(\"/tl",{"_index":1053,"title":{},"content":{"286":{}},"tags":{}}],["otherwis",{"_index":881,"title":{},"content":{"119":{},"131":{}},"tags":{}}],["out",{"_index":453,"title":{"312":{}},"content":{"91":{},"104":{},"105":{},"107":{},"128":{},"131":{},"312":{},"326":{}},"tags":{}}],["outlin",{"_index":599,"title":{},"content":{"100":{},"284":{}},"tags":{}}],["output",{"_index":1209,"title":{},"content":{"323":{}},"tags":{}}],["outsid",{"_index":859,"title":{},"content":{"117":{},"131":{}},"tags":{}}],["over",{"_index":548,"title":{},"content":{"97":{},"105":{},"131":{},"132":{},"304":{},"306":{}},"tags":{}}],["overview",{"_index":598,"title":{"100":{}},"content":{"109":{}},"tags":{}}],["own",{"_index":662,"title":{},"content":{"103":{}},"tags":{}}],["owner",{"_index":206,"title":{"73":{}},"content":{"69":{},"73":{},"90":{},"91":{},"101":{},"103":{},"107":{},"108":{},"291":{},"296":{}},"tags":{}}],["owner'",{"_index":839,"title":{},"content":{"112":{},"116":{}},"tags":{}}],["ownership",{"_index":605,"title":{},"content":{"100":{}},"tags":{}}],["owners—to",{"_index":380,"title":{},"content":{"80":{}},"tags":{}}],["p",{"_index":1089,"title":{},"content":{"292":{}},"tags":{}}],["packet",{"_index":949,"title":{},"content":{"131":{}},"tags":{}}],["page",{"_index":330,"title":{},"content":{"75":{},"109":{}},"tags":{}}],["pair",{"_index":469,"title":{},"content":{"92":{}},"tags":{}}],["paramet",{"_index":860,"title":{},"content":{"117":{},"118":{}},"tags":{}}],["pars",{"_index":762,"title":{},"content":{"107":{}},"tags":{}}],["part",{"_index":268,"title":{},"content":{"71":{},"75":{},"79":{},"91":{},"102":{},"112":{},"116":{},"117":{},"122":{},"126":{},"129":{},"132":{},"299":{},"304":{},"311":{}},"tags":{}}],["parti",{"_index":105,"title":{"73":{},"82":{}},"content":{"69":{},"73":{},"82":{},"88":{},"90":{},"99":{},"103":{},"105":{},"108":{},"111":{},"131":{},"279":{}},"tags":{}}],["particip",{"_index":853,"title":{},"content":{"116":{}},"tags":{}}],["particular",{"_index":1197,"title":{},"content":{"316":{}},"tags":{}}],["particularli",{"_index":608,"title":{},"content":{"100":{},"120":{}},"tags":{}}],["parties—such",{"_index":379,"title":{},"content":{"80":{}},"tags":{}}],["partit",{"_index":747,"title":{},"content":{"107":{},"127":{}},"tags":{}}],["pass",{"_index":265,"title":{},"content":{"71":{}},"tags":{}}],["passiv",{"_index":757,"title":{},"content":{"107":{}},"tags":{}}],["patch",{"_index":1087,"title":{},"content":{"292":{},"311":{}},"tags":{}}],["path",{"_index":1262,"title":{},"content":{"327":{}},"tags":{}}],["patient",{"_index":806,"title":{},"content":{"108":{}},"tags":{}}],["peer",{"_index":1046,"title":{},"content":{"286":{}},"tags":{}}],["pend",{"_index":1184,"title":{},"content":{"314":{}},"tags":{}}],["per",{"_index":933,"title":{},"content":{"129":{},"287":{}},"tags":{}}],["perform",{"_index":508,"title":{},"content":{"94":{},"106":{},"107":{},"123":{},"128":{},"282":{},"300":{}},"tags":{}}],["period",{"_index":704,"title":{},"content":{"105":{}},"tags":{}}],["perman",{"_index":701,"title":{},"content":{"105":{}},"tags":{}}],["permiss",{"_index":663,"title":{},"content":{"103":{},"117":{},"118":{},"322":{}},"tags":{}}],["permit",{"_index":843,"title":{},"content":{"113":{},"121":{}},"tags":{}}],["persist",{"_index":775,"title":{},"content":{"107":{},"315":{},"316":{}},"tags":{}}],["person",{"_index":602,"title":{},"content":{"100":{}},"tags":{}}],["persona",{"_index":657,"title":{"103":{}},"content":{"108":{}},"tags":{}}],["perspect",{"_index":567,"title":{"305":{}},"content":{"99":{},"295":{}},"tags":{}}],["phase",{"_index":627,"title":{},"content":{"101":{},"288":{}},"tags":{}}],["physic",{"_index":621,"title":{},"content":{"101":{},"102":{},"105":{},"106":{},"107":{}},"tags":{}}],["piec",{"_index":319,"title":{},"content":{"75":{}},"tags":{}}],["pii",{"_index":603,"title":{},"content":{"100":{}},"tags":{}}],["pki",{"_index":420,"title":{},"content":{"89":{},"99":{},"129":{}},"tags":{}}],["placehold",{"_index":1023,"title":{},"content":{"285":{}},"tags":{}}],["plain",{"_index":1033,"title":{},"content":{"286":{}},"tags":{}}],["plan",{"_index":1182,"title":{"313":{}},"content":{"313":{},"314":{}},"tags":{}}],["plane",{"_index":639,"title":{},"content":{"102":{},"106":{},"107":{}},"tags":{}}],["platform",{"_index":322,"title":{},"content":{"75":{},"99":{},"101":{},"105":{},"296":{},"314":{},"317":{}},"tags":{}}],["platform'",{"_index":794,"title":{},"content":{"108":{}},"tags":{}}],["play",{"_index":373,"title":{},"content":{"80":{}},"tags":{}}],["pleas",{"_index":1068,"title":{},"content":{"287":{},"297":{}},"tags":{}}],["plugin",{"_index":847,"title":{},"content":{"115":{},"124":{},"128":{}},"tags":{}}],["pod",{"_index":12,"title":{"71":{},"127":{}},"content":{"71":{},"72":{},"76":{},"79":{},"91":{},"93":{},"95":{},"96":{},"97":{},"99":{},"101":{},"102":{},"111":{},"112":{},"116":{},"118":{},"119":{},"120":{},"121":{},"122":{},"125":{},"126":{},"127":{},"128":{},"132":{},"277":{},"285":{},"289":{},"302":{},"316":{}},"tags":{}}],["pod'",{"_index":283,"title":{},"content":{"71":{},"88":{}},"tags":{}}],["podspec",{"_index":863,"title":{},"content":{"117":{},"118":{}},"tags":{}}],["podvm",{"_index":848,"title":{},"content":{"115":{}},"tags":{}}],["pod’",{"_index":368,"title":{},"content":{"79":{}},"tags":{}}],["point",{"_index":343,"title":{},"content":{"75":{},"106":{}},"tags":{}}],["polici",{"_index":150,"title":{"76":{},"113":{},"116":{},"287":{},"302":{},"316":{}},"content":{"67":{},"69":{},"71":{},"72":{},"75":{},"76":{},"78":{},"79":{},"97":{},"101":{},"102":{},"107":{},"110":{},"112":{},"113":{},"116":{},"117":{},"118":{},"119":{},"120":{},"121":{},"126":{},"285":{},"287":{},"291":{},"302":{},"306":{},"307":{},"310":{},"316":{}},"tags":{}}],["policy'",{"_index":279,"title":{},"content":{"71":{},"118":{},"121":{}},"tags":{}}],["pool",{"_index":561,"title":{},"content":{"98":{},"325":{},"326":{}},"tags":{}}],["popul",{"_index":862,"title":{},"content":{"117":{},"286":{}},"tags":{}}],["port",{"_index":472,"title":{},"content":{"93":{},"94":{},"130":{},"131":{},"132":{},"286":{},"289":{},"315":{},"317":{}},"tags":{}}],["port>#::###fals",{"_index":971,"title":{},"content":{"395":{}},"tags":{}}],["name>##tru",{"_index":978,"title":{},"content":{"395":{}},"tags":{}}],["namespac",{"_index":1238,"title":{},"content":{"3":{},"12":{},"15":{}},"tags":{}}],["nativ",{"_index":612,"title":{},"content":{"363":{}},"tags":{}}],["necessari",{"_index":846,"title":{},"content":{"374":{},"400":{},"403":{},"429":{}},"tags":{}}],["need",{"_index":444,"title":{},"content":{"2":{},"3":{},"5":{},"352":{},"357":{},"358":{},"371":{},"372":{},"375":{},"381":{},"386":{},"387":{},"398":{},"400":{},"405":{},"415":{},"420":{},"421":{},"422":{},"433":{}},"tags":{}}],["nest",{"_index":574,"title":{},"content":{"361":{},"362":{}},"tags":{}}],["net_admin",{"_index":996,"title":{},"content":{"395":{}},"tags":{}}],["network",{"_index":579,"title":{},"content":{"361":{},"367":{},"369":{},"370":{},"371":{},"393":{}},"tags":{}}],["new",{"_index":426,"title":{},"content":{"4":{},"6":{},"350":{},"352":{},"354":{},"369":{},"371":{},"375":{},"392":{},"409":{},"426":{},"427":{}},"tags":{}}],["newli",{"_index":1148,"title":{},"content":{"409":{}},"tags":{}}],["newmeshcert",{"_index":496,"title":{},"content":{"354":{}},"tags":{}}],["next",{"_index":107,"title":{"331":{}},"content":{"15":{},"405":{},"422":{},"426":{}},"tags":{}}],["node",{"_index":570,"title":{"387":{},"392":{}},"content":{"5":{},"6":{},"361":{},"362":{},"367":{},"379":{},"385":{},"387":{},"389":{},"392":{},"398":{},"415":{},"433":{}},"tags":{}}],["node.k8s.io/v1",{"_index":923,"title":{},"content":{"386":{}},"tags":{}}],["nodepool",{"_index":1270,"title":{},"content":{"5":{}},"tags":{}}],["nodepool1",{"_index":1273,"title":{},"content":{"5":{}},"tags":{}}],["nodepool2",{"_index":1271,"title":{},"content":{"5":{}},"tags":{}}],["non",{"_index":774,"title":{},"content":{"5":{},"371":{},"395":{}},"tags":{}}],["none",{"_index":1280,"title":{},"content":{"5":{}},"tags":{}}],["northeurop",{"_index":1252,"title":{},"content":{"4":{}},"tags":{}}],["notabl",{"_index":329,"title":{},"content":{"340":{}},"tags":{}}],["note",{"_index":675,"title":{},"content":{"366":{},"395":{}},"tags":{}}],["now",{"_index":1145,"title":{},"content":{"5":{},"409":{},"419":{}},"tags":{}}],["number",{"_index":485,"title":{},"content":{"354":{}},"tags":{}}],["numer",{"_index":463,"title":{},"content":{"353":{}},"tags":{}}],["o=jsonpath='{.spec.runtimeclassnam",{"_index":1352,"title":{},"content":{"15":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1095,"title":{},"content":{"405":{},"408":{},"418":{},"423":{}},"tags":{}}],["object",{"_index":555,"title":{},"content":{"12":{},"360":{},"393":{},"394":{},"431":{}},"tags":{}}],["observ",{"_index":455,"title":{"353":{}},"content":{"384":{}},"tags":{}}],["obtain",{"_index":208,"title":{},"content":{"15":{},"334":{},"338":{},"351":{}},"tags":{}}],["occur",{"_index":135,"title":{},"content":{"332":{}},"tags":{}}],["oci",{"_index":561,"title":{},"content":{"360":{},"361":{},"382":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"330":{},"362":{},"363":{},"372":{},"375":{}},"tags":{}}],["offlin",{"_index":300,"title":{},"content":{"337":{}},"tags":{}}],["older",{"_index":1201,"title":{},"content":{"426":{},"427":{}},"tags":{}}],["omit",{"_index":910,"title":{},"content":{"384":{},"402":{},"431":{}},"tags":{}}],["on",{"_index":273,"title":{},"content":{"4":{},"11":{},"14":{},"15":{},"336":{},"360":{},"372":{},"396":{},"433":{}},"tags":{}}],["onc",{"_index":1023,"title":{},"content":{"398":{},"415":{}},"tags":{}}],["opa",{"_index":584,"title":{},"content":{"361":{},"377":{}},"tags":{}}],["open",{"_index":139,"title":{},"content":{"332":{},"361":{},"377":{}},"tags":{}}],["openssl",{"_index":1128,"title":{},"content":{"408":{},"423":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"3":{},"329":{},"337":{},"343":{},"345":{},"355":{},"363":{},"364":{},"365":{},"367":{},"369":{},"370":{},"372":{},"374":{},"409":{}},"tags":{}}],["optim",{"_index":591,"title":{},"content":{"363":{}},"tags":{}}],["option",{"_index":569,"title":{"424":{}},"content":{"5":{},"361":{}},"tags":{}}],["orchestr",{"_index":613,"title":{},"content":{"363":{},"377":{}},"tags":{}}],["order",{"_index":533,"title":{},"content":{"357":{},"384":{},"403":{},"431":{}},"tags":{}}],["origin",{"_index":580,"title":{},"content":{"361":{},"393":{},"401":{}},"tags":{}}],["os",{"_index":129,"title":{},"content":{"5":{},"332":{},"366":{}},"tags":{}}],["os.readfile(\"/tl",{"_index":1069,"title":{},"content":{"402":{}},"tags":{}}],["otherwis",{"_index":902,"title":{},"content":{"383":{},"395":{}},"tags":{}}],["out",{"_index":449,"title":{"427":{}},"content":{"6":{},"352":{},"368":{},"369":{},"371":{},"392":{},"395":{},"421":{},"427":{}},"tags":{}}],["outlin",{"_index":626,"title":{},"content":{"364":{},"400":{}},"tags":{}}],["output",{"_index":1170,"title":{},"content":{"3":{},"11":{},"12":{},"15":{},"414":{}},"tags":{}}],["outsid",{"_index":881,"title":{},"content":{"381":{},"395":{}},"tags":{}}],["over",{"_index":575,"title":{},"content":{"361":{},"369":{},"395":{},"396":{},"419":{},"421":{}},"tags":{}}],["overview",{"_index":625,"title":{"364":{}},"content":{"373":{}},"tags":{}}],["own",{"_index":688,"title":{},"content":{"367":{}},"tags":{}}],["owner",{"_index":197,"title":{"338":{}},"content":{"334":{},"338":{},"351":{},"352":{},"356":{},"358":{},"365":{},"367":{},"371":{},"372":{},"407":{},"411":{}},"tags":{}}],["owner'",{"_index":861,"title":{},"content":{"376":{},"380":{}},"tags":{}}],["ownership",{"_index":632,"title":{},"content":{"364":{}},"tags":{}}],["owners—to",{"_index":376,"title":{},"content":{"345":{}},"tags":{}}],["p",{"_index":1106,"title":{},"content":{"408":{}},"tags":{}}],["packet",{"_index":968,"title":{},"content":{"395":{}},"tags":{}}],["page",{"_index":326,"title":{},"content":{"340":{},"373":{}},"tags":{}}],["pair",{"_index":468,"title":{},"content":{"353":{}},"tags":{}}],["paramet",{"_index":882,"title":{},"content":{"381":{},"382":{}},"tags":{}}],["pars",{"_index":786,"title":{},"content":{"371":{}},"tags":{}}],["part",{"_index":260,"title":{},"content":{"11":{},"336":{},"340":{},"344":{},"352":{},"366":{},"376":{},"380":{},"381":{},"386":{},"390":{},"393":{},"396":{},"414":{},"419":{},"426":{}},"tags":{}}],["parti",{"_index":105,"title":{"338":{},"347":{}},"content":{"330":{},"334":{},"338":{},"347":{},"349":{},"351":{},"363":{},"367":{},"369":{},"372":{},"375":{},"395":{}},"tags":{}}],["particip",{"_index":875,"title":{},"content":{"380":{}},"tags":{}}],["particular",{"_index":1227,"title":{},"content":{"431":{}},"tags":{}}],["particularli",{"_index":635,"title":{},"content":{"364":{},"384":{}},"tags":{}}],["parties—such",{"_index":375,"title":{},"content":{"345":{}},"tags":{}}],["partit",{"_index":771,"title":{},"content":{"371":{},"391":{}},"tags":{}}],["pass",{"_index":257,"title":{},"content":{"336":{},"357":{},"407":{},"409":{}},"tags":{}}],["passiv",{"_index":781,"title":{},"content":{"371":{}},"tags":{}}],["patch",{"_index":1104,"title":{},"content":{"408":{},"426":{}},"tags":{}}],["path",{"_index":1293,"title":{},"content":{"7":{}},"tags":{}}],["patient",{"_index":828,"title":{},"content":{"372":{}},"tags":{}}],["peer",{"_index":1062,"title":{},"content":{"402":{}},"tags":{}}],["pend",{"_index":1210,"title":{},"content":{"429":{}},"tags":{}}],["per",{"_index":952,"title":{},"content":{"393":{},"403":{}},"tags":{}}],["perform",{"_index":508,"title":{},"content":{"355":{},"370":{},"371":{},"387":{},"392":{},"398":{},"415":{}},"tags":{}}],["period",{"_index":729,"title":{},"content":{"369":{}},"tags":{}}],["perman",{"_index":726,"title":{},"content":{"369":{}},"tags":{}}],["permiss",{"_index":689,"title":{},"content":{"2":{},"367":{},"381":{},"382":{}},"tags":{}}],["permit",{"_index":865,"title":{},"content":{"377":{},"385":{}},"tags":{}}],["persist",{"_index":527,"title":{"357":{}},"content":{"357":{},"358":{},"371":{},"430":{},"431":{}},"tags":{}}],["person",{"_index":629,"title":{},"content":{"364":{}},"tags":{}}],["persona",{"_index":684,"title":{"367":{}},"content":{"372":{}},"tags":{}}],["perspect",{"_index":593,"title":{"420":{}},"content":{"363":{},"410":{}},"tags":{}}],["phase",{"_index":654,"title":{},"content":{"365":{},"404":{},"409":{}},"tags":{}}],["physic",{"_index":648,"title":{},"content":{"365":{},"366":{},"369":{},"370":{},"371":{}},"tags":{}}],["piec",{"_index":315,"title":{},"content":{"340":{}},"tags":{}}],["pii",{"_index":630,"title":{},"content":{"364":{}},"tags":{}}],["pin",{"_index":1333,"title":{"14":{}},"content":{"14":{}},"tags":{}}],["pki",{"_index":416,"title":{},"content":{"350":{},"363":{},"393":{}},"tags":{}}],["placehold",{"_index":1041,"title":{},"content":{"401":{}},"tags":{}}],["plain",{"_index":535,"title":{},"content":{"357":{},"402":{}},"tags":{}}],["plan",{"_index":1208,"title":{"428":{}},"content":{"428":{},"429":{},"430":{},"433":{}},"tags":{}}],["plane",{"_index":666,"title":{},"content":{"366":{},"370":{},"371":{}},"tags":{}}],["platform",{"_index":318,"title":{},"content":{"340":{},"363":{},"365":{},"369":{},"411":{},"429":{},"432":{}},"tags":{}}],["platform'",{"_index":816,"title":{},"content":{"372":{}},"tags":{}}],["play",{"_index":369,"title":{},"content":{"345":{}},"tags":{}}],["pleas",{"_index":1085,"title":{},"content":{"403":{},"412":{}},"tags":{}}],["plugin",{"_index":870,"title":{},"content":{"379":{},"388":{},"392":{}},"tags":{}}],["pod",{"_index":12,"title":{"12":{},"336":{},"391":{}},"content":{"11":{},"12":{},"14":{},"15":{},"328":{},"336":{},"337":{},"341":{},"344":{},"352":{},"354":{},"359":{},"360":{},"361":{},"363":{},"365":{},"366":{},"375":{},"376":{},"380":{},"382":{},"383":{},"384":{},"385":{},"386":{},"389":{},"390":{},"391":{},"392":{},"396":{},"401":{},"405":{},"409":{},"417":{},"431":{},"433":{}},"tags":{}}],["pod'",{"_index":275,"title":{},"content":{"336":{},"349":{}},"tags":{}}],["pod/#::###fals",{"_index":971,"title":{},"content":{"514":{}},"tags":{}}],["name>##tru",{"_index":978,"title":{},"content":{"514":{}},"tags":{}}],["namespac",{"_index":1237,"title":{},"content":{"542":{},"551":{},"554":{}},"tags":{}}],["nativ",{"_index":612,"title":{},"content":{"469":{}},"tags":{}}],["necessari",{"_index":846,"title":{},"content":{"480":{},"502":{},"505":{},"535":{}},"tags":{}}],["need",{"_index":444,"title":{},"content":{"458":{},"463":{},"464":{},"477":{},"478":{},"481":{},"487":{},"492":{},"493":{},"500":{},"502":{},"507":{},"521":{},"526":{},"527":{},"528":{},"539":{},"541":{},"542":{},"544":{}},"tags":{}}],["nest",{"_index":574,"title":{},"content":{"467":{},"468":{}},"tags":{}}],["net_admin",{"_index":996,"title":{},"content":{"514":{}},"tags":{}}],["network",{"_index":579,"title":{},"content":{"467":{},"473":{},"475":{},"476":{},"477":{},"512":{}},"tags":{}}],["new",{"_index":426,"title":{},"content":{"456":{},"458":{},"460":{},"475":{},"477":{},"481":{},"498":{},"511":{},"532":{},"533":{},"543":{},"545":{}},"tags":{}}],["newli",{"_index":1148,"title":{},"content":{"511":{}},"tags":{}}],["newmeshcert",{"_index":496,"title":{},"content":{"460":{}},"tags":{}}],["next",{"_index":107,"title":{"437":{}},"content":{"507":{},"528":{},"532":{},"554":{}},"tags":{}}],["node",{"_index":570,"title":{"493":{},"498":{}},"content":{"467":{},"468":{},"473":{},"485":{},"491":{},"493":{},"495":{},"498":{},"500":{},"521":{},"539":{},"544":{},"545":{}},"tags":{}}],["node.k8s.io/v1",{"_index":923,"title":{},"content":{"492":{}},"tags":{}}],["nodepool",{"_index":1269,"title":{},"content":{"544":{}},"tags":{}}],["nodepool1",{"_index":1272,"title":{},"content":{"544":{}},"tags":{}}],["nodepool2",{"_index":1270,"title":{},"content":{"544":{}},"tags":{}}],["non",{"_index":774,"title":{},"content":{"477":{},"514":{},"544":{}},"tags":{}}],["none",{"_index":1279,"title":{},"content":{"544":{}},"tags":{}}],["northeurop",{"_index":1251,"title":{},"content":{"543":{}},"tags":{}}],["notabl",{"_index":329,"title":{},"content":{"446":{}},"tags":{}}],["note",{"_index":675,"title":{},"content":{"472":{},"514":{}},"tags":{}}],["now",{"_index":1145,"title":{},"content":{"511":{},"525":{},"544":{}},"tags":{}}],["number",{"_index":485,"title":{},"content":{"460":{}},"tags":{}}],["numer",{"_index":463,"title":{},"content":{"459":{}},"tags":{}}],["o=jsonpath='{.spec.runtimeclassnam",{"_index":1345,"title":{},"content":{"554":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1095,"title":{},"content":{"507":{},"510":{},"524":{},"529":{}},"tags":{}}],["object",{"_index":555,"title":{},"content":{"466":{},"512":{},"513":{},"537":{},"551":{}},"tags":{}}],["observ",{"_index":455,"title":{"459":{}},"content":{"490":{}},"tags":{}}],["obtain",{"_index":208,"title":{},"content":{"440":{},"444":{},"457":{},"554":{}},"tags":{}}],["occur",{"_index":135,"title":{},"content":{"438":{}},"tags":{}}],["oci",{"_index":561,"title":{},"content":{"466":{},"467":{},"488":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"436":{},"468":{},"469":{},"478":{},"481":{}},"tags":{}}],["offlin",{"_index":300,"title":{},"content":{"443":{}},"tags":{}}],["older",{"_index":1200,"title":{},"content":{"532":{},"533":{}},"tags":{}}],["omit",{"_index":910,"title":{},"content":{"490":{},"504":{},"537":{}},"tags":{}}],["on",{"_index":273,"title":{},"content":{"442":{},"466":{},"478":{},"515":{},"539":{},"543":{},"550":{},"553":{},"554":{}},"tags":{}}],["onc",{"_index":1023,"title":{},"content":{"500":{},"521":{}},"tags":{}}],["opa",{"_index":584,"title":{},"content":{"467":{},"483":{}},"tags":{}}],["open",{"_index":139,"title":{},"content":{"438":{},"467":{},"483":{}},"tags":{}}],["openssl",{"_index":1128,"title":{},"content":{"510":{},"529":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"435":{},"443":{},"449":{},"451":{},"461":{},"469":{},"470":{},"471":{},"473":{},"475":{},"476":{},"478":{},"480":{},"511":{},"542":{}},"tags":{}}],["optim",{"_index":591,"title":{},"content":{"469":{}},"tags":{}}],["option",{"_index":569,"title":{"530":{}},"content":{"467":{},"544":{}},"tags":{}}],["orchestr",{"_index":613,"title":{},"content":{"469":{},"483":{}},"tags":{}}],["order",{"_index":533,"title":{},"content":{"463":{},"490":{},"505":{},"537":{}},"tags":{}}],["origin",{"_index":580,"title":{},"content":{"467":{},"503":{},"512":{}},"tags":{}}],["os",{"_index":129,"title":{},"content":{"438":{},"472":{},"544":{}},"tags":{}}],["os.readfile(\"/tl",{"_index":1069,"title":{},"content":{"504":{}},"tags":{}}],["otherwis",{"_index":902,"title":{},"content":{"489":{},"514":{}},"tags":{}}],["out",{"_index":449,"title":{"533":{}},"content":{"458":{},"474":{},"475":{},"477":{},"498":{},"514":{},"527":{},"533":{},"545":{}},"tags":{}}],["outlin",{"_index":626,"title":{},"content":{"470":{},"502":{}},"tags":{}}],["output",{"_index":1170,"title":{},"content":{"520":{},"542":{},"550":{},"551":{},"554":{}},"tags":{}}],["outsid",{"_index":881,"title":{},"content":{"487":{},"514":{}},"tags":{}}],["over",{"_index":575,"title":{},"content":{"467":{},"475":{},"514":{},"515":{},"525":{},"527":{}},"tags":{}}],["overview",{"_index":625,"title":{"470":{}},"content":{"479":{}},"tags":{}}],["own",{"_index":688,"title":{},"content":{"473":{}},"tags":{}}],["owner",{"_index":197,"title":{"444":{}},"content":{"440":{},"444":{},"457":{},"458":{},"462":{},"464":{},"471":{},"473":{},"477":{},"478":{},"509":{},"517":{}},"tags":{}}],["owner'",{"_index":861,"title":{},"content":{"482":{},"486":{}},"tags":{}}],["ownership",{"_index":632,"title":{},"content":{"470":{}},"tags":{}}],["owners—to",{"_index":376,"title":{},"content":{"451":{}},"tags":{}}],["p",{"_index":1106,"title":{},"content":{"510":{}},"tags":{}}],["packet",{"_index":968,"title":{},"content":{"514":{}},"tags":{}}],["page",{"_index":326,"title":{},"content":{"446":{},"479":{}},"tags":{}}],["pair",{"_index":468,"title":{},"content":{"459":{}},"tags":{}}],["paramet",{"_index":882,"title":{},"content":{"487":{},"488":{}},"tags":{}}],["pars",{"_index":786,"title":{},"content":{"477":{}},"tags":{}}],["part",{"_index":260,"title":{},"content":{"442":{},"446":{},"450":{},"458":{},"472":{},"482":{},"486":{},"487":{},"492":{},"496":{},"512":{},"515":{},"520":{},"525":{},"532":{},"550":{}},"tags":{}}],["parti",{"_index":105,"title":{"444":{},"453":{}},"content":{"436":{},"440":{},"444":{},"453":{},"455":{},"457":{},"469":{},"473":{},"475":{},"478":{},"481":{},"514":{}},"tags":{}}],["particip",{"_index":875,"title":{},"content":{"486":{}},"tags":{}}],["particular",{"_index":1226,"title":{},"content":{"537":{}},"tags":{}}],["particularli",{"_index":635,"title":{},"content":{"470":{},"490":{}},"tags":{}}],["parties—such",{"_index":375,"title":{},"content":{"451":{}},"tags":{}}],["partit",{"_index":771,"title":{},"content":{"477":{},"497":{}},"tags":{}}],["pass",{"_index":257,"title":{},"content":{"442":{},"463":{},"509":{},"511":{}},"tags":{}}],["passiv",{"_index":781,"title":{},"content":{"477":{}},"tags":{}}],["patch",{"_index":1104,"title":{},"content":{"510":{},"532":{}},"tags":{}}],["path",{"_index":1292,"title":{},"content":{"546":{}},"tags":{}}],["patient",{"_index":828,"title":{},"content":{"478":{}},"tags":{}}],["peer",{"_index":1062,"title":{},"content":{"504":{}},"tags":{}}],["pend",{"_index":1209,"title":{},"content":{"535":{}},"tags":{}}],["per",{"_index":952,"title":{},"content":{"505":{},"512":{}},"tags":{}}],["perform",{"_index":508,"title":{},"content":{"461":{},"476":{},"477":{},"493":{},"498":{},"500":{},"521":{}},"tags":{}}],["period",{"_index":729,"title":{},"content":{"475":{}},"tags":{}}],["perman",{"_index":726,"title":{},"content":{"475":{}},"tags":{}}],["permiss",{"_index":689,"title":{},"content":{"473":{},"487":{},"488":{},"541":{}},"tags":{}}],["permit",{"_index":865,"title":{},"content":{"483":{},"491":{}},"tags":{}}],["persist",{"_index":527,"title":{"463":{}},"content":{"463":{},"464":{},"477":{},"536":{},"537":{}},"tags":{}}],["person",{"_index":629,"title":{},"content":{"470":{}},"tags":{}}],["persona",{"_index":684,"title":{"473":{}},"content":{"478":{}},"tags":{}}],["perspect",{"_index":593,"title":{"526":{}},"content":{"469":{},"516":{}},"tags":{}}],["phase",{"_index":654,"title":{},"content":{"471":{},"506":{},"511":{}},"tags":{}}],["physic",{"_index":648,"title":{},"content":{"471":{},"472":{},"475":{},"476":{},"477":{}},"tags":{}}],["piec",{"_index":315,"title":{},"content":{"446":{}},"tags":{}}],["pii",{"_index":630,"title":{},"content":{"470":{}},"tags":{}}],["pin",{"_index":1332,"title":{"553":{}},"content":{"553":{}},"tags":{}}],["pki",{"_index":416,"title":{},"content":{"456":{},"469":{},"512":{}},"tags":{}}],["placehold",{"_index":1041,"title":{},"content":{"503":{}},"tags":{}}],["plain",{"_index":535,"title":{},"content":{"463":{},"504":{}},"tags":{}}],["plan",{"_index":1207,"title":{"534":{}},"content":{"534":{},"535":{},"536":{},"539":{}},"tags":{}}],["plane",{"_index":666,"title":{},"content":{"472":{},"476":{},"477":{}},"tags":{}}],["platform",{"_index":318,"title":{},"content":{"446":{},"469":{},"471":{},"475":{},"517":{},"523":{},"535":{},"538":{}},"tags":{}}],["platform'",{"_index":816,"title":{},"content":{"478":{}},"tags":{}}],["play",{"_index":369,"title":{},"content":{"451":{}},"tags":{}}],["pleas",{"_index":1085,"title":{},"content":{"505":{},"518":{}},"tags":{}}],["plugin",{"_index":870,"title":{},"content":{"485":{},"494":{},"498":{}},"tags":{}}],["pod",{"_index":12,"title":{"442":{},"497":{},"551":{}},"content":{"434":{},"442":{},"443":{},"447":{},"450":{},"458":{},"460":{},"465":{},"466":{},"467":{},"469":{},"471":{},"472":{},"481":{},"482":{},"486":{},"488":{},"489":{},"490":{},"491":{},"492":{},"495":{},"496":{},"497":{},"498":{},"503":{},"507":{},"511":{},"515":{},"523":{},"537":{},"539":{},"550":{},"551":{},"553":{},"554":{}},"tags":{}}],["pod'",{"_index":275,"title":{},"content":{"442":{},"455":{}},"tags":{}}],["pod/#::/secrets/workload",{"_index":543,"title":{},"content":{"586":{}},"tags":{}}],["move",{"_index":91,"title":{},"content":{"557":{},"675":{}},"tags":{}}],["mtl",{"_index":414,"title":{},"content":{"576":{},"591":{},"621":{},"647":{}},"tags":{}}],["multi",{"_index":104,"title":{},"content":{"557":{},"593":{}},"tags":{}}],["multipl",{"_index":976,"title":{},"content":{"623":{},"624":{}},"tags":{}}],["mutual",{"_index":430,"title":{},"content":{"578":{},"591":{},"595":{},"621":{}},"tags":{}}],["my_resource_dir",{"_index":1036,"title":{},"content":{"629":{}},"tags":{}}],["my_servic",{"_index":1108,"title":{},"content":{"636":{}},"tags":{}}],["n",{"_index":1323,"title":{},"content":{"673":{},"676":{}},"tags":{}}],["name",{"_index":465,"title":{},"content":{"580":{},"581":{},"614":{},"623":{},"624":{},"629":{},"631":{},"636":{},"649":{},"652":{},"664":{},"665":{},"666":{},"667":{},"672":{},"673":{},"676":{}},"tags":{}}],["name>###fals",{"_index":975,"title":{},"content":{"623":{}},"tags":{}}],["name>##tru",{"_index":982,"title":{},"content":{"623":{}},"tags":{}}],["namespac",{"_index":1241,"title":{},"content":{"664":{},"673":{},"676":{}},"tags":{}}],["nativ",{"_index":618,"title":{},"content":{"591":{}},"tags":{}}],["necessari",{"_index":851,"title":{},"content":{"602":{},"628":{},"631":{},"657":{}},"tags":{}}],["need",{"_index":444,"title":{},"content":{"579":{},"584":{},"585":{},"599":{},"600":{},"603":{},"609":{},"614":{},"615":{},"626":{},"628":{},"633":{},"643":{},"648":{},"649":{},"650":{},"661":{},"663":{},"664":{},"666":{}},"tags":{}}],["nest",{"_index":580,"title":{},"content":{"589":{},"590":{}},"tags":{}}],["net_admin",{"_index":1000,"title":{},"content":{"623":{}},"tags":{}}],["network",{"_index":585,"title":{},"content":{"589":{},"595":{},"597":{},"598":{},"599":{},"621":{}},"tags":{}}],["new",{"_index":426,"title":{},"content":{"577":{},"579":{},"581":{},"597":{},"599":{},"603":{},"620":{},"637":{},"654":{},"655":{},"665":{},"667":{}},"tags":{}}],["newli",{"_index":1151,"title":{},"content":{"637":{}},"tags":{}}],["newmeshcert",{"_index":496,"title":{},"content":{"581":{}},"tags":{}}],["next",{"_index":107,"title":{"558":{}},"content":{"633":{},"650":{},"654":{},"676":{}},"tags":{}}],["node",{"_index":576,"title":{"615":{},"620":{}},"content":{"589":{},"590":{},"595":{},"607":{},"613":{},"615":{},"617":{},"620":{},"626":{},"643":{},"661":{},"666":{},"667":{}},"tags":{}}],["node.k8s.io/v1",{"_index":927,"title":{},"content":{"614":{}},"tags":{}}],["nodepool",{"_index":1273,"title":{},"content":{"666":{}},"tags":{}}],["nodepool1",{"_index":1276,"title":{},"content":{"666":{}},"tags":{}}],["nodepool2",{"_index":1274,"title":{},"content":{"666":{}},"tags":{}}],["non",{"_index":780,"title":{},"content":{"599":{},"623":{},"666":{}},"tags":{}}],["none",{"_index":1283,"title":{},"content":{"666":{}},"tags":{}}],["northeurop",{"_index":1255,"title":{},"content":{"665":{}},"tags":{}}],["notabl",{"_index":329,"title":{},"content":{"567":{}},"tags":{}}],["note",{"_index":681,"title":{},"content":{"594":{},"623":{}},"tags":{}}],["now",{"_index":1148,"title":{},"content":{"637":{},"647":{},"666":{}},"tags":{}}],["number",{"_index":485,"title":{},"content":{"581":{}},"tags":{}}],["numer",{"_index":463,"title":{},"content":{"580":{}},"tags":{}}],["o=jsonpath='{.spec.runtimeclassnam",{"_index":1348,"title":{},"content":{"676":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1098,"title":{},"content":{"633":{},"636":{},"646":{},"651":{}},"tags":{}}],["object",{"_index":561,"title":{},"content":{"588":{},"621":{},"622":{},"659":{},"673":{}},"tags":{}}],["observ",{"_index":455,"title":{"580":{}},"content":{"612":{}},"tags":{}}],["obtain",{"_index":208,"title":{},"content":{"561":{},"565":{},"578":{},"676":{}},"tags":{}}],["occur",{"_index":135,"title":{},"content":{"559":{}},"tags":{}}],["oci",{"_index":567,"title":{},"content":{"588":{},"589":{},"610":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"557":{},"590":{},"591":{},"600":{},"603":{}},"tags":{}}],["offlin",{"_index":300,"title":{},"content":{"564":{}},"tags":{}}],["older",{"_index":1204,"title":{},"content":{"654":{},"655":{}},"tags":{}}],["omit",{"_index":914,"title":{},"content":{"612":{},"630":{},"659":{}},"tags":{}}],["on",{"_index":273,"title":{},"content":{"563":{},"588":{},"600":{},"624":{},"661":{},"665":{},"672":{},"675":{},"676":{}},"tags":{}}],["onc",{"_index":1025,"title":{},"content":{"626":{},"643":{}},"tags":{}}],["opa",{"_index":590,"title":{},"content":{"589":{},"605":{}},"tags":{}}],["open",{"_index":139,"title":{},"content":{"559":{},"589":{},"605":{}},"tags":{}}],["openssl",{"_index":1131,"title":{},"content":{"636":{},"651":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"556":{},"564":{},"570":{},"572":{},"582":{},"591":{},"592":{},"593":{},"595":{},"597":{},"598":{},"600":{},"602":{},"637":{},"664":{}},"tags":{}}],["optim",{"_index":597,"title":{},"content":{"591":{}},"tags":{}}],["option",{"_index":575,"title":{"652":{}},"content":{"589":{},"666":{}},"tags":{}}],["orchestr",{"_index":619,"title":{},"content":{"591":{},"605":{}},"tags":{}}],["order",{"_index":533,"title":{},"content":{"584":{},"612":{},"631":{},"659":{}},"tags":{}}],["origin",{"_index":586,"title":{},"content":{"589":{},"621":{},"629":{}},"tags":{}}],["os",{"_index":129,"title":{},"content":{"559":{},"594":{},"666":{}},"tags":{}}],["os.readfile(\"/contrast/tl",{"_index":1071,"title":{},"content":{"630":{}},"tags":{}}],["otherwis",{"_index":906,"title":{},"content":{"611":{},"623":{}},"tags":{}}],["out",{"_index":449,"title":{"655":{}},"content":{"579":{},"596":{},"597":{},"599":{},"620":{},"623":{},"649":{},"655":{},"667":{}},"tags":{}}],["outlin",{"_index":632,"title":{},"content":{"592":{},"628":{}},"tags":{}}],["output",{"_index":1173,"title":{},"content":{"642":{},"664":{},"672":{},"673":{},"676":{}},"tags":{}}],["outsid",{"_index":885,"title":{},"content":{"609":{},"623":{}},"tags":{}}],["over",{"_index":581,"title":{},"content":{"589":{},"597":{},"623":{},"624":{},"647":{},"649":{}},"tags":{}}],["overview",{"_index":631,"title":{"592":{}},"content":{"601":{}},"tags":{}}],["own",{"_index":694,"title":{},"content":{"595":{}},"tags":{}}],["owner",{"_index":197,"title":{"565":{}},"content":{"561":{},"565":{},"578":{},"579":{},"583":{},"585":{},"586":{},"593":{},"595":{},"599":{},"600":{},"635":{},"639":{}},"tags":{}}],["owner'",{"_index":865,"title":{},"content":{"604":{},"608":{}},"tags":{}}],["ownership",{"_index":638,"title":{},"content":{"592":{}},"tags":{}}],["owners—to",{"_index":376,"title":{},"content":{"572":{}},"tags":{}}],["p",{"_index":1109,"title":{},"content":{"636":{}},"tags":{}}],["packet",{"_index":972,"title":{},"content":{"623":{}},"tags":{}}],["page",{"_index":326,"title":{},"content":{"567":{},"601":{}},"tags":{}}],["pair",{"_index":468,"title":{},"content":{"580":{}},"tags":{}}],["paramet",{"_index":886,"title":{},"content":{"609":{},"610":{}},"tags":{}}],["pars",{"_index":792,"title":{},"content":{"599":{}},"tags":{}}],["part",{"_index":260,"title":{},"content":{"563":{},"567":{},"571":{},"579":{},"594":{},"604":{},"608":{},"609":{},"614":{},"618":{},"621":{},"624":{},"642":{},"647":{},"654":{},"672":{}},"tags":{}}],["parti",{"_index":105,"title":{"565":{},"574":{}},"content":{"557":{},"561":{},"565":{},"574":{},"576":{},"578":{},"591":{},"595":{},"597":{},"600":{},"603":{},"623":{}},"tags":{}}],["particip",{"_index":879,"title":{},"content":{"608":{}},"tags":{}}],["particular",{"_index":1230,"title":{},"content":{"659":{}},"tags":{}}],["particularli",{"_index":641,"title":{},"content":{"592":{},"612":{}},"tags":{}}],["parties—such",{"_index":375,"title":{},"content":{"572":{}},"tags":{}}],["partit",{"_index":777,"title":{},"content":{"599":{},"619":{}},"tags":{}}],["pass",{"_index":257,"title":{},"content":{"563":{},"584":{},"635":{},"637":{}},"tags":{}}],["passiv",{"_index":787,"title":{},"content":{"599":{}},"tags":{}}],["patch",{"_index":1107,"title":{},"content":{"636":{},"654":{}},"tags":{}}],["path",{"_index":542,"title":{},"content":{"586":{},"668":{}},"tags":{}}],["patient",{"_index":833,"title":{},"content":{"600":{}},"tags":{}}],["peer",{"_index":1064,"title":{},"content":{"630":{}},"tags":{}}],["pend",{"_index":1213,"title":{},"content":{"657":{}},"tags":{}}],["per",{"_index":956,"title":{},"content":{"621":{},"631":{}},"tags":{}}],["perform",{"_index":508,"title":{},"content":{"582":{},"598":{},"599":{},"615":{},"620":{},"626":{},"643":{}},"tags":{}}],["period",{"_index":735,"title":{},"content":{"597":{}},"tags":{}}],["perman",{"_index":732,"title":{},"content":{"597":{}},"tags":{}}],["permiss",{"_index":695,"title":{},"content":{"595":{},"609":{},"610":{},"663":{}},"tags":{}}],["permit",{"_index":869,"title":{},"content":{"605":{},"613":{}},"tags":{}}],["persist",{"_index":527,"title":{"584":{}},"content":{"584":{},"585":{},"586":{},"599":{},"658":{},"659":{}},"tags":{}}],["person",{"_index":635,"title":{},"content":{"592":{}},"tags":{}}],["persona",{"_index":690,"title":{"595":{}},"content":{"600":{}},"tags":{}}],["perspect",{"_index":599,"title":{"648":{}},"content":{"591":{},"638":{}},"tags":{}}],["phase",{"_index":660,"title":{},"content":{"593":{},"632":{},"637":{}},"tags":{}}],["physic",{"_index":654,"title":{},"content":{"593":{},"594":{},"597":{},"598":{},"599":{}},"tags":{}}],["piec",{"_index":315,"title":{},"content":{"567":{}},"tags":{}}],["pii",{"_index":636,"title":{},"content":{"592":{}},"tags":{}}],["pin",{"_index":1335,"title":{"675":{}},"content":{"675":{}},"tags":{}}],["pki",{"_index":416,"title":{},"content":{"577":{},"591":{},"621":{}},"tags":{}}],["placehold",{"_index":1043,"title":{},"content":{"629":{}},"tags":{}}],["plain",{"_index":535,"title":{},"content":{"584":{},"630":{}},"tags":{}}],["plan",{"_index":1211,"title":{"656":{}},"content":{"656":{},"657":{},"658":{},"661":{}},"tags":{}}],["plane",{"_index":672,"title":{},"content":{"594":{},"598":{},"599":{}},"tags":{}}],["platform",{"_index":318,"title":{},"content":{"567":{},"591":{},"593":{},"597":{},"639":{},"645":{},"657":{},"660":{}},"tags":{}}],["platform'",{"_index":821,"title":{},"content":{"600":{}},"tags":{}}],["play",{"_index":369,"title":{},"content":{"572":{}},"tags":{}}],["pleas",{"_index":1088,"title":{},"content":{"631":{},"640":{}},"tags":{}}],["plugin",{"_index":874,"title":{},"content":{"607":{},"616":{},"620":{}},"tags":{}}],["pod",{"_index":12,"title":{"563":{},"619":{},"673":{}},"content":{"555":{},"563":{},"564":{},"568":{},"571":{},"579":{},"581":{},"587":{},"588":{},"589":{},"591":{},"593":{},"594":{},"603":{},"604":{},"608":{},"610":{},"611":{},"612":{},"613":{},"614":{},"617":{},"618":{},"619":{},"620":{},"624":{},"629":{},"633":{},"637":{},"645":{},"659":{},"661":{},"672":{},"673":{},"675":{},"676":{}},"tags":{}}],["pod'",{"_index":275,"title":{},"content":{"563":{},"576":{}},"tags":{}}],["pod/#::/secrets/workload",{"_index":488,"title":{},"content":{"839":{}},"tags":{}}],["move",{"_index":1415,"title":{},"content":{"940":{},"944":{}},"tags":{}}],["mrconfigid",{"_index":183,"title":{},"content":{"816":{},"871":{}},"tags":{}}],["mrseam",{"_index":1140,"title":{},"content":{"893":{},"906":{}},"tags":{}}],["mtl",{"_index":352,"title":{},"content":{"829":{},"851":{},"882":{},"908":{}},"tags":{}}],["multi",{"_index":707,"title":{},"content":{"853":{},"944":{}},"tags":{}}],["multipl",{"_index":1019,"title":{},"content":{"884":{},"885":{}},"tags":{}}],["mutabl",{"_index":541,"title":{},"content":{"845":{}},"tags":{}}],["mutual",{"_index":369,"title":{},"content":{"831":{},"851":{},"855":{},"882":{}},"tags":{}}],["my_resource_dir",{"_index":1084,"title":{},"content":{"891":{}},"tags":{}}],["my_servic",{"_index":1163,"title":{},"content":{"898":{}},"tags":{}}],["n",{"_index":1403,"title":{},"content":{"938":{},"941":{}},"tags":{}}],["name",{"_index":406,"title":{},"content":{"833":{},"834":{},"875":{},"884":{},"885":{},"891":{},"893":{},"898":{},"910":{},"913":{},"929":{},"930":{},"931":{},"932":{},"937":{},"938":{},"941":{}},"tags":{}}],["name>###fals",{"_index":1018,"title":{},"content":{"884":{}},"tags":{}}],["name>##tru",{"_index":1024,"title":{},"content":{"884":{}},"tags":{}}],["namespac",{"_index":1327,"title":{},"content":{"929":{},"938":{},"941":{}},"tags":{}}],["nativ",{"_index":576,"title":{},"content":{"846":{},"851":{}},"tags":{}}],["necessari",{"_index":898,"title":{},"content":{"862":{},"889":{},"893":{},"918":{}},"tags":{}}],["need",{"_index":385,"title":{},"content":{"832":{},"837":{},"838":{},"840":{},"845":{},"859":{},"860":{},"863":{},"869":{},"874":{},"875":{},"876":{},"887":{},"889":{},"895":{},"904":{},"909":{},"910":{},"911":{},"922":{},"929":{}},"tags":{}}],["nest",{"_index":622,"title":{},"content":{"849":{},"850":{}},"tags":{}}],["net_admin",{"_index":1043,"title":{},"content":{"884":{}},"tags":{}}],["network",{"_index":512,"title":{},"content":{"842":{},"849":{},"855":{},"857":{},"858":{},"859":{},"882":{}},"tags":{}}],["new",{"_index":365,"title":{},"content":{"830":{},"832":{},"834":{},"857":{},"859":{},"863":{},"881":{},"899":{},"915":{},"916":{},"930":{},"932":{}},"tags":{}}],["newer",{"_index":1286,"title":{},"content":{"924":{},"928":{}},"tags":{}}],["newli",{"_index":1203,"title":{},"content":{"899":{}},"tags":{}}],["newmeshcert",{"_index":437,"title":{},"content":{"834":{}},"tags":{}}],["next",{"_index":1151,"title":{"945":{}},"content":{"895":{},"911":{},"915":{},"941":{}},"tags":{}}],["node",{"_index":619,"title":{"876":{},"881":{}},"content":{"849":{},"850":{},"855":{},"867":{},"873":{},"876":{},"878":{},"881":{},"887":{},"904":{},"922":{},"931":{},"932":{}},"tags":{}}],["node.k8s.io/v1",{"_index":972,"title":{},"content":{"875":{}},"tags":{}}],["nodepool1",{"_index":1361,"title":{},"content":{"931":{}},"tags":{}}],["non",{"_index":827,"title":{},"content":{"859":{},"884":{},"924":{}},"tags":{}}],["none",{"_index":1365,"title":{},"content":{"931":{}},"tags":{}}],["northeurop",{"_index":1341,"title":{},"content":{"930":{}},"tags":{}}],["notabl",{"_index":251,"title":{},"content":{"820":{}},"tags":{}}],["note",{"_index":737,"title":{},"content":{"854":{},"884":{},"893":{},"906":{},"925":{},"928":{}},"tags":{}}],["now",{"_index":574,"title":{},"content":{"846":{},"899":{},"908":{},"931":{}},"tags":{}}],["number",{"_index":426,"title":{},"content":{"834":{},"924":{}},"tags":{}}],["numer",{"_index":404,"title":{},"content":{"833":{}},"tags":{}}],["nydu",{"_index":991,"title":{},"content":{"879":{}},"tags":{}}],["o=jsonpath='{.spec.runtimeclassnam",{"_index":1426,"title":{},"content":{"941":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1153,"title":{},"content":{"895":{},"898":{},"907":{},"912":{}},"tags":{}}],["object",{"_index":604,"title":{},"content":{"848":{},"882":{},"883":{},"920":{},"938":{}},"tags":{}}],["observ",{"_index":396,"title":{"833":{}},"content":{"872":{},"893":{},"906":{}},"tags":{}}],["obtain",{"_index":107,"title":{},"content":{"814":{},"818":{},"831":{},"941":{}},"tags":{}}],["occur",{"_index":22,"title":{},"content":{"812":{}},"tags":{}}],["oci",{"_index":611,"title":{},"content":{"848":{},"849":{},"870":{}},"tags":{}}],["offer",{"_index":639,"title":{},"content":{"850":{},"851":{},"860":{},"863":{},"944":{}},"tags":{}}],["offlin",{"_index":221,"title":{},"content":{"817":{}},"tags":{}}],["older",{"_index":1254,"title":{},"content":{"915":{},"916":{}},"tags":{}}],["omit",{"_index":956,"title":{},"content":{"872":{},"892":{},"920":{}},"tags":{}}],["on",{"_index":190,"title":{},"content":{"816":{},"848":{},"860":{},"885":{},"922":{},"930":{},"937":{},"940":{},"941":{}},"tags":{}}],["onc",{"_index":1068,"title":{},"content":{"887":{},"904":{}},"tags":{}}],["opa",{"_index":633,"title":{},"content":{"849":{},"865":{}},"tags":{}}],["open",{"_index":28,"title":{},"content":{"812":{},"849":{},"865":{}},"tags":{}}],["openssl",{"_index":1185,"title":{},"content":{"898":{},"912":{}},"tags":{}}],["oper",{"_index":202,"title":{},"content":{"817":{},"823":{},"825":{},"835":{},"851":{},"852":{},"853":{},"855":{},"857":{},"858":{},"860":{},"862":{},"899":{},"929":{},"943":{}},"tags":{}}],["optim",{"_index":645,"title":{},"content":{"851":{}},"tags":{}}],["option",{"_index":618,"title":{"913":{}},"content":{"849":{}},"tags":{}}],["orchestr",{"_index":670,"title":{},"content":{"851":{},"865":{}},"tags":{}}],["order",{"_index":478,"title":{},"content":{"837":{},"872":{},"893":{},"920":{}},"tags":{}}],["origin",{"_index":627,"title":{},"content":{"849":{},"882":{},"891":{}},"tags":{}}],["os",{"_index":15,"title":{},"content":{"812":{},"854":{},"931":{}},"tags":{}}],["os.readfile(\"/contrast/tl",{"_index":1117,"title":{},"content":{"892":{}},"tags":{}}],["otherwis",{"_index":948,"title":{},"content":{"871":{},"884":{}},"tags":{}}],["out",{"_index":390,"title":{"916":{}},"content":{"832":{},"846":{},"856":{},"857":{},"859":{},"881":{},"884":{},"910":{},"916":{},"932":{}},"tags":{}}],["outdat",{"_index":1322,"title":{},"content":{"928":{}},"tags":{}}],["outlin",{"_index":499,"title":{},"content":{"840":{},"852":{},"889":{}},"tags":{}}],["output",{"_index":1223,"title":{},"content":{"903":{},"929":{},"937":{},"938":{},"941":{}},"tags":{}}],["outsid",{"_index":495,"title":{},"content":{"840":{},"842":{},"869":{},"884":{}},"tags":{}}],["over",{"_index":623,"title":{},"content":{"849":{},"857":{},"884":{},"885":{},"908":{},"910":{}},"tags":{}}],["overview",{"_index":681,"title":{"852":{}},"content":{"861":{}},"tags":{}}],["overwritten",{"_index":966,"title":{},"content":{"874":{},"896":{},"897":{},"899":{},"907":{},"910":{},"915":{}},"tags":{}}],["own",{"_index":750,"title":{},"content":{"855":{}},"tags":{}}],["owner",{"_index":95,"title":{"818":{}},"content":{"814":{},"818":{},"831":{},"832":{},"836":{},"838":{},"839":{},"853":{},"855":{},"859":{},"860":{},"897":{}},"tags":{}}],["owner'",{"_index":911,"title":{},"content":{"864":{},"868":{}},"tags":{}}],["ownership",{"_index":687,"title":{},"content":{"852":{}},"tags":{}}],["owners—to",{"_index":306,"title":{},"content":{"825":{}},"tags":{}}],["p",{"_index":1164,"title":{},"content":{"898":{}},"tags":{}}],["packag",{"_index":1321,"title":{},"content":{"928":{}},"tags":{}}],["packet",{"_index":1016,"title":{},"content":{"884":{}},"tags":{}}],["page",{"_index":248,"title":{},"content":{"820":{},"840":{},"861":{}},"tags":{}}],["pair",{"_index":409,"title":{},"content":{"833":{}},"tags":{}}],["paramet",{"_index":931,"title":{},"content":{"869":{},"870":{}},"tags":{}}],["pars",{"_index":838,"title":{},"content":{"859":{}},"tags":{}}],["part",{"_index":172,"title":{},"content":{"816":{},"820":{},"824":{},"832":{},"854":{},"864":{},"868":{},"869":{},"875":{},"879":{},"882":{},"885":{},"903":{},"908":{},"915":{},"937":{}},"tags":{}}],["parti",{"_index":73,"title":{"818":{},"827":{}},"content":{"814":{},"818":{},"827":{},"829":{},"831":{},"851":{},"855":{},"857":{},"860":{},"863":{},"884":{},"944":{}},"tags":{}}],["particip",{"_index":925,"title":{},"content":{"868":{}},"tags":{}}],["particular",{"_index":1278,"title":{},"content":{"920":{}},"tags":{}}],["particularli",{"_index":552,"title":{},"content":{"845":{},"852":{},"872":{}},"tags":{}}],["parties—such",{"_index":305,"title":{},"content":{"825":{}},"tags":{}}],["partit",{"_index":825,"title":{},"content":{"859":{},"880":{}},"tags":{}}],["pass",{"_index":169,"title":{},"content":{"816":{},"837":{},"897":{},"899":{}},"tags":{}}],["passiv",{"_index":834,"title":{},"content":{"859":{}},"tags":{}}],["patch",{"_index":1162,"title":{},"content":{"898":{},"915":{},"924":{}},"tags":{}}],["path",{"_index":487,"title":{},"content":{"839":{},"933":{}},"tags":{}}],["patient",{"_index":879,"title":{},"content":{"860":{}},"tags":{}}],["peer",{"_index":506,"title":{},"content":{"842":{},"892":{}},"tags":{}}],["pend",{"_index":1263,"title":{},"content":{"918":{}},"tags":{}}],["per",{"_index":539,"title":{},"content":{"845":{},"882":{},"893":{}},"tags":{}}],["perform",{"_index":451,"title":{},"content":{"835":{},"858":{},"859":{},"876":{},"881":{},"887":{},"904":{}},"tags":{}}],["period",{"_index":787,"title":{},"content":{"857":{}},"tags":{}}],["perman",{"_index":784,"title":{},"content":{"857":{}},"tags":{}}],["permiss",{"_index":751,"title":{},"content":{"855":{},"869":{},"870":{}},"tags":{}}],["permit",{"_index":915,"title":{},"content":{"865":{},"873":{}},"tags":{}}],["persist",{"_index":472,"title":{"837":{}},"content":{"837":{},"838":{},"839":{},"843":{},"845":{},"859":{},"919":{},"920":{}},"tags":{}}],["person",{"_index":684,"title":{},"content":{"852":{}},"tags":{}}],["persona",{"_index":745,"title":{"855":{}},"content":{"860":{}},"tags":{}}],["perspect",{"_index":532,"title":{},"content":{"845":{},"851":{},"900":{}},"tags":{}}],["phase",{"_index":712,"title":{},"content":{"853":{},"894":{},"899":{}},"tags":{}}],["physic",{"_index":704,"title":{},"content":{"853":{},"854":{},"857":{},"858":{},"859":{}},"tags":{}}],["piec",{"_index":237,"title":{},"content":{"820":{}},"tags":{}}],["pii",{"_index":685,"title":{},"content":{"852":{}},"tags":{}}],["pin",{"_index":547,"title":{"940":{}},"content":{"845":{},"940":{}},"tags":{}}],["pipe",{"_index":583,"title":{},"content":{"846":{}},"tags":{}}],["pki",{"_index":355,"title":{},"content":{"830":{},"842":{},"851":{},"882":{}},"tags":{}}],["place",{"_index":1296,"title":{},"content":{"924":{}},"tags":{}}],["placehold",{"_index":1091,"title":{},"content":{"891":{}},"tags":{}}],["plain",{"_index":480,"title":{},"content":{"837":{},"892":{}},"tags":{}}],["plan",{"_index":1261,"title":{"917":{}},"content":{"917":{},"918":{},"919":{},"922":{}},"tags":{}}],["plane",{"_index":730,"title":{},"content":{"854":{},"858":{},"859":{}},"tags":{}}],["platform",{"_index":240,"title":{"874":{}},"content":{"820":{},"851":{},"853":{},"857":{},"874":{},"893":{},"906":{},"918":{},"921":{}},"tags":{}}],["platform'",{"_index":865,"title":{},"content":{"860":{}},"tags":{}}],["play",{"_index":297,"title":{},"content":{"825":{}},"tags":{}}],["pleas",{"_index":1143,"title":{},"content":{"893":{}},"tags":{}}],["plugin",{"_index":920,"title":{},"content":{"867":{},"877":{},"881":{}},"tags":{}}],["pod",{"_index":115,"title":{"816":{},"880":{},"938":{}},"content":{"816":{},"817":{},"821":{},"824":{},"832":{},"834":{},"845":{},"847":{},"848":{},"849":{},"851":{},"853":{},"854":{},"863":{},"864":{},"868":{},"870":{},"871":{},"872":{},"873":{},"875":{},"878":{},"879":{},"880":{},"881":{},"885":{},"891":{},"895":{},"899":{},"906":{},"920":{},"922":{},"937":{},"938":{},"940":{},"941":{},"942":{}},"tags":{}}],["pod'",{"_index":193,"title":{},"content":{"816":{},"829":{}},"tags":{}}],["pod/#::###fals",{"_index":1083,"title":{},"content":{"754":{}},"tags":{}}],["name>##tru",{"_index":1089,"title":{},"content":{"754":{}},"tags":{}}],["namespac",{"_index":1381,"title":{},"content":{"799":{},"808":{},"811":{}},"tags":{}}],["nativ",{"_index":694,"title":{},"content":{"716":{},"721":{}},"tags":{}}],["necessari",{"_index":599,"title":{},"content":{"709":{},"732":{},"759":{},"763":{},"788":{}},"tags":{}}],["need",{"_index":448,"title":{},"content":{"701":{},"706":{},"707":{},"709":{},"710":{},"715":{},"729":{},"730":{},"733":{},"739":{},"744":{},"745":{},"746":{},"757":{},"759":{},"765":{},"774":{},"779":{},"780":{},"781":{},"792":{},"799":{}},"tags":{}}],["nest",{"_index":736,"title":{},"content":{"719":{},"720":{}},"tags":{}}],["net_admin",{"_index":1104,"title":{},"content":{"754":{}},"tags":{}}],["network",{"_index":635,"title":{},"content":{"712":{},"719":{},"725":{},"727":{},"728":{},"729":{},"752":{}},"tags":{}}],["new",{"_index":430,"title":{},"content":{"699":{},"701":{},"703":{},"727":{},"729":{},"733":{},"751":{},"769":{},"785":{},"786":{},"800":{},"802":{}},"tags":{}}],["newer",{"_index":1340,"title":{},"content":{"794":{},"798":{}},"tags":{}}],["newli",{"_index":1259,"title":{},"content":{"769":{}},"tags":{}}],["newmeshcert",{"_index":500,"title":{},"content":{"703":{}},"tags":{}}],["next",{"_index":107,"title":{"680":{}},"content":{"765":{},"781":{},"785":{},"811":{}},"tags":{}}],["node",{"_index":733,"title":{"746":{},"751":{}},"content":{"719":{},"720":{},"725":{},"737":{},"743":{},"746":{},"748":{},"751":{},"757":{},"774":{},"792":{},"801":{},"802":{}},"tags":{}}],["node.k8s.io/v1",{"_index":1041,"title":{},"content":{"745":{}},"tags":{}}],["nodepool1",{"_index":1415,"title":{},"content":{"801":{}},"tags":{}}],["non",{"_index":907,"title":{},"content":{"729":{},"754":{},"794":{}},"tags":{}}],["none",{"_index":1419,"title":{},"content":{"801":{}},"tags":{}}],["northeurop",{"_index":1395,"title":{},"content":{"800":{}},"tags":{}}],["notabl",{"_index":333,"title":{},"content":{"689":{}},"tags":{}}],["note",{"_index":610,"title":{},"content":{"709":{},"724":{},"754":{},"763":{},"776":{},"795":{},"798":{}},"tags":{}}],["now",{"_index":692,"title":{},"content":{"716":{},"769":{},"778":{},"801":{}},"tags":{}}],["number",{"_index":489,"title":{},"content":{"703":{},"794":{}},"tags":{}}],["numer",{"_index":467,"title":{},"content":{"702":{}},"tags":{}}],["nydu",{"_index":1056,"title":{},"content":{"749":{}},"tags":{}}],["o=jsonpath='{.spec.runtimeclassnam",{"_index":1477,"title":{},"content":{"811":{}},"tags":{}}],["o=jsonpath='{.status.loadbalancer.ingress[0].ip",{"_index":1210,"title":{},"content":{"765":{},"768":{},"777":{},"782":{}},"tags":{}}],["object",{"_index":719,"title":{},"content":{"718":{},"752":{},"753":{},"808":{}},"tags":{}}],["observ",{"_index":459,"title":{"702":{}},"content":{"742":{},"763":{},"776":{}},"tags":{}}],["obtain",{"_index":208,"title":{},"content":{"683":{},"687":{},"700":{},"811":{}},"tags":{}}],["occur",{"_index":135,"title":{},"content":{"681":{}},"tags":{}}],["oci",{"_index":725,"title":{},"content":{"718":{},"719":{},"740":{}},"tags":{}}],["offer",{"_index":100,"title":{},"content":{"679":{},"720":{},"721":{},"730":{},"733":{}},"tags":{}}],["offlin",{"_index":304,"title":{},"content":{"686":{}},"tags":{}}],["older",{"_index":1310,"title":{},"content":{"785":{},"786":{}},"tags":{}}],["omit",{"_index":1028,"title":{},"content":{"742":{},"762":{},"790":{}},"tags":{}}],["on",{"_index":276,"title":{},"content":{"685":{},"718":{},"730":{},"755":{},"792":{},"800":{},"807":{},"810":{},"811":{}},"tags":{}}],["onc",{"_index":1128,"title":{},"content":{"757":{},"774":{}},"tags":{}}],["opa",{"_index":744,"title":{},"content":{"719":{},"735":{}},"tags":{}}],["open",{"_index":139,"title":{},"content":{"681":{},"709":{},"719":{},"735":{}},"tags":{}}],["openssl",{"_index":1241,"title":{},"content":{"768":{},"782":{}},"tags":{}}],["oper",{"_index":78,"title":{},"content":{"678":{},"686":{},"692":{},"694":{},"704":{},"721":{},"722":{},"723":{},"725":{},"727":{},"728":{},"730":{},"732":{},"769":{},"799":{}},"tags":{}}],["optim",{"_index":750,"title":{},"content":{"721":{}},"tags":{}}],["option",{"_index":732,"title":{"783":{}},"content":{"719":{}},"tags":{}}],["orchestr",{"_index":770,"title":{},"content":{"721":{},"735":{}},"tags":{}}],["order",{"_index":537,"title":{},"content":{"706":{},"742":{},"763":{},"790":{}},"tags":{}}],["origin",{"_index":582,"title":{},"content":{"709":{},"719":{},"752":{},"761":{}},"tags":{}}],["os",{"_index":129,"title":{},"content":{"681":{},"724":{},"801":{}},"tags":{}}],["os.readfile(\"/contrast/tl",{"_index":1176,"title":{},"content":{"762":{}},"tags":{}}],["otherwis",{"_index":1020,"title":{},"content":{"741":{},"754":{}},"tags":{}}],["out",{"_index":453,"title":{"786":{}},"content":{"701":{},"716":{},"726":{},"727":{},"729":{},"751":{},"754":{},"780":{},"786":{},"802":{}},"tags":{}}],["outdat",{"_index":1376,"title":{},"content":{"798":{}},"tags":{}}],["outlin",{"_index":559,"title":{},"content":{"709":{},"710":{},"722":{},"759":{}},"tags":{}}],["output",{"_index":1279,"title":{},"content":{"773":{},"799":{},"807":{},"808":{},"811":{}},"tags":{}}],["outsid",{"_index":620,"title":{},"content":{"710":{},"712":{},"739":{},"754":{}},"tags":{}}],["over",{"_index":737,"title":{},"content":{"719":{},"727":{},"754":{},"755":{},"778":{},"780":{}},"tags":{}}],["overview",{"_index":780,"title":{"722":{}},"content":{"731":{}},"tags":{}}],["overwritten",{"_index":1037,"title":{},"content":{"744":{},"766":{},"767":{},"769":{},"777":{},"780":{},"785":{}},"tags":{}}],["own",{"_index":835,"title":{},"content":{"725":{}},"tags":{}}],["owner",{"_index":197,"title":{"687":{}},"content":{"683":{},"687":{},"700":{},"701":{},"705":{},"707":{},"708":{},"723":{},"725":{},"729":{},"730":{},"767":{}},"tags":{}}],["owner'",{"_index":983,"title":{},"content":{"734":{},"738":{}},"tags":{}}],["ownership",{"_index":786,"title":{},"content":{"722":{}},"tags":{}}],["owners—to",{"_index":380,"title":{},"content":{"694":{}},"tags":{}}],["p",{"_index":1221,"title":{},"content":{"768":{}},"tags":{}}],["packag",{"_index":1375,"title":{},"content":{"798":{}},"tags":{}}],["packet",{"_index":1081,"title":{},"content":{"754":{}},"tags":{}}],["page",{"_index":330,"title":{},"content":{"689":{},"710":{},"731":{}},"tags":{}}],["pair",{"_index":472,"title":{},"content":{"702":{}},"tags":{}}],["paramet",{"_index":1003,"title":{},"content":{"739":{},"740":{}},"tags":{}}],["pars",{"_index":918,"title":{},"content":{"729":{}},"tags":{}}],["part",{"_index":260,"title":{},"content":{"685":{},"689":{},"693":{},"701":{},"724":{},"734":{},"738":{},"739":{},"745":{},"749":{},"752":{},"755":{},"773":{},"778":{},"785":{},"807":{}},"tags":{}}],["parti",{"_index":105,"title":{"687":{},"696":{}},"content":{"679":{},"683":{},"687":{},"696":{},"698":{},"700":{},"721":{},"725":{},"727":{},"730":{},"733":{},"754":{}},"tags":{}}],["particip",{"_index":997,"title":{},"content":{"738":{}},"tags":{}}],["particular",{"_index":1332,"title":{},"content":{"790":{}},"tags":{}}],["particularli",{"_index":673,"title":{},"content":{"715":{},"722":{},"742":{}},"tags":{}}],["parties—such",{"_index":379,"title":{},"content":{"694":{}},"tags":{}}],["partit",{"_index":905,"title":{},"content":{"729":{},"750":{}},"tags":{}}],["pass",{"_index":257,"title":{},"content":{"685":{},"706":{},"767":{},"769":{}},"tags":{}}],["passiv",{"_index":914,"title":{},"content":{"729":{}},"tags":{}}],["patch",{"_index":1219,"title":{},"content":{"768":{},"785":{},"794":{}},"tags":{}}],["path",{"_index":548,"title":{},"content":{"708":{},"803":{}},"tags":{}}],["path/to/original/app",{"_index":593,"title":{},"content":{"709":{}},"tags":{}}],["patient",{"_index":954,"title":{},"content":{"730":{}},"tags":{}}],["peer",{"_index":629,"title":{},"content":{"712":{},"762":{}},"tags":{}}],["pend",{"_index":1319,"title":{},"content":{"788":{}},"tags":{}}],["per",{"_index":660,"title":{},"content":{"715":{},"752":{},"763":{}},"tags":{}}],["perform",{"_index":512,"title":{},"content":{"704":{},"728":{},"729":{},"746":{},"751":{},"757":{},"774":{}},"tags":{}}],["period",{"_index":869,"title":{},"content":{"727":{}},"tags":{}}],["perman",{"_index":866,"title":{},"content":{"727":{}},"tags":{}}],["permiss",{"_index":836,"title":{},"content":{"725":{},"739":{},"740":{}},"tags":{}}],["permit",{"_index":987,"title":{},"content":{"735":{},"743":{}},"tags":{}}],["persist",{"_index":531,"title":{"706":{},"709":{}},"content":{"706":{},"707":{},"708":{},"709":{},"713":{},"715":{},"729":{},"789":{}},"tags":{}}],["persistentvolumeclaim",{"_index":604,"title":{},"content":{"709":{}},"tags":{}}],["person",{"_index":783,"title":{},"content":{"722":{}},"tags":{}}],["persona",{"_index":832,"title":{"725":{}},"content":{"730":{}},"tags":{}}],["perspect",{"_index":653,"title":{},"content":{"715":{},"721":{},"770":{}},"tags":{}}],["phase",{"_index":807,"title":{},"content":{"723":{},"764":{},"769":{}},"tags":{}}],["physic",{"_index":801,"title":{},"content":{"723":{},"724":{},"727":{},"728":{},"729":{}},"tags":{}}],["piec",{"_index":319,"title":{},"content":{"689":{}},"tags":{}}],["pii",{"_index":784,"title":{},"content":{"722":{}},"tags":{}}],["pin",{"_index":668,"title":{"810":{}},"content":{"715":{},"810":{}},"tags":{}}],["pipe",{"_index":701,"title":{},"content":{"716":{}},"tags":{}}],["pki",{"_index":420,"title":{},"content":{"699":{},"712":{},"721":{},"752":{}},"tags":{}}],["place",{"_index":1350,"title":{},"content":{"794":{}},"tags":{}}],["placehold",{"_index":1150,"title":{},"content":{"761":{}},"tags":{}}],["plain",{"_index":539,"title":{},"content":{"706":{},"762":{}},"tags":{}}],["plan",{"_index":1317,"title":{"787":{}},"content":{"787":{},"788":{},"789":{},"792":{}},"tags":{}}],["plane",{"_index":819,"title":{},"content":{"724":{},"728":{},"729":{}},"tags":{}}],["platform",{"_index":322,"title":{"744":{}},"content":{"689":{},"721":{},"723":{},"727":{},"744":{},"763":{},"776":{},"788":{},"791":{}},"tags":{}}],["platform'",{"_index":943,"title":{},"content":{"730":{}},"tags":{}}],["play",{"_index":373,"title":{},"content":{"694":{}},"tags":{}}],["pleas",{"_index":1202,"title":{},"content":{"763":{}},"tags":{}}],["plugin",{"_index":992,"title":{},"content":{"737":{},"747":{},"751":{}},"tags":{}}],["pod",{"_index":12,"title":{"685":{},"750":{},"808":{}},"content":{"677":{},"685":{},"686":{},"690":{},"693":{},"701":{},"703":{},"715":{},"717":{},"718":{},"719":{},"721":{},"723":{},"724":{},"733":{},"734":{},"738":{},"740":{},"741":{},"742":{},"743":{},"745":{},"748":{},"749":{},"750":{},"751":{},"755":{},"761":{},"765":{},"769":{},"776":{},"790":{},"792":{},"807":{},"808":{},"810":{},"811":{}},"tags":{}}],["pod'",{"_index":279,"title":{},"content":{"685":{},"698":{}},"tags":{}}],["pod/#https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architectureweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/attestation/coordinatorweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/attestation/hardwareweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/attestation/manifestweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/attestation/pod-vmweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/attestation/runtime-policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/certificates-and-identities/pkiweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/components/cliweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/components/coordinatorweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/components/init-containerweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/protocols-and-keysweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/architecture/network-encryption/sidecarweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/category/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/category/certificates-and-identitiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/category/componentsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/category/network-encryptionweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/examplesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/getting-startedweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/getting-started/first-stepsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.5/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/aboutweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/architectureweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/componentsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/examplesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/getting-startedweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.6/known-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/aboutweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/architectureweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/componentsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/examplesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/getting-startedweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.7/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/architecture/secretsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/components/overviewweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.8/troubleshootingweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/architecture/secretsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/components/overviewweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/0.9/troubleshootingweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0weekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/architecture/secretsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/components/overviewweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/1.0/troubleshootingweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/nextweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/architecture/secretsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/architecture/security-considerationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/components/overviewweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/getting-started/bare-metalweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/next/troubleshootingweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/about/telemetryweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/architecture/attestationweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/architecture/certificatesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/architecture/observabilityweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/architecture/secretsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/architecture/security-considerationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/basics/confidential-containersweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/basics/featuresweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/basics/security-benefitsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/components/overviewweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/components/policiesweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/components/runtimeweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/components/service-meshweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/deploymentweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/examples/emojivotoweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/features-limitationsweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/getting-started/bare-metalweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/getting-started/cluster-setupweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/getting-started/installweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/troubleshootingweekly0.5https://docs.edgeless.systems/contrast/pr-preview/pr-976/weekly0.5 \ No newline at end of file diff --git a/pr-preview/pr-976/troubleshooting.html b/pr-preview/pr-976/troubleshooting.html new file mode 100644 index 0000000000..f249a604fa --- /dev/null +++ b/pr-preview/pr-976/troubleshooting.html @@ -0,0 +1,100 @@ + + + + + +Troubleshooting | Contrast + + + + + + + + + + + + + +
Version: 1.1

Troubleshooting

+

This section contains information on how to debug your Contrast deployment.

+

Logging

+

Collecting logs can be a good first step to identify problems in your +deployment. Both the CLI and the Contrast Coordinator as well as the Initializer +can be configured to emit additional logs.

+

CLI

+

The CLI logs can be configured with the --log-level command-line flag, which +can be set to either debug, info, warn or error. The default is info. +Setting this to debug can get more fine-grained information as to where the +problem lies.

+

Coordinator and Initializer

+

The logs from the Coordinator and the Initializer can be configured via the +environment variables CONTRAST_LOG_LEVEL, CONTRAST_LOG_FORMAT and +CONTRAST_LOG_SUBSYSTEMS.

+
    +
  • CONTRAST_LOG_LEVEL can be set to one of either debug, info, warn, or +error, similar to the CLI (defaults to info).
  • +
  • CONTRAST_LOG_FORMAT can be set to text or json, determining the output +format (defaults to text).
  • +
  • CONTRAST_LOG_SUBSYSTEMS is a comma-seperated list of subsystems that should +be enabled for logging, which are disabled by default. Subsystems include: +kds-getter, issuer and validator. +To enable all subsystems, use * as the value for this environment variable. +Warnings and error messages from subsystems get printed regardless of whether +the subsystem is listed in the CONTRAST_LOG_SUBSYSTEMS environment variable.
  • +
+

To configure debug logging with all subsystems for your Coordinator, add the +following variables to your container definition.

+
spec: # v1.PodSpec
containers:
image: "ghcr.io/edgelesssys/contrast/coordinator:v1.1.0@sha256:9147d7a83021cd11848c6bf28bb8a58652e28ac43be946bfe3996a2d020dbc57"
name: coordinator
env:
- name: CONTRAST_LOG_LEVEL
value: debug
- name: CONTRAST_LOG_SUBSYSTEMS
value: "*"
# ...
+
info

While the Contrast Coordinator has a policy that allows certain configurations, +the Initializer and service mesh don't. When changing environment variables of other +parts than the Coordinator, ensure to rerun contrast generate to update the policy.

+

To access the logs generated by the Coordinator, you can use kubectl with the +following command:

+
kubectl logs <coordinator-pod-name>
+

Pod fails to start

+

If the Coordinator or a workload pod fails to even start, it can be helpful to +look at the events of the pod during the startup process using the describe +command.

+
kubectl -n <namespace> events --for pod/<coordinator-pod-name>
+

Example output:

+
LAST SEEN  TYPE     REASON  OBJECT             MESSAGE
32m Warning Failed Pod/coordinator-0 kubelet Error: failed to create containerd task: failed to create shim task: "CreateContainerRequest is blocked by policy: ...
+

A common error, as in this example, is that the container creation was blocked by the +policy. Potential reasons are a modification of the deployment YAML without updating +the policies afterward, or a version mismatch between Contrast components.

+

Regenerating the policies

+

To ensure there isn't a mismatch between Kubernetes resource YAML and the annotated +policies, rerun

+
contrast generate
+

on your deployment. If any of the policy annotations change, re-deploy with the updated policies.

+

Pin container images

+

When generating the policies, Contrast will download the images specified in your deployment +YAML and include their cryptographic identity. If the image tag is moved to another +container image after the policy has been generated, the image downloaded at deploy time +will differ from the one at generation time, and the policy enforcement won't allow the +container to be started in the pod VM.

+

To ensure the correct image is always used, pin the container image to a fixed sha256:

+
image: ubuntu:22.04@sha256:19478ce7fc2ffbce89df29fea5725a8d12e57de52eb9ea570890dc5852aac1ac
+

This way, the same image will still be pulled when the container tag (22.04) is moved +to another image.

+

Validate Contrast components match

+

A version mismatch between Contrast components can cause policy validation or attestation +to fail. Each Contrast runtime is identifiable based on its (shortened) measurement value +used to name the runtime class version.

+

First, analyze which runtime class is currently installed in your cluster by running

+
kubectl get runtimeclasses
+

This should give you output similar to the following one.

+
NAME                                           HANDLER                                        AGE
contrast-cc-aks-clh-snp-7173acb5 contrast-cc-aks-clh-snp-7173acb5 23h
kata-cc-isolation kata-cc 45d
+

The output shows that there are four Contrast runtime classes installed (as well as the runtime class provided +by the AKS CoCo preview, which isn't used by Contrast).

+

Next, check if the pod that won't start has the correct runtime class configured, and the +Coordinator uses the exact same runtime:

+
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<pod-name>
kubectl -n <namespace> get -o=jsonpath='{.spec.runtimeClassName}' pod/<coordinator-pod-name>
+

The output should list the runtime class the pod is using:

+
contrast-cc-aks-clh-snp-7173acb5
+

Version information about the currently used CLI can be obtained via the version flag:

+
contrast --version
+
contrast version v0.X.0

runtime handler: contrast-cc-aks-clh-snp-7173acb5
launch digest: beee79ca916b9e5dc59602788cbfb097721cde34943e1583a3918f21011a71c47f371f68e883f5e474a6d4053d931a35
genpolicy version: 3.2.0.azl1.genpolicy0
image versions: ghcr.io/edgelesssys/contrast/coordinator@sha256:...
ghcr.io/edgelesssys/contrast/initializer@sha256:...
+ + \ No newline at end of file
Version: 1.1

Contrast

+

Welcome to the documentation of Contrast! Contrast runs confidential container deployments on Kubernetes at scale.

+

Contrast concept

+

Contrast is based on the Kata Containers and +Confidential Containers projects. +Confidential Containers are Kubernetes pods that are executed inside a confidential micro-VM and provide strong hardware-based isolation from the surrounding environment. +This works with unmodified containers in a lift-and-shift approach. +Contrast currently targets the CoCo preview on AKS.

+
tip

See the 📄whitepaper for more information on confidential computing.

+

Goal

+

Contrast is designed to keep all data always encrypted and to prevent access from the infrastructure layer. It removes the infrastructure provider from the trusted computing base (TCB). This includes access from datacenter employees, privileged cloud admins, own cluster administrators, and attackers coming through the infrastructure, for example, malicious co-tenants escalating their privileges.

+

Contrast integrates fluently with the existing Kubernetes workflows. It's compatible with managed Kubernetes, can be installed as a day-2 operation and imposes only minimal changes to your deployment flow.

+

Use Cases

+

Contrast provides unique security features and benefits. The core use cases are:

+
    +
  • Increasing the security of your containers
  • +
  • Moving sensitive workloads from on-prem to the cloud with Confidential Computing
  • +
  • Shielding the code and data even from the own cluster administrators
  • +
  • Increasing the trustworthiness of your SaaS offerings
  • +
  • Simplifying regulatory compliance
  • +
  • Multi-party computation for data collaboration
  • +
+

Next steps

+

You can learn more about the concept of Confidential Containers, features, and security benefits of Contrast in this section. To jump right into the action head to Getting started.

<$- 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 TlrCHZ^@k|m4wP| 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≪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 z

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