From 3314d93a58c9e412bc4eebceee51237393099c9b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Sep 2023 11:09:25 +0000 Subject: [PATCH] deploy: 1e4e91d46cb3dd068cd46a86693585db7e7244e0 --- 404.html | 8 +++--- assets/js/0f4270c8.80bf4242.js | 1 - assets/js/0fbdd4ac.1a1bd137.js | 1 - assets/js/0fbdd4ac.fde097b1.js | 1 + assets/js/1c14429f.a04cefc1.js | 1 + assets/js/1c14429f.c7f842e6.js | 1 - assets/js/1d8a5d15.1b54b05c.js | 1 + ...0e145.cf48e169.js => 2730e145.17a8321b.js} | 2 +- ...62a39.ef6a4298.js => 29b62a39.6fecc08b.js} | 2 +- assets/js/2baa5a9a.4aef429e.js | 1 - assets/js/2baa5a9a.ea74f963.js | 1 + ...eb86f.fbf1555a.js => 40aeb86f.4a80f588.js} | 2 +- ...007b2.d0439b6b.js => 4d7007b2.5d79f29d.js} | 2 +- assets/js/507ab7d0.e46e86fc.js | 1 - ...134d1.49400344.js => 5b6134d1.4d6a6b20.js} | 2 +- ...8f08d.ca451cf1.js => 5d08f08d.3c6e741c.js} | 2 +- assets/js/5ec90731.f6a49b70.js | 1 + ...32138.6c9cea17.js => 6be32138.8137ceb0.js} | 2 +- ...bd6c9.e5b417d2.js => 84cbd6c9.3c01fe76.js} | 2 +- ...2e787.2ff8da0a.js => 8a92e787.b29f91dc.js} | 2 +- ...554cd.a4e6c1b1.js => b2f554cd.a240283d.js} | 2 +- ...f1b7f.ba499ed0.js => b35f1b7f.7bff8be2.js} | 2 +- assets/js/b8466c91.1d301634.js | 1 - assets/js/b8466c91.b9b0588b.js | 1 + ...78a4d.29570cf0.js => d1b78a4d.bc432b6b.js} | 2 +- ...e0e5a.03a46161.js => d8be0e5a.686ccb83.js} | 2 +- ...64676.22d300a2.js => e1f64676.a14f546f.js} | 2 +- assets/js/ed7afecf.dd6bae0f.js | 1 - assets/js/fa69a7f4.1bb6f346.js | 1 + assets/js/fa69a7f4.54f0c913.js | 1 - ...b74dc.8dd7faa7.js => fd2b74dc.5e571f47.js} | 2 +- assets/js/main.4c25d06d.js | 2 -- assets/js/main.78c992c4.js | 2 ++ ...CENSE.txt => main.78c992c4.js.LICENSE.txt} | 0 assets/js/runtime~main.936e938b.js | 1 + assets/js/runtime~main.987eca14.js | 1 - blog/archive/index.html | 10 +++---- blog/atom.xml | 4 +-- .../index.html | 12 ++++----- blog/feed.json | 2 +- blog/index.html | 10 +++---- blog/rss.xml | 4 +-- blog/tags/blog/index.html | 10 +++---- blog/tags/content-routing/index.html | 10 +++---- blog/tags/engineering/index.html | 10 +++---- blog/tags/fleek-network/index.html | 10 +++---- blog/tags/index.html | 8 +++--- docs/Core/developers/index.html | 8 +++--- docs/Core/edge-nodes/index.html | 8 +++--- docs/Core/services/index.html | 8 +++--- docs/Open-source/code-of-conduct/index.html | 8 +++--- docs/Open-source/contributing/index.html | 8 +++--- docs/Open-source/index.html | 8 +++--- docs/Open-source/repositories/index.html | 8 +++--- docs/contribute/index.html | 8 +++--- docs/develop/client/index.html | 8 +++--- docs/develop/json-rpc/index.html | 8 +++--- docs/develop/overview/index.html | 8 +++--- docs/develop/service-development/index.html | 8 +++--- docs/index.html | 8 +++--- .../delivery-acknowledgements/index.html | 8 +++--- docs/learn/developers/index.html | 8 +++--- docs/learn/introduction/index.html | 8 +++--- docs/learn/ports/index.html | 8 +++--- docs/learn/services/index.html | 8 +++--- docs/learn/the-network/index.html | 8 +++--- docs/learn/token-and-economics/index.html | 8 +++--- docs/node/Install/index.html | 8 +++--- docs/node/configuration/index.html | 8 +++--- docs/node/diagnostics/index.html | 8 +++--- docs/node/health-check/index.html | 8 +++--- docs/node/overview/index.html | 8 +++--- docs/node/requirements/index.html | 8 +++--- docs/node/testnet-onboarding/index.html | 8 +++--- docs/roadmap/index.html | 8 +++--- docs/tags/about/index.html | 8 +++--- docs/tags/algorithms/index.html | 8 +++--- docs/tags/architecture/index.html | 8 +++--- docs/tags/awards/index.html | 8 +++--- docs/tags/build/index.html | 8 +++--- docs/tags/cdn/index.html | 8 +++--- docs/tags/client/index.html | 8 +++--- docs/tags/code-of-conduct/index.html | 8 +++--- docs/tags/codebase/index.html | 8 +++--- docs/tags/compile/index.html | 8 +++--- docs/tags/configuration/index.html | 8 +++--- docs/tags/consensus/index.html | 8 +++--- docs/tags/contribute/index.html | 8 +++--- docs/tags/contributing/index.html | 8 +++--- docs/tags/contributor/index.html | 8 +++--- docs/tags/cryptoeconomics/index.html | 8 +++--- docs/tags/decentralization/index.html | 8 +++--- docs/tags/develop/index.html | 8 +++--- docs/tags/development/index.html | 8 +++--- docs/tags/diagnostics/index.html | 8 +++--- docs/tags/economics/index.html | 8 +++--- docs/tags/edge-network/index.html | 8 +++--- docs/tags/edge-platform/index.html | 8 +++--- docs/tags/fleek-network/index.html | 8 +++--- docs/tags/getting-started/index.html | 8 +++--- docs/tags/git/index.html | 8 +++--- docs/tags/guide/index.html | 8 +++--- docs/tags/healthcheck/index.html | 8 +++--- docs/tags/incentives/index.html | 8 +++--- docs/tags/index.html | 8 +++--- docs/tags/learn/index.html | 8 +++--- docs/tags/manual/index.html | 8 +++--- docs/tags/node-status/index.html | 8 +++--- docs/tags/onboarding/index.html | 8 +++--- docs/tags/open-source/index.html | 8 +++--- docs/tags/permissionless/index.html | 8 +++--- docs/tags/phases/index.html | 8 +++--- docs/tags/pledge/index.html | 8 +++--- docs/tags/ports/index.html | 8 +++--- docs/tags/protocol/index.html | 8 +++--- docs/tags/repositories/index.html | 8 +++--- docs/tags/repository/index.html | 8 +++--- docs/tags/reputation/index.html | 8 +++--- docs/tags/requirements/index.html | 8 +++--- docs/tags/rewards/index.html | 8 +++--- docs/tags/roadmap/index.html | 8 +++--- docs/tags/rpc/index.html | 8 +++--- docs/tags/rust-dependencies/index.html | 8 +++--- docs/tags/sdk/index.html | 8 +++--- docs/tags/server/index.html | 8 +++--- docs/tags/services/index.html | 8 +++--- docs/tags/snar-ks/index.html | 8 +++--- docs/tags/snarks/index.html | 8 +++--- docs/tags/standards/index.html | 8 +++--- docs/tags/testnet/index.html | 8 +++--- docs/tags/token/index.html | 8 +++--- docs/tags/tokenomics/index.html | 8 +++--- docs/tags/toolkit/index.html | 8 +++--- docs/tags/verification/index.html | 8 +++--- docs/tags/whitepaper/index.html | 8 +++--- docs/tags/wizard/index.html | 8 +++--- docs/whitepaper/index.html | 8 +++--- .../Node Operators/getting-started/index.html | 12 ++++----- .../index.html | 27 ------------------- .../transfering-setup-ownership/index.html | 27 +++++++++++++++++++ guides/index.html | 10 +++---- guides/tags/configuration/index.html | 10 +++---- guides/tags/edge-computing/index.html | 8 +++--- guides/tags/fleek-network/index.html | 8 +++--- guides/tags/getting-started/index.html | 8 +++--- guides/tags/guide/index.html | 10 +++---- guides/tags/guides/index.html | 8 +++--- guides/tags/help/index.html | 8 +++--- guides/tags/index.html | 10 +++---- guides/tags/migrate/index.html | 27 ------------------- guides/tags/migration/index.html | 27 ------------------- guides/tags/ownership/index.html | 10 +++---- guides/tags/setup/index.html | 10 +++---- guides/tags/transfer/index.html | 27 +++++++++++++++++++ index.html | 8 +++--- .../index.html | 10 +++---- .../file-permissions-and-ownership/index.html | 10 +++---- .../Lightning CLI/keys-not-found/index.html | 10 +++---- .../permission-denied-os-error-13/index.html | 10 +++---- .../uninstall-lightning-cli/index.html | 10 +++---- .../update-cli-from-source-code/index.html | 10 +++---- .../shutting-down-persistance/index.html | 10 +++---- references/Systemd/user-service/index.html | 10 +++---- references/index.html | 10 +++---- references/tags/clean/index.html | 8 +++--- references/tags/clear/index.html | 8 +++--- references/tags/delete/index.html | 8 +++--- references/tags/file-permissions/index.html | 8 +++--- references/tags/fix/index.html | 8 +++--- references/tags/frozen/index.html | 8 +++--- references/tags/help/index.html | 8 +++--- references/tags/idle/index.html | 8 +++--- references/tags/index.html | 8 +++--- references/tags/keystore/index.html | 8 +++--- references/tags/lost-keys/index.html | 8 +++--- references/tags/ownership/index.html | 8 +++--- references/tags/permissions/index.html | 8 +++--- references/tags/reference/index.html | 8 +++--- references/tags/references/index.html | 8 +++--- references/tags/remove/index.html | 8 +++--- references/tags/root/index.html | 8 +++--- references/tags/service-error/index.html | 8 +++--- references/tags/shutdown/index.html | 8 +++--- references/tags/sudoer/index.html | 8 +++--- references/tags/systemctl/index.html | 8 +++--- references/tags/systemd/index.html | 8 +++--- references/tags/uninstall/index.html | 8 +++--- references/tags/unit/index.html | 8 +++--- references/tags/update/index.html | 8 +++--- references/tags/upgrade/index.html | 8 +++--- references/tags/user-service/index.html | 8 +++--- search/index.html | 8 +++--- sitemap.xml | 2 +- 193 files changed, 706 insertions(+), 734 deletions(-) delete mode 100644 assets/js/0f4270c8.80bf4242.js delete mode 100644 assets/js/0fbdd4ac.1a1bd137.js create mode 100644 assets/js/0fbdd4ac.fde097b1.js create mode 100644 assets/js/1c14429f.a04cefc1.js delete mode 100644 assets/js/1c14429f.c7f842e6.js create mode 100644 assets/js/1d8a5d15.1b54b05c.js rename assets/js/{2730e145.cf48e169.js => 2730e145.17a8321b.js} (99%) rename assets/js/{29b62a39.ef6a4298.js => 29b62a39.6fecc08b.js} (98%) delete mode 100644 assets/js/2baa5a9a.4aef429e.js create mode 100644 assets/js/2baa5a9a.ea74f963.js rename assets/js/{40aeb86f.fbf1555a.js => 40aeb86f.4a80f588.js} (99%) rename assets/js/{4d7007b2.d0439b6b.js => 4d7007b2.5d79f29d.js} (98%) delete mode 100644 assets/js/507ab7d0.e46e86fc.js rename assets/js/{5b6134d1.49400344.js => 5b6134d1.4d6a6b20.js} (99%) rename assets/js/{5d08f08d.ca451cf1.js => 5d08f08d.3c6e741c.js} (64%) create mode 100644 assets/js/5ec90731.f6a49b70.js rename assets/js/{6be32138.6c9cea17.js => 6be32138.8137ceb0.js} (99%) rename assets/js/{84cbd6c9.e5b417d2.js => 84cbd6c9.3c01fe76.js} (58%) rename assets/js/{8a92e787.2ff8da0a.js => 8a92e787.b29f91dc.js} (98%) rename assets/js/{b2f554cd.a4e6c1b1.js => b2f554cd.a240283d.js} (99%) rename assets/js/{b35f1b7f.ba499ed0.js => b35f1b7f.7bff8be2.js} (98%) delete mode 100644 assets/js/b8466c91.1d301634.js create mode 100644 assets/js/b8466c91.b9b0588b.js rename assets/js/{d1b78a4d.29570cf0.js => d1b78a4d.bc432b6b.js} (98%) rename assets/js/{d8be0e5a.03a46161.js => d8be0e5a.686ccb83.js} (98%) rename assets/js/{e1f64676.22d300a2.js => e1f64676.a14f546f.js} (98%) delete mode 100644 assets/js/ed7afecf.dd6bae0f.js create mode 100644 assets/js/fa69a7f4.1bb6f346.js delete mode 100644 assets/js/fa69a7f4.54f0c913.js rename assets/js/{fd2b74dc.8dd7faa7.js => fd2b74dc.5e571f47.js} (97%) delete mode 100644 assets/js/main.4c25d06d.js create mode 100644 assets/js/main.78c992c4.js rename assets/js/{main.4c25d06d.js.LICENSE.txt => main.78c992c4.js.LICENSE.txt} (100%) create mode 100644 assets/js/runtime~main.936e938b.js delete mode 100644 assets/js/runtime~main.987eca14.js delete mode 100644 guides/Node Operators/migrate-ownership-of-node-setup-to-user/index.html create mode 100644 guides/Node Operators/transfering-setup-ownership/index.html delete mode 100644 guides/tags/migrate/index.html delete mode 100644 guides/tags/migration/index.html create mode 100644 guides/tags/transfer/index.html diff --git a/404.html b/404.html index af0043c4b..d29181b0e 100644 --- a/404.html +++ b/404.html @@ -13,15 +13,15 @@ - - + +
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/assets/js/0f4270c8.80bf4242.js b/assets/js/0f4270c8.80bf4242.js deleted file mode 100644 index eeed27a39..000000000 --- a/assets/js/0f4270c8.80bf4242.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3238],{3905:(e,t,n)=>{n.d(t,{Zo:()=>h,kt:()=>g});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},h=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,g=d["".concat(l,".").concat(m)]||d[m]||u[m]||a;return n?o.createElement(g,i(i({ref:t},h),{},{components:n})):o.createElement(g,i({ref:t},h))}));function g(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>c,frontMatter:()=>l,metadata:()=>h,toc:()=>u});var o=n(7462),r=(n(7294),n(3905)),a=n(3872),i=(n(2915),n(6733)),s=n(3242);const l={template:"post",draft:!1,hide_title:!0,title:"Migrate ownership of node setup to user",slug:"migrate-ownership-of-node-setup-to-user",date:new Date("2023-09-12T23:00:00.000Z"),description:"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup",category:"Tutorial",tags:["migration","migrate","ownership","guide","setup","configuration"]},p=void 0,h={unversionedId:"Node Operators/migrate-ownership-to-user",id:"Node Operators/migrate-ownership-to-user",title:"Migrate ownership of node setup to user",description:"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup",source:"@site/guides/Node Operators/migrate-ownership-to-user.md",sourceDirName:"Node Operators",slug:"/Node Operators/migrate-ownership-of-node-setup-to-user",permalink:"/guides/Node Operators/migrate-ownership-of-node-setup-to-user",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/Node Operators/migrate-ownership-to-user.md",tags:[{label:"migration",permalink:"/guides/tags/migration"},{label:"migrate",permalink:"/guides/tags/migrate"},{label:"ownership",permalink:"/guides/tags/ownership"},{label:"guide",permalink:"/guides/tags/guide"},{label:"setup",permalink:"/guides/tags/setup"},{label:"configuration",permalink:"/guides/tags/configuration"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{template:"post",draft:!1,hide_title:!0,title:"Migrate ownership of node setup to user",slug:"migrate-ownership-of-node-setup-to-user",date:"2023-09-12T23:00:00.000Z",description:"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup",category:"Tutorial",tags:["migration","migrate","ownership","guide","setup","configuration"]},sidebar:"defaultSidebar",previous:{title:"Getting Started",permalink:"/guides/Node Operators/getting-started"}},d={},u=[{value:"Introduction",id:"introduction",level:2},{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Ownership of Lightning CLI files",id:"ownership-of-lightning-cli-files",level:2},{value:"Systemd Service",id:"systemd-service",level:2},{value:"Stop the service",id:"stop-the-service",level:2},{value:"Clear the .lightning data",id:"clear-the-lightning-data",level:2},{value:"Create a user",id:"create-a-user",level:2},{value:"Move lightning system and source code directory to user's home",id:"move-lightning-system-and-source-code-directory-to-users-home",level:2},{value:"1) Move the /root/.lightning directory from one user to the other",id:"1-move-the-rootlightning-directory-from-one-user-to-the-other",level:3},{value:"2) Move the /root/fleek-network directory from one user to the other",id:"2-move-the-rootfleek-network-directory-from-one-user-to-the-other",level:3},{value:"3) Confirm move by finding both directories",id:"3-confirm-move-by-finding-both-directories",level:3},{value:"Change ownership of files",id:"change-ownership-of-files",level:2},{value:"Update the Systemd service unit",id:"update-the-systemd-service-unit",level:2},{value:"Update the config.toml with user-preferred file locations",id:"update-the-configtoml-with-user-preferred-file-locations",level:2},{value:"Start the service",id:"start-the-service",level:2},{value:"Conclusion",id:"conclusion",level:2}],m={toc:u},g="wrapper";function c(e){let{components:t,...n}=e;return(0,r.kt)(g,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"Our Lightning CLI and Node process is run by a user, that has some sort of permissions\u2013some users run it as a super user (root) which is questionable as root privileges are not a necessary good. We'll look into how to create a user to manage and control the Fleek Network Lightning CLI and Systemd unit service. Also, presents the concept of file permissions and ownership which is crucial in preventing private or sensitive data from being exposed to dodgy actors."),(0,r.kt)("p",null,"Let's discuss the topic and open up a few ideas to help us improve the security of our server."),(0,r.kt)("h2",{id:"pre-requisites"},"Pre-requisites"),(0,r.kt)("p",null,"To follow the guide, you will need the following:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Familiarity with the command-line interface"),(0,r.kt)("li",{parentName:"ul"},"Have installed and set up the Lightning CLI and service")),(0,r.kt)("h2",{id:"ownership-of-lightning-cli-files"},"Ownership of Lightning CLI files"),(0,r.kt)("p",null,"The user who installs the Lightning CLI and sets the Service takes an important role that determines the location of the configuration files, the setup, and how the Systemd service is managed or controlled."),(0,r.kt)("p",null,"Our ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install"},"install")," document recommends creating a user and switching to the user to set up the service. You shouldn't want installed applications to run with elevated privileges. Applications are meant to be run with non-administrative privileges. If an application requires higher privileges, the administrator, such as a ",(0,r.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Sudo"},"sudoer")," should be able to elevate it. An application that has full access and control of a system can modify it in harmful ways, e.g. compromise the private keys."),(0,r.kt)("p",null,"For our guide, we'll illustrate the process of migration from a super user (root) to another user (sudo). The knowledge should be easily appliable for any other user-to-user migration. We stick with root user for simplicity and because that's the most common use case."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"A reference document about ",(0,r.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"File permissions and ownership")," is available that explains how it works practically, by showcasing how the process can be started, how the node process locates the Keystore, etc.")),(0,r.kt)("h2",{id:"systemd-service"},"Systemd Service"),(0,r.kt)("p",null,"In systemd, a unit refers to any resource that the system knows how to operate on and manage. This is the primary object that the systemd tools know how to deal with. These resources are defined using configuration files called unit files."),(0,r.kt)("p",null,"The recommended installation process features a ",(0,r.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.service.html"},"systemd.service")," which is a resource that the system knows how to operate and manage by an administrator user."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"When using a Systemd service to run a process, it operates comparably to running it directly. The key difference is that Systemd keeps track of all the processes and threads that are spawned. This means that when a service is stopped using systemctl, such as the Fleek Network Lightning Node service, all the child processes that were started by the service are also terminated. Additionally, by utilizing Systemd, a user can run the process in the background and configure it to start automatically on system startup.")),(0,r.kt)("p",null,"If you have followed the installation recommendations, find the systemd service unit in the location ",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," (we are using Ubuntu Linux as an example to keep it short)."),(0,r.kt)("p",null,"Make sure that you have set up a ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"Systemd unit service"),", as recommended during the installation as this guide assumes you have one setup."),(0,r.kt)("h2",{id:"stop-the-service"},"Stop the service"),(0,r.kt)("p",null,"Before we proceed with any changes required for the migration, you'll have to stop the ",(0,r.kt)("inlineCode",{parentName:"p"},"lightning.service"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl stop lightning\n")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"For this guide, we are assuming that you are migrating ownership from ",(0,r.kt)("strong",{parentName:"p"},"root")," to a ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," user. If not, you might be required to elevate privileges as ",(0,r.kt)("strong",{parentName:"p"},"sudo**")," where required. For example, ",(0,r.kt)("inlineCode",{parentName:"p"},"sudo systemctl stop lightning"),".")),(0,r.kt)("h2",{id:"clear-the-lightning-data"},"Clear the .lightning data"),(0,r.kt)("p",null,"Run the following command to clear the ",(0,r.kt)("inlineCode",{parentName:"p"},"/root/.lightning/data"),", as it can be quite large and we don't need to move it."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -rf /root/.lightning/data\n")),(0,r.kt)("h2",{id:"create-a-user"},"Create a user"),(0,r.kt)(i.ZP,{mdxType:"CreateAUser"}),(0,r.kt)("h2",{id:"move-lightning-system-and-source-code-directory-to-users-home"},"Move lightning system and source code directory to user's home"),(0,r.kt)("p",null,"A user should've been created, added the user to the sudo group, switched to the user, and changed the directory to the user's home."),(0,r.kt)("p",null,"Run the command ",(0,r.kt)("inlineCode",{parentName:"p"},"pwd"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n")),(0,r.kt)("p",null,"The output would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"/home/\n")),(0,r.kt)("p",null,"Given the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"/home/lgtn\n")),(0,r.kt)("p",null,"You'll then move two directories:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"/root/.lightning")),(0,r.kt)("li",{parentName:"ul"},"The source code under the parent ",(0,r.kt)("inlineCode",{parentName:"li"},"/root/fleek-network"))),(0,r.kt)("h3",{id:"1-move-the-rootlightning-directory-from-one-user-to-the-other"},"1) Move the ",(0,r.kt)("inlineCode",{parentName:"h3"},"/root/.lightning")," directory from one user to the other"),(0,r.kt)("p",null,"For our demo, we have assumed ",(0,r.kt)("strong",{parentName:"p"},"root")," user to ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," user named ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),", thus that'll look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mv /root/.lightning /home/lgtn/\n")),(0,r.kt)("h3",{id:"2-move-the-rootfleek-network-directory-from-one-user-to-the-other"},"2) Move the ",(0,r.kt)("inlineCode",{parentName:"h3"},"/root/fleek-network")," directory from one user to the other"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mv /root/fleek-network /home/lgtn/\n")),(0,r.kt)("h3",{id:"3-confirm-move-by-finding-both-directories"},"3) Confirm move by finding both directories"),(0,r.kt)("p",null,"In the user $HOME directory, you should be able to list the content of the directory and find the ",(0,r.kt)("inlineCode",{parentName:"p"},".lightning")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"fleek-network")," directory."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la\n")),(0,r.kt)("p",null,"The output should be similar to the following."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 13:51 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 root root 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 3 root root 4096 Sep 11 12:28 fleek-network\n")),(0,r.kt)("h2",{id:"change-ownership-of-files"},"Change ownership of files"),(0,r.kt)("p",null,"Once the directories and files are moved, they should have have the wrong ownership, which should be set to ",(0,r.kt)("strong",{parentName:"p"},"root:root"),". We'll now have to change the ownership of the directories and files recursively."),(0,r.kt)("p",null,"Change the ownership of ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning")," to the user ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo chown -R lgtn:lgtn .lightning\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Make sure that you use the ",(0,r.kt)("inlineCode",{parentName:"p"},"-R")," flag to have the ownership changes applied to the parent, the child directories and all the files.")),(0,r.kt)("p",null,"Change the ownership of ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/fleek-network")," to the user ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo chown -R lgtn:lgtn fleek-network\n")),(0,r.kt)("p",null,"Once completed, if you list the content of the directory the ownership should have changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"root:root")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn:lgtn"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la\n")),(0,r.kt)("p",null,"The output should be similar to the following."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 13:51 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 3 lgtn lgtn 4096 Sep 11 12:28 fleek-network\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Remember that we are using ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," for our demo. If you have opted for a different username, make sure you use the correct username. To find the username you are logged in with run the command:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"whoami\n")),(0,r.kt)("p",{parentName:"admonition"},"For our demo, we'll assume that you understand that ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," is the user we opted in for our demo.")),(0,r.kt)("p",null,"##\xa0The lgtn symbolic link (symlink)"),(0,r.kt)("p",null,"We have the symbolic link that links the binary built from the source code, to the alias ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," that's set under the ",(0,r.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn")," pathname."),(0,r.kt)("p",null,"For example, you can find where that is linked to by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la $(which lgtn)\n")),(0,r.kt)("p",null,"On the output below, we can see that the ",(0,r.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn")," points to ",(0,r.kt)("inlineCode",{parentName:"p"},"/root/fleek-network/lightning/target/release/lightning-node"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"lrwxrwxrwx 1 root root 64 Sep 11 15:48 /usr/local/bin/lgtn -> /root/fleek-network/lightning/target/release/lightning-node\n")),(0,r.kt)("p",null,"The target base path is ",(0,r.kt)("inlineCode",{parentName:"p"},"/root")," and we know that we've moved the source code directory to the user home ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn"),". For this reason, we need to create a new symlink with the updated location of the binary file."),(0,r.kt)("p",null,"Unlink the symlink:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo unlink lgtn\n")),(0,r.kt)("p",null,"Create the symlink:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sudo ln -s "/home/lgtn/fleek-network/lightning/target/release/lightning-node" /usr/local/bin/lgtn\n')),(0,r.kt)("p",null,"If successful, you should be able to execute the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn help\n")),(0,r.kt)("p",null,"The output should look similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"Usage: lgtn [OPTIONS] \n\nCommands:\n run Start the node\n keys Handle keys\n print-config Print the loaded configuration\n help Print this message or the help of the given subcommand(s)\n\nOptions:\n -c, --config Path to the toml configuration file [default: ~/.lightning/config.toml]\n --with-mock-consensus Determines that we should be using the mock consensus backend\n -v... Increases the level of verbosity (the max level is -vvv)\n --log-location Print code location on console logs\n -h, --help Print help\n -V, --version Print version\n")),(0,r.kt)("h2",{id:"update-the-systemd-service-unit"},"Update the Systemd service unit"),(0,r.kt)("p",null,"Open the file, its settings should be similar to the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home//.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,r.kt)("p",null,"Since we opted in for the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," for our demo, replaced ",(0,r.kt)("inlineCode",{parentName:"p"},"")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," and it would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Notice the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExecStart=")," which includes the flag ",(0,r.kt)("inlineCode",{parentName:"p"},"-c")," where the location of the user files is declared. Learn how to ",(0,r.kt)("a",{parentName:"p",href:"#update-the-configtoml-with-user-preferred-file-locations"},"update the config.toml")," to include the user-preferred file paths, e.g. declare the keystore pathname.")),(0,r.kt)("p",null,"Complete the step by reloading the daemon, to apply the newly created changes. You can do this by executing:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,r.kt)("h2",{id:"update-the-configtoml-with-user-preferred-file-locations"},"Update the config.toml with user-preferred file locations"),(0,r.kt)("p",null,"Open the ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," file in your favorite text editor."),(0,r.kt)("p",null,"Replace every instance of ",(0,r.kt)("inlineCode",{parentName:"p"},"~")," (tilde) with the user's home path. We do this to ensure that every time we control the service via systemctl, the configuration file that tells which keystore to use is declared upfront regardless of running it as user or delegating to root with ",(0,r.kt)("strong",{parentName:"p"},"sudo"),". Learn more about ",(0,r.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"file permissions and ownership")," by reading the reference document."),(0,r.kt)(s.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,r.kt)("h2",{id:"start-the-service"},"Start the service"),(0,r.kt)("p",null,"At this stage, you should have migrated the essential files to the user home."),(0,r.kt)("p",null,"Ideally, you would now manage the service as the ",(0,r.kt)("inlineCode",{parentName:"p"},"user")," (as described in the ",(0,r.kt)("a",{parentName:"p",href:"/references/Systemd/user-service/"},"user service reference"),"). To keep our guide wider to all users, we'll prefix the commands with ",(0,r.kt)("strong",{parentName:"p"},"sudo"),", which elevates the permissions to ",(0,r.kt)("strong",{parentName:"p"},"root"),". But since we have provided the configuration file the ",(0,r.kt)("inlineCode",{parentName:"p"},"-c")," in our ",(0,r.kt)("a",{parentName:"p",href:"#systemd-service"},"systemd service"),", we'll have the user-preferred configuration options ruling. "),(0,r.kt)("p",null,"Start the service by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl start lightning.service\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Find the timeline of events for the Lightning service by checking the log files. Learn about it in the section ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#analyzing-log-messages"},"Log Messages"),".")),(0,r.kt)("p",null,"To learn more, visit the section ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#use-systemctl-to-manage-systemd-service"},"Use Systemctl to manage the Lightning Service")),(0,r.kt)("h2",{id:"conclusion"},"Conclusion"),(0,r.kt)("p",null,"We started by giving a brief introduction to ownership of the Lightning CLI files."),(0,r.kt)("p",null,"Jumped through topics of Systemd service that helps the user manage the service in the Linux environment, which helps keep keeps track of all the processes and threads that are spawned."),(0,r.kt)("p",null,"We've gone through the step-by-step process to migrate the Fleek Network CLI and Systemd service setup from one user to the other. To keep it short, we decided to go with the use-case of where the migration happens between a ",(0,r.kt)("strong",{parentName:"p"},"root")," user and a ",(0,r.kt)("strong",{parentName:"p"},"sudoer"),"."),(0,r.kt)("p",null,"Discover more about the project by ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"watching/contributing on GitHub"),", following us on ",(0,r.kt)("a",{parentName:"p",href:"https://twitter.com/fleek_net"},"Twitter"),", and joining ",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"our community Discord")," for any updates."),(0,r.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}c.isMDXComponent=!0},6733:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We recommend creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"non-root")," user with administrative privileges. It'll allow us to install any system requirements."),(0,r.kt)("p",null,"You can create a new user and add to the ",(0,r.kt)("strong",{parentName:"p"},"sudo")," group by running:"),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"For our example, we'll be using the name ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," but you can pick whichever you'd like. If you already have a ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," account, you can skip this step.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"adduser lgtn\n")),(0,r.kt)("p",null,"After completing the ",(0,r.kt)("inlineCode",{parentName:"p"},"adduser")," steps, execute the ",(0,r.kt)("inlineCode",{parentName:"p"},"usermod")," to add the ",(0,r.kt)("inlineCode",{parentName:"p"},"user")," to the ",(0,r.kt)("strong",{parentName:"p"},"sudo")," group, as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"usermod -aG sudo lgtn\n")),(0,r.kt)("p",null,"Switch to the new ",(0,r.kt)("strong",{parentName:"p"},"user")," by using the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"su lgtn\n")),(0,r.kt)("p",null,"Change the directory to the new user's home, as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"cd /home/lgtn\n")))}s.isMDXComponent=!0},3242:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In the ",(0,r.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,r.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,r.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,r.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,r.kt)("p",null,"Here's an example of how to do it using ",(0,r.kt)("strong",{parentName:"p"},"sed"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,r.kt)("p",null,"For example, if your username is ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,r.kt)("p",null,"Once modified, you can run a ",(0,r.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,r.kt)("p",null,"For our example where we opted in for the username ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,r.kt)("admonition",{title:"Warning",type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}s.isMDXComponent=!0},2915:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"You have several ways of doing this:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Clone via HTTPS"),(0,r.kt)("li",{parentName:"ul"},"Clone via SSH"),(0,r.kt)("li",{parentName:"ul"},"Download via Github CLI"),(0,r.kt)("li",{parentName:"ul"},"Download the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning/archive/refs/heads/main.zip"},"zip package")," from the repository")),(0,r.kt)("p",{parentName:"admonition"},"We recommend HTTPS because it is the easiest to set up in the wild, and by users who are new to all this.\nAlthough, we strongly recommend using an SSH connection when interacting with GitHub. If you are to this and are interested read more about it ",(0,r.kt)("a",{parentName:"p",href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh"},"here"),"."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git \n")),(0,r.kt)("p",{parentName:"admonition"},"Here's an example of what it'd look like when sticking to the recommended path location:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git ~/fleek-network/lightning\n"))))}s.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>r});var o=n(7294);const r=e=>{let{image:t,name:n,title:r,url:a}=e;return o.createElement("section",{className:"author_card"},o.createElement("div",null,o.createElement("span",{className:"avatar"},o.createElement("a",{href:a,target:"_blank",alt:n},o.createElement("img",{src:t,alt:n}))),o.createElement("div",null,o.createElement("span",{className:"name"},o.createElement("a",{href:a,target:"_blank",alt:n},n)),o.createElement("span",{className:"title"},r),o.createElement("span",{className:"discord"},"Got questions? Find us on ",o.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/0fbdd4ac.1a1bd137.js b/assets/js/0fbdd4ac.1a1bd137.js deleted file mode 100644 index 5431d9bf2..000000000 --- a/assets/js/0fbdd4ac.1a1bd137.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[8934],{8944:e=>{e.exports=JSON.parse('{"label":"ownership","permalink":"/guides/tags/ownership","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file diff --git a/assets/js/0fbdd4ac.fde097b1.js b/assets/js/0fbdd4ac.fde097b1.js new file mode 100644 index 000000000..09145c3e7 --- /dev/null +++ b/assets/js/0fbdd4ac.fde097b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[8934],{8944:e=>{e.exports=JSON.parse('{"label":"ownership","permalink":"/guides/tags/ownership","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/transfering-setup-ownership"}]}')}}]); \ No newline at end of file diff --git a/assets/js/1c14429f.a04cefc1.js b/assets/js/1c14429f.a04cefc1.js new file mode 100644 index 000000000..c99652507 --- /dev/null +++ b/assets/js/1c14429f.a04cefc1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[2702],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var o=n(7294);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 r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),d=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},c=function(e){var t=d(e.components);return o.createElement(s.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,c=l(e,["components","mdxType","originalType","parentName"]),u=d(n),h=a,m=u["".concat(s,".").concat(h)]||u[h]||p[h]||r;return n?o.createElement(m,i(i({ref:t},c),{},{components:n})):o.createElement(m,i({ref:t},c))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[u]="string"==typeof e?e:a,i[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>m,frontMatter:()=>l,metadata:()=>d,toc:()=>u});var o=n(7462),a=(n(7294),n(3905)),r=n(3872),i=n(2915);const l={template:"post",draft:!1,hide_title:!0,title:"Getting Started",slug:"getting-started",date:new Date("2023-08-31T23:00:00.000Z"),canonical:"",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",category:"Tutorial",tags:["Edge computing","Guide","Getting Started"]},s=void 0,d={unversionedId:"Node Operators/getting-started-guide",id:"Node Operators/getting-started-guide",title:"Getting Started",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",source:"@site/guides/Node Operators/getting-started-guide.md",sourceDirName:"Node Operators",slug:"/Node Operators/getting-started",permalink:"/guides/Node Operators/getting-started",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/Node Operators/getting-started-guide.md",tags:[{label:"Edge computing",permalink:"/guides/tags/edge-computing"},{label:"Guide",permalink:"/guides/tags/guide"},{label:"Getting Started",permalink:"/guides/tags/getting-started"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{template:"post",draft:!1,hide_title:!0,title:"Getting Started",slug:"getting-started",date:"2023-08-31T23:00:00.000Z",canonical:"",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",category:"Tutorial",tags:["Edge computing","Guide","Getting Started"]},sidebar:"defaultSidebar",previous:{title:"About guides",permalink:"/guides/"},next:{title:"Transfering setup ownership",permalink:"/guides/Node Operators/transfering-setup-ownership"}},c={},u=[{value:"Introduction",id:"introduction",level:2},{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Need a quick Fleek Network TL;DR?",id:"need-a-quick-fleek-network-tldr",level:2},{value:"Why is Fleek Network needed?",id:"why-is-fleek-network-needed",level:2},{value:"How Does Fleek Network Work?",id:"how-does-fleek-network-work",level:2},{value:"Running a Node",id:"running-a-node",level:2},{value:"Clone the source code",id:"clone-the-source-code",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Build",id:"build",level:3},{value:"Node Launch",id:"node-launch",level:3},{value:"Health check",id:"health-check",level:3},{value:"Next steps",id:"next-steps",level:2},{value:"Conclusion",id:"conclusion",level:2}],p={toc:u},h="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"introduction"},"Introduction"),(0,a.kt)("p",null,"For this guide, we\u2019ll have a simple look into how Fleek Network works in its current development phase and briefly share some of the core concepts like spinning up a node and making a request to a service to put and retrieve a .car files from the network."),(0,a.kt)("p",null,"For those seeking advanced knowledge:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Read our ",(0,a.kt)("a",{parentName:"li",href:"/docs/whitepaper"},"whitepaper"),"."),(0,a.kt)("li",{parentName:"ul"},"Check out ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning"},"our open-source code"),".")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"If you find any typos in our documentation, feel free to ",(0,a.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"provide us feedback")," or contribute by opening a PR in our repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/fleek-network-docs/"},"here"),".")),(0,a.kt)("h2",{id:"pre-requisites"},"Pre-requisites"),(0,a.kt)("p",null,"To follow the guide, you will need the following:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Familiarity with the command-line interface"),(0,a.kt)("li",{parentName:"ul"},"Git")),(0,a.kt)("h2",{id:"need-a-quick-fleek-network-tldr"},"Need a quick Fleek Network TL;DR?"),(0,a.kt)("p",null,"Fleek Network is an open-source edge computing platform to accelerate the development and execution of the next generation of web services."),(0,a.kt)("p",null,"The system is built on a distributed network of nodes, where services run within a fair and incentivized ecosystem constituted by an open community of developers and operators. It relies on blockchain technology at its core, allowing governance and token rewards as incentives for participation in serving the network."),(0,a.kt)("p",null,"Made by an open community that's free to operate nodes or build services without the need for approvals, permissions, or intermediaries. Or simply, consume Fleek Network resources on demand, from anywhere, provided by services running on the edge."),(0,a.kt)("p",null,"Applications, platforms and protocols build and utilize decentralized services on the Fleek Network to optimize performance and reduce dependency on typical centralized cloud providers and corporate infrastructure."),(0,a.kt)("p",null,"Developers can build faster and launch better products by offloading parts of the development stack to the edge to focus on core features for the value proposition of the services being developed."),(0,a.kt)("p",null,"To get started, install a Network Node in a ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/requirements"},"supported")," Linux server, such as Debian or Ubuntu (latest) by utilizing our simple ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#assisted-installer"},"assisted installer")," to help onboard as quickly as possible."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Our network is open to everyone, so you're more than welcome to join us anytime without any restrictions, permission or formalities. We'd be happy to have you as part of our community!")),(0,a.kt)("p",null,"Once connected to the server, open a terminal window and execute the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"curl https://get.fleek.network | bash\n")),(0,a.kt)("p",null,"Follow the install assistant recommendations to have the node ready without hassle and as quickly as possible."),(0,a.kt)("h2",{id:"why-is-fleek-network-needed"},"Why is Fleek Network needed?"),(0,a.kt)("p",null,"Web3 products typically rely on centralized cloud infrastructure, which is vulnerable to attacks as computation and data can be easily manipulated to suit business goals. However, blockchain technology has paved the way for a new era of decentralized cloud computing and data storage. The Fleek Network offers a sustainable alternative to traditional centralized architectures, providing a secure, transparent, and accessible decentralized edge computing future for everyone."),(0,a.kt)("h2",{id:"how-does-fleek-network-work"},"How Does Fleek Network Work?"),(0,a.kt)("p",null,"When a client requests a service, the protocol determines the best route to the nodes where the service replicas and workload are allocated."),(0,a.kt)("p",null,"Once the computation is successful, the data streaming routes to the client. On-client request fulfillment, a proof of delivery is generated containing cryptographically secured metadata about the original request, any parts involved and the resources consumed."),(0,a.kt)("p",null,"The Delivery Acknowledgements are stored locally in the participating node memory pools, rolled up to the protocol consensus consistently throughout the Epoch. This agreement is formed by a random committee of any healthy Nodes that use the information provided to reward the Nodes fairly."),(0,a.kt)("h2",{id:"running-a-node"},"Running a Node"),(0,a.kt)("p",null,"A Fleek Network node can be built and run on your machine. It\u2019s an ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"open-source project")," and is open for contributions."),(0,a.kt)("p",null,"The project is written with Rust, a general-purpose programming language that you need to have installed in advance to be able to follow the current guide."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"To set up Rust, packages and library dependencies can be tricky. The quickest is to visit the ",(0,a.kt)("a",{parentName:"p",href:"https://rustup.rs/"},"rustup.rs"),". Alternatively, if you haven't already, the build section has a ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation")," document to help.")),(0,a.kt)("h3",{id:"clone-the-source-code"},"Clone the source code"),(0,a.kt)("p",null,"We\u2019ll clone the repository locally, build it and interact with the node through the binary or the HTTP JSON-RPC API with a client like cURL, but you can use a GUI (Postman, Insomnia, amongst others) if you prefer."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"The ~/fleek-network/lightning or $HOME/fleek-network/lightning directory is the default or recommended location to store the repository. If you like to follow conventions, then is best to stick with the recommendation, to avoid confusion and make it easier to follow our documentation.")),(0,a.kt)("p",null,"Start by cloning the repository located at ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"https://github.com/fleek-network/lightning")),(0,a.kt)(i.ZP,{mdxType:"GitCloneOptions"}),(0,a.kt)("p",null,"Once the git clone completes, you\u2019ll have the latest version at the time of cloning. You should use git to fetch or pull the latest versions consequently."),(0,a.kt)("h3",{id:"dependencies"},"Dependencies"),(0,a.kt)("p",null,"Install the required dependencies necessary for compiling general software and for our use-case Lightning CLI."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get install \\\n build-essential \\\n clang \\\n pkg-config \\\n libssl-dev \\\n gcc-multilib \\\n protobuf-compiler\n")),(0,a.kt)("h3",{id:"build"},"Build"),(0,a.kt)("p",null,"Start by changing the directory to the project directory where the source code is stored. If you have followed the recommended location that'll be ",(0,a.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning"),", as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~/fleek-network/lightning\n")),(0,a.kt)("p",null,"Run the Rust package manager clean and update commands."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cargo clean\ncargo update\n")),(0,a.kt)("p",null,"Execute the install command to build and install the Fleek Network CLI."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cargo build\n")),(0,a.kt)("p",null,"The install command uses the Rust compiler to build; It might take a while depending on how speedy is your machine."),(0,a.kt)("p",null,"Once the Rust compiler completes, the generated binary will be available in the source code project directory. If you stick with the default, that'll look like ",(0,a.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning/target/debug/lightning-node"),"."),(0,a.kt)("p",null,"To avoid having to specify the pathname everytime, create a symbolic link to keep it short. Here we'll name the process as the global ",(0,a.kt)("inlineCode",{parentName:"p"},"lgtn"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'sudo ln -s "~/fleek-network/lightning/target/debug/lightning-node" /usr/local/bin/lgtn\n')),(0,a.kt)("p",null,"Run the CLI with the flag ",(0,a.kt)("inlineCode",{parentName:"p"},"version")," to confirm it's available globally."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn --version\n")),(0,a.kt)("p",null,"The output should look like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"Usage: lgtn [OPTIONS] \n\nCommands:\n run Start the node\n keys Handle keys\n print-config Print the loaded configuration\n dev-init-only Initialize the node without starting it\n dev-dump-graph Dump the infusion graph of the node instance\n help Print this message or the help of the given subcommand(s)\n\nOptions:\n -c, --config Path to the toml configuration file [default: ~/.lightning/config.toml]\n --with-mock-consensus Determines that we should be using the mock consensus backend\n -v... Increases the level of verbosity (the max level is -vvv)\n --log-location Print code location on console logs\n -h, --help Print help\n -V, --version Print version\n")),(0,a.kt)("h3",{id:"node-launch"},"Node Launch"),(0,a.kt)("p",null,"After ",(0,a.kt)("a",{parentName:"p",href:"#build"},"building"),", the node can be launched by running the subcommand ",(0,a.kt)("inlineCode",{parentName:"p"},"run"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn run\n")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"It's highly recommend to use systemd to manage the Fleek Network service for node operators. Systemd is a system and service manager for Linux operating systems that provides a consistent way to manage system services across various distributions.")),(0,a.kt)("p",null,"Learn how to create a new Systemd service in the ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation")," document."),(0,a.kt)("h3",{id:"health-check"},"Health check"),(0,a.kt)("p",null,"It's important for Node operators to regularly check on the health of their resources to make sure everything is running smoothly. By doing this, they can get helpful feedback and know for sure if their Node is up and running. Some experienced node operators even automate this process using cronjobs and get reports sent to them via email or other custom methods."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'curl -w "\\n" localhost:4069/health\n')),(0,a.kt)("p",null,"If everything goes well, the response should be:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"OK\n")),(0,a.kt)("p",null,"Alternatively, use the JSON-RPC method ",(0,a.kt)("inlineCode",{parentName:"p"},"flk_ping"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'curl -s \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d \'{\n "jsonrpc": "2.0",\n "method": "flk_ping",\n "params": [],\n "id": 1\n }\' \\\n localhost:4069/rpc/v0\n')),(0,a.kt)("p",null,"Which response should return the key ",(0,a.kt)("inlineCode",{parentName:"p"},"result")," with value ",(0,a.kt)("inlineCode",{parentName:"p"},"pong"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'{\n "jsonrpc": "2.0",\n "result": "pong",\n "id": 1\n}\n')),(0,a.kt)("h2",{id:"next-steps"},"Next steps"),(0,a.kt)("p",null,"While you can run the Network Node as described here, it's required to set up the Network Node correctly and securely! It requires some degree of patience, knowledge and time to go through our guides but we'll provide some guides and references to help you manage your network node server!"),(0,a.kt)("p",null,"To avoid having to go through all the steps manually, we recommend reading our ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#assisted-installer"},"assisted installer")," document for quick onboarding."),(0,a.kt)("h2",{id:"conclusion"},"Conclusion"),(0,a.kt)("p",null,"We introduced Fleek Network as an open-source edge computing platform to help us accelerate the development and execution of the next generation of web services."),(0,a.kt)("p",null,"We have learned a bit about the importance of a decentralized edge computing network to reach and fulfill the future of computation and how the Fleek Network protocol works succinctly."),(0,a.kt)("p",null,"We guide you through a step-by-step installation of the network node process, where we pull the source code, build the binary and launch the service."),(0,a.kt)("p",null,"Finally, we do a quick health check to confirm the status of our node."),(0,a.kt)("p",null,"Discover more about the project by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"watching/contributing on GitHub"),", following us on ",(0,a.kt)("a",{parentName:"p",href:"https://twitter.com/fleek_net"},"Twitter"),", and joining ",(0,a.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"our community Discord")," for any updates."),(0,a.kt)(r.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}m.isMDXComponent=!0},2915:(e,t,n)=>{n.d(t,{ZP:()=>l});var o=n(7462),a=(n(7294),n(3905));const r={toc:[]},i="wrapper";function l(e){let{components:t,...n}=e;return(0,a.kt)(i,(0,o.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"You have several ways of doing this:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},"Clone via HTTPS"),(0,a.kt)("li",{parentName:"ul"},"Clone via SSH"),(0,a.kt)("li",{parentName:"ul"},"Download via Github CLI"),(0,a.kt)("li",{parentName:"ul"},"Download the ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning/archive/refs/heads/main.zip"},"zip package")," from the repository")),(0,a.kt)("p",{parentName:"admonition"},"We recommend HTTPS because it is the easiest to set up in the wild, and by users who are new to all this.\nAlthough, we strongly recommend using an SSH connection when interacting with GitHub. If you are to this and are interested read more about it ",(0,a.kt)("a",{parentName:"p",href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh"},"here"),"."),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git \n")),(0,a.kt)("p",{parentName:"admonition"},"Here's an example of what it'd look like when sticking to the recommended path location:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git ~/fleek-network/lightning\n"))))}l.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>a});var o=n(7294);const a=e=>{let{image:t,name:n,title:a,url:r}=e;return o.createElement("section",{className:"author_card"},o.createElement("div",null,o.createElement("span",{className:"avatar"},o.createElement("a",{href:r,target:"_blank",alt:n},o.createElement("img",{src:t,alt:n}))),o.createElement("div",null,o.createElement("span",{className:"name"},o.createElement("a",{href:r,target:"_blank",alt:n},n)),o.createElement("span",{className:"title"},a),o.createElement("span",{className:"discord"},"Got questions? Find us on ",o.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/1c14429f.c7f842e6.js b/assets/js/1c14429f.c7f842e6.js deleted file mode 100644 index 3dfe5f4e0..000000000 --- a/assets/js/1c14429f.c7f842e6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[2702],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var o=n(7294);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 r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var s=o.createContext({}),d=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=d(e.components);return o.createElement(s.Provider,{value:t},e.children)},c="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},h=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),c=d(n),h=a,m=c["".concat(s,".").concat(h)]||c[h]||p[h]||r;return n?o.createElement(m,i(i({ref:t},u),{},{components:n})):o.createElement(m,i({ref:t},u))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[c]="string"==typeof e?e:a,i[1]=l;for(var d=2;d{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>s,default:()=>m,frontMatter:()=>l,metadata:()=>d,toc:()=>c});var o=n(7462),a=(n(7294),n(3905)),r=n(3872),i=n(2915);const l={template:"post",draft:!1,hide_title:!0,title:"Getting Started",slug:"getting-started",date:new Date("2023-08-31T23:00:00.000Z"),canonical:"",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",category:"Tutorial",tags:["Edge computing","Guide","Getting Started"]},s=void 0,d={unversionedId:"Node Operators/getting-started-guide",id:"Node Operators/getting-started-guide",title:"Getting Started",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",source:"@site/guides/Node Operators/getting-started-guide.md",sourceDirName:"Node Operators",slug:"/Node Operators/getting-started",permalink:"/guides/Node Operators/getting-started",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/Node Operators/getting-started-guide.md",tags:[{label:"Edge computing",permalink:"/guides/tags/edge-computing"},{label:"Guide",permalink:"/guides/tags/guide"},{label:"Getting Started",permalink:"/guides/tags/getting-started"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{template:"post",draft:!1,hide_title:!0,title:"Getting Started",slug:"getting-started",date:"2023-08-31T23:00:00.000Z",canonical:"",description:"A first look at what Fleek Network is, why it's important, and a simple tutorial of running and interacting with a node on your local machine!",category:"Tutorial",tags:["Edge computing","Guide","Getting Started"]},sidebar:"defaultSidebar",previous:{title:"About guides",permalink:"/guides/"},next:{title:"Migrate ownership of node setup to user",permalink:"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}},u={},c=[{value:"Introduction",id:"introduction",level:2},{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Need a quick Fleek Network TL;DR?",id:"need-a-quick-fleek-network-tldr",level:2},{value:"Why is Fleek Network needed?",id:"why-is-fleek-network-needed",level:2},{value:"How Does Fleek Network Work?",id:"how-does-fleek-network-work",level:2},{value:"Running a Node",id:"running-a-node",level:2},{value:"Clone the source code",id:"clone-the-source-code",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Build",id:"build",level:3},{value:"Node Launch",id:"node-launch",level:3},{value:"Health check",id:"health-check",level:3},{value:"Next steps",id:"next-steps",level:2},{value:"Conclusion",id:"conclusion",level:2}],p={toc:c},h="wrapper";function m(e){let{components:t,...n}=e;return(0,a.kt)(h,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h2",{id:"introduction"},"Introduction"),(0,a.kt)("p",null,"For this guide, we\u2019ll have a simple look into how Fleek Network works in its current development phase and briefly share some of the core concepts like spinning up a node and making a request to a service to put and retrieve a .car files from the network."),(0,a.kt)("p",null,"For those seeking advanced knowledge:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Read our ",(0,a.kt)("a",{parentName:"li",href:"/docs/whitepaper"},"whitepaper"),"."),(0,a.kt)("li",{parentName:"ul"},"Check out ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning"},"our open-source code"),".")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"If you find any typos in our documentation, feel free to ",(0,a.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"provide us feedback")," or contribute by opening a PR in our repository ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/fleek-network-docs/"},"here"),".")),(0,a.kt)("h2",{id:"pre-requisites"},"Pre-requisites"),(0,a.kt)("p",null,"To follow the guide, you will need the following:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},"Familiarity with the command-line interface"),(0,a.kt)("li",{parentName:"ul"},"Git")),(0,a.kt)("h2",{id:"need-a-quick-fleek-network-tldr"},"Need a quick Fleek Network TL;DR?"),(0,a.kt)("p",null,"Fleek Network is an open-source edge computing platform to accelerate the development and execution of the next generation of web services."),(0,a.kt)("p",null,"The system is built on a distributed network of nodes, where services run within a fair and incentivized ecosystem constituted by an open community of developers and operators. It relies on blockchain technology at its core, allowing governance and token rewards as incentives for participation in serving the network."),(0,a.kt)("p",null,"Made by an open community that's free to operate nodes or build services without the need for approvals, permissions, or intermediaries. Or simply, consume Fleek Network resources on demand, from anywhere, provided by services running on the edge."),(0,a.kt)("p",null,"Applications, platforms and protocols build and utilize decentralized services on the Fleek Network to optimize performance and reduce dependency on typical centralized cloud providers and corporate infrastructure."),(0,a.kt)("p",null,"Developers can build faster and launch better products by offloading parts of the development stack to the edge to focus on core features for the value proposition of the services being developed."),(0,a.kt)("p",null,"To get started, install a Network Node in a ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/requirements"},"supported")," Linux server, such as Debian or Ubuntu (latest) by utilizing our simple ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#assisted-installer"},"assisted installer")," to help onboard as quickly as possible."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"Our network is open to everyone, so you're more than welcome to join us anytime without any restrictions, permission or formalities. We'd be happy to have you as part of our community!")),(0,a.kt)("p",null,"Once connected to the server, open a terminal window and execute the following command:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"curl https://get.fleek.network | bash\n")),(0,a.kt)("p",null,"Follow the install assistant recommendations to have the node ready without hassle and as quickly as possible."),(0,a.kt)("h2",{id:"why-is-fleek-network-needed"},"Why is Fleek Network needed?"),(0,a.kt)("p",null,"Web3 products typically rely on centralized cloud infrastructure, which is vulnerable to attacks as computation and data can be easily manipulated to suit business goals. However, blockchain technology has paved the way for a new era of decentralized cloud computing and data storage. The Fleek Network offers a sustainable alternative to traditional centralized architectures, providing a secure, transparent, and accessible decentralized edge computing future for everyone."),(0,a.kt)("h2",{id:"how-does-fleek-network-work"},"How Does Fleek Network Work?"),(0,a.kt)("p",null,"When a client requests a service, the protocol determines the best route to the nodes where the service replicas and workload are allocated."),(0,a.kt)("p",null,"Once the computation is successful, the data streaming routes to the client. On-client request fulfillment, a proof of delivery is generated containing cryptographically secured metadata about the original request, any parts involved and the resources consumed."),(0,a.kt)("p",null,"The Delivery Acknowledgements are stored locally in the participating node memory pools, rolled up to the protocol consensus consistently throughout the Epoch. This agreement is formed by a random committee of any healthy Nodes that use the information provided to reward the Nodes fairly."),(0,a.kt)("h2",{id:"running-a-node"},"Running a Node"),(0,a.kt)("p",null,"A Fleek Network node can be built and run on your machine. It\u2019s an ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"open-source project")," and is open for contributions."),(0,a.kt)("p",null,"The project is written with Rust, a general-purpose programming language that you need to have installed in advance to be able to follow the current guide."),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"To set up Rust, packages and library dependencies can be tricky. The quickest is to visit the ",(0,a.kt)("a",{parentName:"p",href:"https://rustup.rs/"},"rustup.rs"),". Alternatively, if you haven't already, the build section has a ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation")," document to help.")),(0,a.kt)("h3",{id:"clone-the-source-code"},"Clone the source code"),(0,a.kt)("p",null,"We\u2019ll clone the repository locally, build it and interact with the node through the binary or the HTTP JSON-RPC API with a client like cURL, but you can use a GUI (Postman, Insomnia, amongst others) if you prefer."),(0,a.kt)("admonition",{type:"note"},(0,a.kt)("p",{parentName:"admonition"},"The ~/fleek-network/lightning or $HOME/fleek-network/lightning directory is the default or recommended location to store the repository. If you like to follow conventions, then is best to stick with the recommendation, to avoid confusion and make it easier to follow our documentation.")),(0,a.kt)("p",null,"Start by cloning the repository located at ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"https://github.com/fleek-network/lightning")),(0,a.kt)(i.ZP,{mdxType:"GitCloneOptions"}),(0,a.kt)("p",null,"Once the git clone completes, you\u2019ll have the latest version at the time of cloning. You should use git to fetch or pull the latest versions consequently."),(0,a.kt)("h3",{id:"dependencies"},"Dependencies"),(0,a.kt)("p",null,"Install the required dependencies necessary for compiling general software and for our use-case Lightning CLI."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get install \\\n build-essential \\\n clang \\\n pkg-config \\\n libssl-dev \\\n gcc-multilib \\\n protobuf-compiler\n")),(0,a.kt)("h3",{id:"build"},"Build"),(0,a.kt)("p",null,"Start by changing the directory to the project directory where the source code is stored. If you have followed the recommended location that'll be ",(0,a.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning"),", as follows:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~/fleek-network/lightning\n")),(0,a.kt)("p",null,"Run the Rust package manager clean and update commands."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cargo clean\ncargo update\n")),(0,a.kt)("p",null,"Execute the install command to build and install the Fleek Network CLI."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"cargo build\n")),(0,a.kt)("p",null,"The install command uses the Rust compiler to build; It might take a while depending on how speedy is your machine."),(0,a.kt)("p",null,"Once the Rust compiler completes, the generated binary will be available in the source code project directory. If you stick with the default, that'll look like ",(0,a.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning/target/debug/lightning-node"),"."),(0,a.kt)("p",null,"To avoid having to specify the pathname everytime, create a symbolic link to keep it short. Here we'll name the process as the global ",(0,a.kt)("inlineCode",{parentName:"p"},"lgtn"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'sudo ln -s "~/fleek-network/lightning/target/debug/lightning-node" /usr/local/bin/lgtn\n')),(0,a.kt)("p",null,"Run the CLI with the flag ",(0,a.kt)("inlineCode",{parentName:"p"},"version")," to confirm it's available globally."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn --version\n")),(0,a.kt)("p",null,"The output should look like:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"Usage: lgtn [OPTIONS] \n\nCommands:\n run Start the node\n keys Handle keys\n print-config Print the loaded configuration\n dev-init-only Initialize the node without starting it\n dev-dump-graph Dump the infusion graph of the node instance\n help Print this message or the help of the given subcommand(s)\n\nOptions:\n -c, --config Path to the toml configuration file [default: ~/.lightning/config.toml]\n --with-mock-consensus Determines that we should be using the mock consensus backend\n -v... Increases the level of verbosity (the max level is -vvv)\n --log-location Print code location on console logs\n -h, --help Print help\n -V, --version Print version\n")),(0,a.kt)("h3",{id:"node-launch"},"Node Launch"),(0,a.kt)("p",null,"After ",(0,a.kt)("a",{parentName:"p",href:"#build"},"building"),", the node can be launched by running the subcommand ",(0,a.kt)("inlineCode",{parentName:"p"},"run"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn run\n")),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"It's highly recommend to use systemd to manage the Fleek Network service for node operators. Systemd is a system and service manager for Linux operating systems that provides a consistent way to manage system services across various distributions.")),(0,a.kt)("p",null,"Learn how to create a new Systemd service in the ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation")," document."),(0,a.kt)("h3",{id:"health-check"},"Health check"),(0,a.kt)("p",null,"It's important for Node operators to regularly check on the health of their resources to make sure everything is running smoothly. By doing this, they can get helpful feedback and know for sure if their Node is up and running. Some experienced node operators even automate this process using cronjobs and get reports sent to them via email or other custom methods."),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'curl -w "\\n" localhost:4069/health\n')),(0,a.kt)("p",null,"If everything goes well, the response should be:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"OK\n")),(0,a.kt)("p",null,"Alternatively, use the JSON-RPC method ",(0,a.kt)("inlineCode",{parentName:"p"},"flk_ping"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'curl -s \\\n -X POST \\\n -H "Content-Type: application/json" \\\n -d \'{\n "jsonrpc": "2.0",\n "method": "flk_ping",\n "params": [],\n "id": 1\n }\' \\\n localhost:4069/rpc/v0\n')),(0,a.kt)("p",null,"Which response should return the key ",(0,a.kt)("inlineCode",{parentName:"p"},"result")," with value ",(0,a.kt)("inlineCode",{parentName:"p"},"pong"),":"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-sh"},'{\n "jsonrpc": "2.0",\n "result": "pong",\n "id": 1\n}\n')),(0,a.kt)("h2",{id:"next-steps"},"Next steps"),(0,a.kt)("p",null,"While you can run the Network Node as described here, it's required to set up the Network Node correctly and securely! It requires some degree of patience, knowledge and time to go through our guides but we'll provide some guides and references to help you manage your network node server!"),(0,a.kt)("p",null,"To avoid having to go through all the steps manually, we recommend reading our ",(0,a.kt)("a",{parentName:"p",href:"/docs/node/install#assisted-installer"},"assisted installer")," document for quick onboarding."),(0,a.kt)("h2",{id:"conclusion"},"Conclusion"),(0,a.kt)("p",null,"We introduced Fleek Network as an open-source edge computing platform to help us accelerate the development and execution of the next generation of web services."),(0,a.kt)("p",null,"We have learned a bit about the importance of a decentralized edge computing network to reach and fulfill the future of computation and how the Fleek Network protocol works succinctly."),(0,a.kt)("p",null,"We guide you through a step-by-step installation of the network node process, where we pull the source code, build the binary and launch the service."),(0,a.kt)("p",null,"Finally, we do a quick health check to confirm the status of our node."),(0,a.kt)("p",null,"Discover more about the project by ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"watching/contributing on GitHub"),", following us on ",(0,a.kt)("a",{parentName:"p",href:"https://twitter.com/fleek_net"},"Twitter"),", and joining ",(0,a.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"our community Discord")," for any updates."),(0,a.kt)(r.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}m.isMDXComponent=!0},2915:(e,t,n)=>{n.d(t,{ZP:()=>l});var o=n(7462),a=(n(7294),n(3905));const r={toc:[]},i="wrapper";function l(e){let{components:t,...n}=e;return(0,a.kt)(i,(0,o.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("admonition",{type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"You have several ways of doing this:"),(0,a.kt)("ul",{parentName:"admonition"},(0,a.kt)("li",{parentName:"ul"},"Clone via HTTPS"),(0,a.kt)("li",{parentName:"ul"},"Clone via SSH"),(0,a.kt)("li",{parentName:"ul"},"Download via Github CLI"),(0,a.kt)("li",{parentName:"ul"},"Download the ",(0,a.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning/archive/refs/heads/main.zip"},"zip package")," from the repository")),(0,a.kt)("p",{parentName:"admonition"},"We recommend HTTPS because it is the easiest to set up in the wild, and by users who are new to all this.\nAlthough, we strongly recommend using an SSH connection when interacting with GitHub. If you are to this and are interested read more about it ",(0,a.kt)("a",{parentName:"p",href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh"},"here"),"."),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git \n")),(0,a.kt)("p",{parentName:"admonition"},"Here's an example of what it'd look like when sticking to the recommended path location:"),(0,a.kt)("pre",{parentName:"admonition"},(0,a.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git ~/fleek-network/lightning\n"))))}l.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>a});var o=n(7294);const a=e=>{let{image:t,name:n,title:a,url:r}=e;return o.createElement("section",{className:"author_card"},o.createElement("div",null,o.createElement("span",{className:"avatar"},o.createElement("a",{href:r,target:"_blank",alt:n},o.createElement("img",{src:t,alt:n}))),o.createElement("div",null,o.createElement("span",{className:"name"},o.createElement("a",{href:r,target:"_blank",alt:n},n)),o.createElement("span",{className:"title"},a),o.createElement("span",{className:"discord"},"Got questions? Find us on ",o.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/1d8a5d15.1b54b05c.js b/assets/js/1d8a5d15.1b54b05c.js new file mode 100644 index 000000000..509e2aeef --- /dev/null +++ b/assets/js/1d8a5d15.1b54b05c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[9854],{3905:(e,t,n)=>{n.d(t,{Zo:()=>h,kt:()=>c});var o=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=o.createContext({}),p=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},h=function(e){var t=p(e.components);return o.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,r=e.mdxType,a=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=p(n),m=r,c=d["".concat(l,".").concat(m)]||d[m]||u[m]||a;return n?o.createElement(c,i(i({ref:t},h),{},{components:n})):o.createElement(c,i({ref:t},h))}));function c(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var a=n.length,i=new Array(a);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:r,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>p,default:()=>g,frontMatter:()=>l,metadata:()=>h,toc:()=>u});var o=n(7462),r=(n(7294),n(3905)),a=n(3872),i=(n(2915),n(6733)),s=n(3242);const l={template:"post",draft:!1,hide_title:!0,title:"Transfering setup ownership",slug:"transfering-setup-ownership",date:new Date("2023-09-12T23:00:00.000Z"),description:"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup",category:"Tutorial",tags:["transfer","ownership","guide","setup","configuration"]},p=void 0,h={unversionedId:"Node Operators/transfering-setup-ownership",id:"Node Operators/transfering-setup-ownership",title:"Transfering setup ownership",description:"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup",source:"@site/guides/Node Operators/transfering-setup-ownership.md",sourceDirName:"Node Operators",slug:"/Node Operators/transfering-setup-ownership",permalink:"/guides/Node Operators/transfering-setup-ownership",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/Node Operators/transfering-setup-ownership.md",tags:[{label:"transfer",permalink:"/guides/tags/transfer"},{label:"ownership",permalink:"/guides/tags/ownership"},{label:"guide",permalink:"/guides/tags/guide"},{label:"setup",permalink:"/guides/tags/setup"},{label:"configuration",permalink:"/guides/tags/configuration"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{template:"post",draft:!1,hide_title:!0,title:"Transfering setup ownership",slug:"transfering-setup-ownership",date:"2023-09-12T23:00:00.000Z",description:"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup",category:"Tutorial",tags:["transfer","ownership","guide","setup","configuration"]},sidebar:"defaultSidebar",previous:{title:"Getting Started",permalink:"/guides/Node Operators/getting-started"}},d={},u=[{value:"Introduction",id:"introduction",level:2},{value:"Pre-requisites",id:"pre-requisites",level:2},{value:"Ownership of Lightning CLI files",id:"ownership-of-lightning-cli-files",level:2},{value:"Systemd Service",id:"systemd-service",level:2},{value:"Stop the service",id:"stop-the-service",level:2},{value:"Clear the .lightning data",id:"clear-the-lightning-data",level:2},{value:"Create a user",id:"create-a-user",level:2},{value:"Move lightning system and source code directory to user's home",id:"move-lightning-system-and-source-code-directory-to-users-home",level:2},{value:"1) Move the /root/.lightning directory from one user to the other",id:"1-move-the-rootlightning-directory-from-one-user-to-the-other",level:3},{value:"2) Move the /root/fleek-network directory from one user to the other",id:"2-move-the-rootfleek-network-directory-from-one-user-to-the-other",level:3},{value:"3) Confirm move by finding both directories",id:"3-confirm-move-by-finding-both-directories",level:3},{value:"Change ownership of files",id:"change-ownership-of-files",level:2},{value:"Update the Systemd service unit",id:"update-the-systemd-service-unit",level:2},{value:"Update the config.toml with user-preferred file locations",id:"update-the-configtoml-with-user-preferred-file-locations",level:2},{value:"Start the service",id:"start-the-service",level:2},{value:"Conclusion",id:"conclusion",level:2}],m={toc:u},c="wrapper";function g(e){let{components:t,...n}=e;return(0,r.kt)(c,(0,o.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"introduction"},"Introduction"),(0,r.kt)("p",null,"Our Lightning CLI and Node process is run by a user, that has some sort of permissions\u2013some users run it as a super user (root) which is questionable as root privileges are not a necessary good. We'll look into how to create a user to manage and control the Fleek Network Lightning CLI and Systemd unit service. Also, presents the concept of file permissions and ownership which is crucial in preventing private or sensitive data from being exposed to dodgy actors."),(0,r.kt)("p",null,"Let's discuss the topic and open up a few ideas to help us improve the security of our server."),(0,r.kt)("h2",{id:"pre-requisites"},"Pre-requisites"),(0,r.kt)("p",null,"To follow the guide, you will need the following:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"Familiarity with the command-line interface"),(0,r.kt)("li",{parentName:"ul"},"Have installed and set up the Lightning CLI and service")),(0,r.kt)("h2",{id:"ownership-of-lightning-cli-files"},"Ownership of Lightning CLI files"),(0,r.kt)("p",null,"The user who installs the Lightning CLI and sets the Service takes an important role that determines the location of the configuration files, the setup, and how the Systemd service is managed or controlled."),(0,r.kt)("p",null,"Our ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install"},"install")," document recommends creating a user and switching to the user to set up the service. You shouldn't want installed applications to run with elevated privileges. Applications are meant to be run with non-administrative privileges. If an application requires higher privileges, the administrator, such as a ",(0,r.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Sudo"},"sudoer")," should be able to elevate it. An application that has full access and control of a system can modify it in harmful ways, e.g. compromise the private keys."),(0,r.kt)("p",null,"For our guide, we'll illustrate the process of migration from a super user (root) to another user (sudo). The knowledge should be easily appliable for any other user-to-user migration. We stick with root user for simplicity and because that's the most common use case."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"A reference document about ",(0,r.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"File permissions and ownership")," is available that explains how it works practically, by showcasing how the process can be started, how the node process locates the Keystore, etc.")),(0,r.kt)("h2",{id:"systemd-service"},"Systemd Service"),(0,r.kt)("p",null,"In systemd, a unit refers to any resource that the system knows how to operate on and manage. This is the primary object that the systemd tools know how to deal with. These resources are defined using configuration files called unit files."),(0,r.kt)("p",null,"The recommended installation process features a ",(0,r.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.service.html"},"systemd.service")," which is a resource that the system knows how to operate and manage by an administrator user."),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"When using a Systemd service to run a process, it operates comparably to running it directly. The key difference is that Systemd keeps track of all the processes and threads that are spawned. This means that when a service is stopped using systemctl, such as the Fleek Network Lightning Node service, all the child processes that were started by the service are also terminated. Additionally, by utilizing Systemd, a user can run the process in the background and configure it to start automatically on system startup.")),(0,r.kt)("p",null,"If you have followed the installation recommendations, find the systemd service unit in the location ",(0,r.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," (we are using Ubuntu Linux as an example to keep it short)."),(0,r.kt)("p",null,"Make sure that you have set up a ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"Systemd unit service"),", as recommended during the installation as this guide assumes you have one setup."),(0,r.kt)("h2",{id:"stop-the-service"},"Stop the service"),(0,r.kt)("p",null,"Before we proceed with any changes required for the migration, you'll have to stop the ",(0,r.kt)("inlineCode",{parentName:"p"},"lightning.service"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl stop lightning\n")),(0,r.kt)("admonition",{type:"note"},(0,r.kt)("p",{parentName:"admonition"},"For this guide, we are assuming that you are migrating ownership from ",(0,r.kt)("strong",{parentName:"p"},"root")," to a ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," user. If not, you might be required to elevate privileges as ",(0,r.kt)("strong",{parentName:"p"},"sudo**")," where required. For example, ",(0,r.kt)("inlineCode",{parentName:"p"},"sudo systemctl stop lightning"),".")),(0,r.kt)("h2",{id:"clear-the-lightning-data"},"Clear the .lightning data"),(0,r.kt)("p",null,"Run the following command to clear the ",(0,r.kt)("inlineCode",{parentName:"p"},"/root/.lightning/data"),", as it can be quite large and we don't need to move it."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -rf /root/.lightning/data\n")),(0,r.kt)("h2",{id:"create-a-user"},"Create a user"),(0,r.kt)(i.ZP,{mdxType:"CreateAUser"}),(0,r.kt)("h2",{id:"move-lightning-system-and-source-code-directory-to-users-home"},"Move lightning system and source code directory to user's home"),(0,r.kt)("p",null,"A user should've been created, added the user to the sudo group, switched to the user, and changed the directory to the user's home."),(0,r.kt)("p",null,"Run the command ",(0,r.kt)("inlineCode",{parentName:"p"},"pwd"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"pwd\n")),(0,r.kt)("p",null,"The output would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"/home/\n")),(0,r.kt)("p",null,"Given the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"/home/lgtn\n")),(0,r.kt)("p",null,"You'll then move two directories:"),(0,r.kt)("ul",null,(0,r.kt)("li",{parentName:"ul"},"The ",(0,r.kt)("inlineCode",{parentName:"li"},"/root/.lightning")),(0,r.kt)("li",{parentName:"ul"},"The source code under the parent ",(0,r.kt)("inlineCode",{parentName:"li"},"/root/fleek-network"))),(0,r.kt)("h3",{id:"1-move-the-rootlightning-directory-from-one-user-to-the-other"},"1) Move the ",(0,r.kt)("inlineCode",{parentName:"h3"},"/root/.lightning")," directory from one user to the other"),(0,r.kt)("p",null,"For our demo, we have assumed ",(0,r.kt)("strong",{parentName:"p"},"root")," user to ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," user named ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),", thus that'll look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mv /root/.lightning /home/lgtn/\n")),(0,r.kt)("h3",{id:"2-move-the-rootfleek-network-directory-from-one-user-to-the-other"},"2) Move the ",(0,r.kt)("inlineCode",{parentName:"h3"},"/root/fleek-network")," directory from one user to the other"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mv /root/fleek-network /home/lgtn/\n")),(0,r.kt)("h3",{id:"3-confirm-move-by-finding-both-directories"},"3) Confirm move by finding both directories"),(0,r.kt)("p",null,"In the user $HOME directory, you should be able to list the content of the directory and find the ",(0,r.kt)("inlineCode",{parentName:"p"},".lightning")," and ",(0,r.kt)("inlineCode",{parentName:"p"},"fleek-network")," directory."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la\n")),(0,r.kt)("p",null,"The output should be similar to the following."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 13:51 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 root root 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 3 root root 4096 Sep 11 12:28 fleek-network\n")),(0,r.kt)("h2",{id:"change-ownership-of-files"},"Change ownership of files"),(0,r.kt)("p",null,"Once the directories and files are moved, they should have have the wrong ownership, which should be set to ",(0,r.kt)("strong",{parentName:"p"},"root:root"),". We'll now have to change the ownership of the directories and files recursively."),(0,r.kt)("p",null,"Change the ownership of ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning")," to the user ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo chown -R lgtn:lgtn .lightning\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Make sure that you use the ",(0,r.kt)("inlineCode",{parentName:"p"},"-R")," flag to have the ownership changes applied to the parent, the child directories and all the files.")),(0,r.kt)("p",null,"Change the ownership of ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/fleek-network")," to the user ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo chown -R lgtn:lgtn fleek-network\n")),(0,r.kt)("p",null,"Once completed, if you list the content of the directory the ownership should have changed from ",(0,r.kt)("inlineCode",{parentName:"p"},"root:root")," to ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn:lgtn"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la\n")),(0,r.kt)("p",null,"The output should be similar to the following."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 13:51 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 3 lgtn lgtn 4096 Sep 11 12:28 fleek-network\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Remember that we are using ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," for our demo. If you have opted for a different username, make sure you use the correct username. To find the username you are logged in with run the command:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"whoami\n")),(0,r.kt)("p",{parentName:"admonition"},"For our demo, we'll assume that you understand that ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," is the user we opted in for our demo.")),(0,r.kt)("p",null,"##\xa0The lgtn symbolic link (symlink)"),(0,r.kt)("p",null,"We have the symbolic link that links the binary built from the source code, to the alias ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," that's set under the ",(0,r.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn")," pathname."),(0,r.kt)("p",null,"For example, you can find where that is linked to by running:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"ls -la $(which lgtn)\n")),(0,r.kt)("p",null,"On the output below, we can see that the ",(0,r.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn")," points to ",(0,r.kt)("inlineCode",{parentName:"p"},"/root/fleek-network/lightning/target/release/lightning-node"),"."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"lrwxrwxrwx 1 root root 64 Sep 11 15:48 /usr/local/bin/lgtn -> /root/fleek-network/lightning/target/release/lightning-node\n")),(0,r.kt)("p",null,"The target base path is ",(0,r.kt)("inlineCode",{parentName:"p"},"/root")," and we know that we've moved the source code directory to the user home ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn"),". For this reason, we need to create a new symlink with the updated location of the binary file."),(0,r.kt)("p",null,"Unlink the symlink:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo unlink lgtn\n")),(0,r.kt)("p",null,"Create the symlink:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sudo ln -s "/home/lgtn/fleek-network/lightning/target/release/lightning-node" /usr/local/bin/lgtn\n')),(0,r.kt)("p",null,"If successful, you should be able to execute the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn help\n")),(0,r.kt)("p",null,"The output should look similar to:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"Usage: lgtn [OPTIONS] \n\nCommands:\n run Start the node\n keys Handle keys\n print-config Print the loaded configuration\n help Print this message or the help of the given subcommand(s)\n\nOptions:\n -c, --config Path to the toml configuration file [default: ~/.lightning/config.toml]\n --with-mock-consensus Determines that we should be using the mock consensus backend\n -v... Increases the level of verbosity (the max level is -vvv)\n --log-location Print code location on console logs\n -h, --help Print help\n -V, --version Print version\n")),(0,r.kt)("h2",{id:"update-the-systemd-service-unit"},"Update the Systemd service unit"),(0,r.kt)("p",null,"Open the file, its settings should be similar to the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home//.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,r.kt)("p",null,"Since we opted in for the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn")," for our demo, replaced ",(0,r.kt)("inlineCode",{parentName:"p"},"")," with ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," and it would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Notice the ",(0,r.kt)("inlineCode",{parentName:"p"},"ExecStart=")," which includes the flag ",(0,r.kt)("inlineCode",{parentName:"p"},"-c")," where the location of the user files is declared. Learn how to ",(0,r.kt)("a",{parentName:"p",href:"#update-the-configtoml-with-user-preferred-file-locations"},"update the config.toml")," to include the user-preferred file paths, e.g. declare the keystore pathname.")),(0,r.kt)("p",null,"Complete the step by reloading the daemon, to apply the newly created changes. You can do this by executing:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,r.kt)("h2",{id:"update-the-configtoml-with-user-preferred-file-locations"},"Update the config.toml with user-preferred file locations"),(0,r.kt)("p",null,"Open the ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," file in your favorite text editor."),(0,r.kt)("p",null,"Replace every instance of ",(0,r.kt)("inlineCode",{parentName:"p"},"~")," (tilde) with the user's home path. We do this to ensure that every time we control the service via systemctl, the configuration file that tells which keystore to use is declared upfront regardless of running it as user or delegating to root with ",(0,r.kt)("strong",{parentName:"p"},"sudo"),". Learn more about ",(0,r.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"file permissions and ownership")," by reading the reference document."),(0,r.kt)(s.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,r.kt)("h2",{id:"start-the-service"},"Start the service"),(0,r.kt)("p",null,"At this stage, you should have migrated the essential files to the user home."),(0,r.kt)("p",null,"Ideally, you would now manage the service as the ",(0,r.kt)("inlineCode",{parentName:"p"},"user")," (as described in the ",(0,r.kt)("a",{parentName:"p",href:"/references/Systemd/user-service/"},"user service reference"),"). To keep our guide wider to all users, we'll prefix the commands with ",(0,r.kt)("strong",{parentName:"p"},"sudo"),", which elevates the permissions to ",(0,r.kt)("strong",{parentName:"p"},"root"),". But since we have provided the configuration file the ",(0,r.kt)("inlineCode",{parentName:"p"},"-c")," in our ",(0,r.kt)("a",{parentName:"p",href:"#systemd-service"},"systemd service"),", we'll have the user-preferred configuration options ruling. "),(0,r.kt)("p",null,"Start the service by running the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl start lightning.service\n")),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Find the timeline of events for the Lightning service by checking the log files. Learn about it in the section ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#analyzing-log-messages"},"Log Messages"),".")),(0,r.kt)("p",null,"To learn more, visit the section ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#use-systemctl-to-manage-systemd-service"},"Use Systemctl to manage the Lightning Service")),(0,r.kt)("h2",{id:"conclusion"},"Conclusion"),(0,r.kt)("p",null,"We started by giving a brief introduction to ownership of the Lightning CLI files."),(0,r.kt)("p",null,"Jumped through topics of Systemd service that helps the user manage the service in the Linux environment, which helps keep keeps track of all the processes and threads that are spawned."),(0,r.kt)("p",null,"We've gone through the step-by-step process to migrate the Fleek Network CLI and Systemd service setup from one user to the other. To keep it short, we decided to go with the use-case of where the migration happens between a ",(0,r.kt)("strong",{parentName:"p"},"root")," user and a ",(0,r.kt)("strong",{parentName:"p"},"sudoer"),"."),(0,r.kt)("p",null,"Discover more about the project by ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"watching/contributing on GitHub"),", following us on ",(0,r.kt)("a",{parentName:"p",href:"https://twitter.com/fleek_net"},"Twitter"),", and joining ",(0,r.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"our community Discord")," for any updates."),(0,r.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}g.isMDXComponent=!0},6733:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"We recommend creating a ",(0,r.kt)("inlineCode",{parentName:"p"},"non-root")," user with administrative privileges. It'll allow us to install any system requirements."),(0,r.kt)("p",null,"You can create a new user and add to the ",(0,r.kt)("strong",{parentName:"p"},"sudo")," group by running:"),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"For our example, we'll be using the name ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," but you can pick whichever you'd like. If you already have a ",(0,r.kt)("strong",{parentName:"p"},"sudoer")," account, you can skip this step.")),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"adduser lgtn\n")),(0,r.kt)("p",null,"After completing the ",(0,r.kt)("inlineCode",{parentName:"p"},"adduser")," steps, execute the ",(0,r.kt)("inlineCode",{parentName:"p"},"usermod")," to add the ",(0,r.kt)("inlineCode",{parentName:"p"},"user")," to the ",(0,r.kt)("strong",{parentName:"p"},"sudo")," group, as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"usermod -aG sudo lgtn\n")),(0,r.kt)("p",null,"Switch to the new ",(0,r.kt)("strong",{parentName:"p"},"user")," by using the command:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"su lgtn\n")),(0,r.kt)("p",null,"Change the directory to the new user's home, as follows:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"cd /home/lgtn\n")))}s.isMDXComponent=!0},3242:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("p",null,"In the ",(0,r.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,r.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,r.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,r.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,r.kt)("p",null,"Here's an example of how to do it using ",(0,r.kt)("strong",{parentName:"p"},"sed"),":"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Replace the ",(0,r.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,r.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,r.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,r.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,r.kt)("p",null,"For example, if your username is ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,r.kt)("p",null,"Once modified, you can run a ",(0,r.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,r.kt)("p",null,"For our example where we opted in for the username ",(0,r.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,r.kt)("admonition",{title:"Warning",type:"caution"},(0,r.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}s.isMDXComponent=!0},2915:(e,t,n)=>{n.d(t,{ZP:()=>s});var o=n(7462),r=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,r.kt)(i,(0,o.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("admonition",{type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"You have several ways of doing this:"),(0,r.kt)("ul",{parentName:"admonition"},(0,r.kt)("li",{parentName:"ul"},"Clone via HTTPS"),(0,r.kt)("li",{parentName:"ul"},"Clone via SSH"),(0,r.kt)("li",{parentName:"ul"},"Download via Github CLI"),(0,r.kt)("li",{parentName:"ul"},"Download the ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/fleek-network/lightning/archive/refs/heads/main.zip"},"zip package")," from the repository")),(0,r.kt)("p",{parentName:"admonition"},"We recommend HTTPS because it is the easiest to set up in the wild, and by users who are new to all this.\nAlthough, we strongly recommend using an SSH connection when interacting with GitHub. If you are to this and are interested read more about it ",(0,r.kt)("a",{parentName:"p",href:"https://docs.github.com/en/authentication/connecting-to-github-with-ssh"},"here"),"."),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git \n")),(0,r.kt)("p",{parentName:"admonition"},"Here's an example of what it'd look like when sticking to the recommended path location:"),(0,r.kt)("pre",{parentName:"admonition"},(0,r.kt)("code",{parentName:"pre",className:"language-sh"},"git clone -b testnet-alpha-0 https://github.com/fleek-network/lightning.git ~/fleek-network/lightning\n"))))}s.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>r});var o=n(7294);const r=e=>{let{image:t,name:n,title:r,url:a}=e;return o.createElement("section",{className:"author_card"},o.createElement("div",null,o.createElement("span",{className:"avatar"},o.createElement("a",{href:a,target:"_blank",alt:n},o.createElement("img",{src:t,alt:n}))),o.createElement("div",null,o.createElement("span",{className:"name"},o.createElement("a",{href:a,target:"_blank",alt:n},n)),o.createElement("span",{className:"title"},r),o.createElement("span",{className:"discord"},"Got questions? Find us on ",o.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/2730e145.cf48e169.js b/assets/js/2730e145.17a8321b.js similarity index 99% rename from assets/js/2730e145.cf48e169.js rename to assets/js/2730e145.17a8321b.js index 4ddc92663..69dc54743 100644 --- a/assets/js/2730e145.cf48e169.js +++ b/assets/js/2730e145.17a8321b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[7147],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),d=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=d(e.components);return r.createElement(l.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(t),u=i,h=c["".concat(l,".").concat(u)]||c[u]||m[u]||a;return t?r.createElement(h,o(o({ref:n},p),{},{components:t})):r.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var d=2;d{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var r=t(7462),i=(t(7294),t(3905)),a=t(3872);const o={title:"Permission denied (os error 13)",slug:"permission-denied-os-error-13",hide_title:!0,tags:["permissions"]},s=void 0,l={unversionedId:"Lightning CLI/permission-denied-os-error-13",id:"Lightning CLI/permission-denied-os-error-13",title:"Permission denied (os error 13)",description:"\x3c!--",source:"@site/references/Lightning CLI/permission-denied-os-error-13.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/permission-denied-os-error-13",permalink:"/references/Lightning CLI/permission-denied-os-error-13",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/permission-denied-os-error-13.md",tags:[{label:"permissions",permalink:"/references/tags/permissions"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Permission denied (os error 13)",slug:"permission-denied-os-error-13",hide_title:!0,tags:["permissions"]},sidebar:"defaultSidebar",previous:{title:"Keys not found",permalink:"/references/Lightning CLI/keys-not-found"},next:{title:"Uninstall Lightning CLI",permalink:"/references/Lightning CLI/uninstall-lightning-cli"}},d={},p=[{value:"Ownership and file permissions",id:"ownership-and-file-permissions",level:2},{value:"Override the TMPDIR",id:"override-the-tmpdir",level:2}],c={toc:p},m="wrapper";function u(e){let{components:n,...t}=e;return(0,i.kt)(m,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"ownership-and-file-permissions"},"Ownership and file permissions"),(0,i.kt)("p",null,"When running the Lightning CLI, the user who's in control can delegate to ",(0,i.kt)("strong",{parentName:"p"},"root")," via ",(0,i.kt)("strong",{parentName:"p"},"sudo"),". Depending on how the Fleek Networking Lightning CLI was installed, this might cause some confusion, which is better explained by reading the reference ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/keys-not-found"},"Keys not found"),", which illustrates a situation where a user gets an error message about the wrong location of a system path (keystore)."),(0,i.kt)("p",null,"Some of the reasons why the ",(0,i.kt)("inlineCode",{parentName:"p"},"Permission denied (os error 13)")," might occur are related to:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The Fleek Network Lightning CLI process trying to write to a ",(0,i.kt)("inlineCode",{parentName:"li"},".lightning")," stored in a non permited location"),(0,i.kt)("li",{parentName:"ul"},"The Fleek Network Lightning CLI process trying to write to ",(0,i.kt)("inlineCode",{parentName:"li"},"/tmp"))),(0,i.kt)("p",null,"The most common issue can be fixed by reading the section ",(0,i.kt)("a",{parentName:"p",href:"#override-the-tmpdir"},"Override the TMPDIR"),"."),(0,i.kt)("h2",{id:"override-the-tmpdir"},"Override the TMPDIR"),(0,i.kt)("p",null,"The Fleek Network Lightning process requires writing to a temporary directory. As the process requires permissions, this might fail as demonstrated by some of the output logs we have below."),(0,i.kt)("p",null,"a) A permission denied error message"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"Permission denied (os error 13)\n")),(0,i.kt)("p",null,"b) Rust panic error message which includes a permission denied"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\n")),(0,i.kt)("p",null,"c) A trace showing the path where this has failed"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},'[00007fcbe168e764] openat(AT_FDCWD, "/tmp/lightning.log", O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, 0666) = -1 EACCES (Permission denied)\n[00007fcbe168ea6f] write(2, "thread \'", 8thread \') = 8\n[00007fcbe168ea6f] write(2, "main", 4main) = 4\n[00007fcbe168ea6f] write(2, "\' panicked at \'", 15\' panicked at \') = 15\n[00007fcbe168ea6f] write(2, "called `Result::unwrap()` on an "..., 114called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }) = 114\n[00007fcbe168ea6f] write(2, "\', ", 3\', ) = 3\n')),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp")," directory should have wide permissions for all applications, but to mitigate any permission issues the user can override the system environment ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR"),". For example, the ",(0,i.kt)("inlineCode",{parentName:"p"},"installer")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"update")," scripts override ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR")," environment variable to ",(0,i.kt)("inlineCode",{parentName:"p"},"/var/tmp")," setting it in the service unit ",(0,i.kt)("inlineCode",{parentName:"p"},"Environment="),".")),(0,i.kt)("p",null,"The Lightning CLI process is aware of the environment variable TMPDIR, which the operators can override as discussed in the reference for ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/update-cli-from-source-code/#update-the-systemd-service-unit"},"Update the System service unit"),"."),(0,i.kt)("p",null,"In short, it requires you to include an ",(0,i.kt)("inlineCode",{parentName:"p"},"Environment=")," value of ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR=/var/tmp")," as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"[Service]\n...\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n")),(0,i.kt)("admonition",{title:"attention",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," service unit file presented here is a shorter version for simplicity. Do not replace your service unit file with the shorter content version presented here.")),(0,i.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}u.isMDXComponent=!0},3872:(e,n,t)=>{t.d(n,{Z:()=>i});var r=t(7294);const i=e=>{let{image:n,name:t,title:i,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:t},r.createElement("img",{src:n,alt:t}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:t},t)),r.createElement("span",{className:"title"},i),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[7147],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>h});var r=t(7294);function i(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function a(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function o(e){for(var n=1;n=0||(i[t]=e[t]);return i}(e,n);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(i[t]=e[t])}return i}var l=r.createContext({}),d=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):o(o({},n),e)),t},p=function(e){var n=d(e.components);return r.createElement(l.Provider,{value:n},e.children)},c="mdxType",m={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},u=r.forwardRef((function(e,n){var t=e.components,i=e.mdxType,a=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),c=d(t),u=i,h=c["".concat(l,".").concat(u)]||c[u]||m[u]||a;return t?r.createElement(h,o(o({ref:n},p),{},{components:t})):r.createElement(h,o({ref:n},p))}));function h(e,n){var t=arguments,i=n&&n.mdxType;if("string"==typeof e||i){var a=t.length,o=new Array(a);o[0]=u;var s={};for(var l in n)hasOwnProperty.call(n,l)&&(s[l]=n[l]);s.originalType=e,s[c]="string"==typeof e?e:i,o[1]=s;for(var d=2;d{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>p});var r=t(7462),i=(t(7294),t(3905)),a=t(3872);const o={title:"Permission denied (os error 13)",slug:"permission-denied-os-error-13",hide_title:!0,tags:["permissions"]},s=void 0,l={unversionedId:"Lightning CLI/permission-denied-os-error-13",id:"Lightning CLI/permission-denied-os-error-13",title:"Permission denied (os error 13)",description:"\x3c!--",source:"@site/references/Lightning CLI/permission-denied-os-error-13.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/permission-denied-os-error-13",permalink:"/references/Lightning CLI/permission-denied-os-error-13",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/permission-denied-os-error-13.md",tags:[{label:"permissions",permalink:"/references/tags/permissions"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Permission denied (os error 13)",slug:"permission-denied-os-error-13",hide_title:!0,tags:["permissions"]},sidebar:"defaultSidebar",previous:{title:"Keys not found",permalink:"/references/Lightning CLI/keys-not-found"},next:{title:"Uninstall Lightning CLI",permalink:"/references/Lightning CLI/uninstall-lightning-cli"}},d={},p=[{value:"Ownership and file permissions",id:"ownership-and-file-permissions",level:2},{value:"Override the TMPDIR",id:"override-the-tmpdir",level:2}],c={toc:p},m="wrapper";function u(e){let{components:n,...t}=e;return(0,i.kt)(m,(0,r.Z)({},c,t,{components:n,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"ownership-and-file-permissions"},"Ownership and file permissions"),(0,i.kt)("p",null,"When running the Lightning CLI, the user who's in control can delegate to ",(0,i.kt)("strong",{parentName:"p"},"root")," via ",(0,i.kt)("strong",{parentName:"p"},"sudo"),". Depending on how the Fleek Networking Lightning CLI was installed, this might cause some confusion, which is better explained by reading the reference ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/keys-not-found"},"Keys not found"),", which illustrates a situation where a user gets an error message about the wrong location of a system path (keystore)."),(0,i.kt)("p",null,"Some of the reasons why the ",(0,i.kt)("inlineCode",{parentName:"p"},"Permission denied (os error 13)")," might occur are related to:"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},"The Fleek Network Lightning CLI process trying to write to a ",(0,i.kt)("inlineCode",{parentName:"li"},".lightning")," stored in a non permited location"),(0,i.kt)("li",{parentName:"ul"},"The Fleek Network Lightning CLI process trying to write to ",(0,i.kt)("inlineCode",{parentName:"li"},"/tmp"))),(0,i.kt)("p",null,"The most common issue can be fixed by reading the section ",(0,i.kt)("a",{parentName:"p",href:"#override-the-tmpdir"},"Override the TMPDIR"),"."),(0,i.kt)("h2",{id:"override-the-tmpdir"},"Override the TMPDIR"),(0,i.kt)("p",null,"The Fleek Network Lightning process requires writing to a temporary directory. As the process requires permissions, this might fail as demonstrated by some of the output logs we have below."),(0,i.kt)("p",null,"a) A permission denied error message"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"Permission denied (os error 13)\n")),(0,i.kt)("p",null,"b) Rust panic error message which includes a permission denied"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\nthread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 13, kind: PermissionDenied, message: \"Permission denied\" }', core/node/src/cli.rs:181:18\nnote: run with RUST_BACKTRACE=1 environment variable to display a backtrace\n")),(0,i.kt)("p",null,"c) A trace showing the path where this has failed"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},'[00007fcbe168e764] openat(AT_FDCWD, "/tmp/lightning.log", O_WRONLY|O_CREAT|O_APPEND|O_CLOEXEC, 0666) = -1 EACCES (Permission denied)\n[00007fcbe168ea6f] write(2, "thread \'", 8thread \') = 8\n[00007fcbe168ea6f] write(2, "main", 4main) = 4\n[00007fcbe168ea6f] write(2, "\' panicked at \'", 15\' panicked at \') = 15\n[00007fcbe168ea6f] write(2, "called `Result::unwrap()` on an "..., 114called `Result::unwrap()` on an `Err` value: Os { code: 13, kind: PermissionDenied, message: "Permission denied" }) = 114\n[00007fcbe168ea6f] write(2, "\', ", 3\', ) = 3\n')),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"/tmp")," directory should have wide permissions for all applications, but to mitigate any permission issues the user can override the system environment ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR"),". For example, the ",(0,i.kt)("inlineCode",{parentName:"p"},"installer")," and ",(0,i.kt)("inlineCode",{parentName:"p"},"update")," scripts override ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR")," environment variable to ",(0,i.kt)("inlineCode",{parentName:"p"},"/var/tmp")," setting it in the service unit ",(0,i.kt)("inlineCode",{parentName:"p"},"Environment="),".")),(0,i.kt)("p",null,"The Lightning CLI process is aware of the environment variable TMPDIR, which the operators can override as discussed in the reference for ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/update-cli-from-source-code/#update-the-systemd-service-unit"},"Update the System service unit"),"."),(0,i.kt)("p",null,"In short, it requires you to include an ",(0,i.kt)("inlineCode",{parentName:"p"},"Environment=")," value of ",(0,i.kt)("inlineCode",{parentName:"p"},"TMPDIR=/var/tmp")," as follows:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"[Service]\n...\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n")),(0,i.kt)("admonition",{title:"attention",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"The ",(0,i.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," service unit file presented here is a shorter version for simplicity. Do not replace your service unit file with the shorter content version presented here.")),(0,i.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}u.isMDXComponent=!0},3872:(e,n,t)=>{t.d(n,{Z:()=>i});var r=t(7294);const i=e=>{let{image:n,name:t,title:i,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:t},r.createElement("img",{src:n,alt:t}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:t},t)),r.createElement("span",{className:"title"},i),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/29b62a39.ef6a4298.js b/assets/js/29b62a39.6fecc08b.js similarity index 98% rename from assets/js/29b62a39.ef6a4298.js rename to assets/js/29b62a39.6fecc08b.js index 67751c267..f2c5791b6 100644 --- a/assets/js/29b62a39.ef6a4298.js +++ b/assets/js/29b62a39.6fecc08b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1498],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),d=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=d(r),f=o,m=u["".concat(c,".").concat(f)]||u[f]||p[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var d=2;d{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a=r.p+"assets/images/banner-guides-cd76f6e8aac3594bb5d072a564e0e277.png",i={title:"About guides",hide_title:!0,sidebar_position:1,tags:["Guides","Help","Fleek Network"]},s=void 0,c={unversionedId:"index",id:"index",title:"About guides",description:"The guides provide step-by-step instructions and descriptions to help understand how and why you'd have to do or execute certain commands or processes.",source:"@site/guides/index.md",sourceDirName:".",slug:"/",permalink:"/guides/",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/index.md",tags:[{label:"Guides",permalink:"/guides/tags/guides"},{label:"Help",permalink:"/guides/tags/help"},{label:"Fleek Network",permalink:"/guides/tags/fleek-network"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",sidebarPosition:1,frontMatter:{title:"About guides",hide_title:!0,sidebar_position:1,tags:["Guides","Help","Fleek Network"]},sidebar:"defaultSidebar",next:{title:"Getting Started",permalink:"/guides/Node Operators/getting-started"}},d={},l=[],u={toc:l},p="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("img",{className:"banner",src:a}),(0,o.kt)("p",null,"The guides provide step-by-step instructions and descriptions to help understand how and why you'd have to do or execute certain commands or processes."),(0,o.kt)("p",null,"It differs from the ",(0,o.kt)("a",{parentName:"p",href:"/references"},"references")," documentation which serves as a quick direct breakdown of commands and processes without much explanation, as the name implies."),(0,o.kt)("p",null,"To start, find guides by consulting the available categories to locate the content on the sidebar. Our guides are also available as a result when using the search feature located at the very top of the documentation site."))}f.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1498],{3905:(e,t,r)=>{r.d(t,{Zo:()=>l,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var c=n.createContext({}),d=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},l=function(e){var t=d(e.components);return n.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=d(r),f=o,m=u["".concat(c,".").concat(f)]||u[f]||p[f]||a;return r?n.createElement(m,i(i({ref:t},l),{},{components:r})):n.createElement(m,i({ref:t},l))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,i=new Array(a);i[0]=f;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var d=2;d{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>f,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a=r.p+"assets/images/banner-guides-cd76f6e8aac3594bb5d072a564e0e277.png",i={title:"About guides",hide_title:!0,sidebar_position:1,tags:["Guides","Help","Fleek Network"]},s=void 0,c={unversionedId:"index",id:"index",title:"About guides",description:"The guides provide step-by-step instructions and descriptions to help understand how and why you'd have to do or execute certain commands or processes.",source:"@site/guides/index.md",sourceDirName:".",slug:"/",permalink:"/guides/",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/guides/index.md",tags:[{label:"Guides",permalink:"/guides/tags/guides"},{label:"Help",permalink:"/guides/tags/help"},{label:"Fleek Network",permalink:"/guides/tags/fleek-network"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",sidebarPosition:1,frontMatter:{title:"About guides",hide_title:!0,sidebar_position:1,tags:["Guides","Help","Fleek Network"]},sidebar:"defaultSidebar",next:{title:"Getting Started",permalink:"/guides/Node Operators/getting-started"}},d={},l=[],u={toc:l},p="wrapper";function f(e){let{components:t,...r}=e;return(0,o.kt)(p,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("img",{className:"banner",src:a}),(0,o.kt)("p",null,"The guides provide step-by-step instructions and descriptions to help understand how and why you'd have to do or execute certain commands or processes."),(0,o.kt)("p",null,"It differs from the ",(0,o.kt)("a",{parentName:"p",href:"/references"},"references")," documentation which serves as a quick direct breakdown of commands and processes without much explanation, as the name implies."),(0,o.kt)("p",null,"To start, find guides by consulting the available categories to locate the content on the sidebar. Our guides are also available as a result when using the search feature located at the very top of the documentation site."))}f.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2baa5a9a.4aef429e.js b/assets/js/2baa5a9a.4aef429e.js deleted file mode 100644 index fbde2f0cd..000000000 --- a/assets/js/2baa5a9a.4aef429e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[9021],{8704:e=>{e.exports=JSON.parse('{"label":"configuration","permalink":"/guides/tags/configuration","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file diff --git a/assets/js/2baa5a9a.ea74f963.js b/assets/js/2baa5a9a.ea74f963.js new file mode 100644 index 000000000..1a7492802 --- /dev/null +++ b/assets/js/2baa5a9a.ea74f963.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[9021],{8704:e=>{e.exports=JSON.parse('{"label":"configuration","permalink":"/guides/tags/configuration","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/transfering-setup-ownership"}]}')}}]); \ No newline at end of file diff --git a/assets/js/40aeb86f.fbf1555a.js b/assets/js/40aeb86f.4a80f588.js similarity index 99% rename from assets/js/40aeb86f.fbf1555a.js rename to assets/js/40aeb86f.4a80f588.js index c8a791e08..629dba65a 100644 --- a/assets/js/40aeb86f.fbf1555a.js +++ b/assets/js/40aeb86f.4a80f588.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4402],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),h=p(n),d=o,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||r;return n?a.createElement(m,l(l({ref:t},c),{},{components:n})):a.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[h]="string"==typeof e?e:o,l[1]=i;for(var p=2;p{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,o.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,o.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,o.kt)("p",null,"Here's an example of how to do it using ",(0,o.kt)("strong",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,o.kt)("p",null,"For example, if your username is ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("p",null,"Once modified, you can run a ",(0,o.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,o.kt)("p",null,"For our example where we opted in for the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{title:"Warning",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}i.isMDXComponent=!0},3813:(e,t,n)=>{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The flag ",(0,o.kt)("inlineCode",{parentName:"p"},"-c")," in the ",(0,o.kt)("inlineCode",{parentName:"p"},"lightning.service")," ",(0,o.kt)("strong",{parentName:"p"},"ExecStart"),", is to provide the toml configuration file path e.g. defaults to ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.lightning/config.toml"),". This is to avoid the path being determined dynamically (given path base ~ or $HOME), as users might control the systemctl service as a ",(0,o.kt)("strong",{parentName:"p"},"user")," or ",(0,o.kt)("strong",{parentName:"p"},"sudoer"),". For example, a ",(0,o.kt)("strong",{parentName:"p"},"sudoer")," would have the ",(0,o.kt)("strong",{parentName:"p"},"configuration")," set to ",(0,o.kt)("inlineCode",{parentName:"p"},"/root/.lightning/config.toml")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/username/.lightning/config.toml")," depending on using ",(0,o.kt)("strong",{parentName:"p"},"sudo")," which might cause some confusion to some users.")))}i.isMDXComponent=!0},2300:(e,t,n)=>{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"You should be following the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user-1"},"create a user")," recommendation. For our example, we have the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),"."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you have chosen a different username, replace ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," by the correct username you have selected.")),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("p",null,"Find and replace all instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"~")," in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml"),". Here's an example using ",(0,o.kt)("inlineCode",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," example below is a shorter version of what you'll encounter, yours might look different. We do this to keep the guide simple to read. Do not copy and replace with the version demonstrated here.")),(0,o.kt)("p",null,"Once changed, all the instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"~/")," should be replaced by your user path e.g. ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/"),". For our example, the output would look like the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "/home/lgtn/.lightning/data/app_db"\n\n[consensus]\nstore_path = "/home/lgtn/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "/home/lgtn/.lightning/blockstore"\n\n[resolver]\nstore_path = "/home/lgtn/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "/home/lgtn/.lightning/keystore/consensus.pem"\nnode_key_path = "/home/lgtn/.lightning/keystore/node.pem"\n')))}i.isMDXComponent=!0},1054:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>k,frontMatter:()=>p,metadata:()=>h,toc:()=>d});var a=n(7462),o=(n(7294),n(3905)),r=n(3872),l=n(2300),i=n(3813),s=n(3242);const p={title:"Update CLI from source code",slug:"update-cli-from-source-code",hide_title:!0,tags:["references","help","update","upgrade","fix"]},c=void 0,h={unversionedId:"Lightning CLI/update-cli-from-source-code",id:"Lightning CLI/update-cli-from-source-code",title:"Update CLI from source code",description:"\x3c!--",source:"@site/references/Lightning CLI/update-cli-from-source-code.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/update-cli-from-source-code",permalink:"/references/Lightning CLI/update-cli-from-source-code",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/update-cli-from-source-code.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"update",permalink:"/references/tags/update"},{label:"upgrade",permalink:"/references/tags/upgrade"},{label:"fix",permalink:"/references/tags/fix"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Update CLI from source code",slug:"update-cli-from-source-code",hide_title:!0,tags:["references","help","update","upgrade","fix"]},sidebar:"defaultSidebar",previous:{title:"Uninstall Lightning CLI",permalink:"/references/Lightning CLI/uninstall-lightning-cli"},next:{title:"Shutting down persistance",permalink:"/references/Systemd/shutting-down-persistance"}},u={},d=[{value:"Switch to the installation user",id:"switch-to-the-installation-user",level:2},{value:"Change directory to the source code",id:"change-directory-to-the-source-code",level:2},{value:"Checkout to branch",id:"checkout-to-branch",level:2},{value:"Pull the latest changes",id:"pull-the-latest-changes",level:2},{value:"Build binary from the source",id:"build-binary-from-the-source",level:2},{value:"Update the symlink",id:"update-the-symlink",level:2},{value:"Set user path in config.toml",id:"set-user-path-in-configtoml",level:2},{value:"Update the systemd service unit",id:"update-the-systemd-service-unit",level:2},{value:"Clear the data",id:"clear-the-data",level:2},{value:"Update the config.toml with user home path",id:"update-the-configtoml-with-user-home-path",level:2},{value:"Restart the service",id:"restart-the-service",level:2},{value:"Health checkup",id:"health-checkup",level:2}],m={toc:d},g="wrapper";function k(e){let{components:t,...n}=e;return(0,o.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Although the step-by-step instructions described here are simple to follow, this process is available as an automated script. To use it execute the following command in your server terminal and follow the instructions:"),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"curl -sS https://get.fleek.network/update | bash\n"))),(0,o.kt)("h2",{id:"switch-to-the-installation-user"},"Switch to the installation user"),(0,o.kt)("p",null,"Switch to the username you've used throughout the installation process."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"su \n")),(0,o.kt)("p",null,"For example, if you used the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," it'll look like the following command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"su lgtn\n")),(0,o.kt)("h2",{id:"change-directory-to-the-source-code"},"Change directory to the source code"),(0,o.kt)("p",null,"If you have installed it via the recommended process or instructions, then the default location where the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"source code")," is stored is ",(0,o.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~/fleek-network/lightning\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Notice that we use ",(0,o.kt)("inlineCode",{parentName:"p"},"~"),", which refers to ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME"),". You must use the username used for the installation process. For example, on ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/requirements#server"},"Ubuntu")," if you use the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),", the pathname for ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn"),".")),(0,o.kt)("h2",{id:"checkout-to-branch"},"Checkout to branch"),(0,o.kt)("p",null,"Make sure that you are checked in to the correct branch. For the current testnet phase that'd be ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),". If you use any other branch name, your node will not function correctly. Use the branch name ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git checkout testnet-alpha-0\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We try to update our documentation promptly but sometimes are a bit behind on any changes we might make in real-time. If you find any typos, such as the wrong branch name, help us by letting us know! Find us in Fleek Network section of our ",(0,o.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"Discord"),".")),(0,o.kt)("h2",{id:"pull-the-latest-changes"},"Pull the latest changes"),(0,o.kt)("p",null,"Before make sure that you stash or clear any changes you may have in the working directory, as otherwise, ",(0,o.kt)("inlineCode",{parentName:"p"},"git")," will let you know about local changes\u2013if you'd like to learn more about it read the ",(0,o.kt)("a",{parentName:"p",href:"https://git-scm.com/docs/git-stash"},"git stash document"),"."),(0,o.kt)("p",null,"A quick way to clean is to ",(0,o.kt)("inlineCode",{parentName:"p"},"stash")," the changes, for example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git stash \n")),(0,o.kt)("p",null,"To pull the latest changes use the ",(0,o.kt)("inlineCode",{parentName:"p"},"git pull")," command, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git pull origin testnet-alpha-0\n")),(0,o.kt)("p",null,"Alternatively, to have to stash and pull, you can reset the repository to the origin."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git fetch origin testnet-alpha-0\ngit reset --hard origin/testnet-alpha-0\ngit clean -f\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We are using the branch named ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),", which is specific to the early testnet launch. Change to the correct branch name according to needs. For example, in the future the mainnet version will go on branch name ",(0,o.kt)("inlineCode",{parentName:"p"},"main"),".")),(0,o.kt)("h2",{id:"build-binary-from-the-source"},"Build binary from the source"),(0,o.kt)("p",null,"To build the binary from the source code, we execute the cargo build command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cargo +stable build --release\n")),(0,o.kt)("h2",{id:"update-the-symlink"},"Update the symlink"),(0,o.kt)("p",null,"Start by removing the existing one:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sudo rm -f "/usr/local/bin/lgtn"\n')),(0,o.kt)("p",null,"Create a new symlink that links the new build binary to ",(0,o.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn"),", as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo ln -s ~/fleek-network/lightning/target/release/lightning-node /usr/local/bin/lgtn\n")),(0,o.kt)("h2",{id:"set-user-path-in-configtoml"},"Set user path in config.toml"),(0,o.kt)(l.ZP,{mdxType:"SetUserPathInConfigToml"}),(0,o.kt)("h2",{id:"update-the-systemd-service-unit"},"Update the systemd service unit"),(0,o.kt)("p",null,"Open and edit the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," file."),(0,o.kt)("p",null,"1) Replace ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with the username. For example, in the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"documentation")," we use the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),"."),(0,o.kt)("p",null,"2) Make sure that the ",(0,o.kt)("inlineCode",{parentName:"p"},"ExecStart")," is set correctly"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)(i.ZP,{mdxType:"NoteExecStartFlagCConfigPath"}),(0,o.kt)("p",null,"When complete make sure the file is saved. Followed by a systemctl daemon reload:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,o.kt)("h2",{id:"clear-the-data"},"Clear the data"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"rm -rf ~/.lightning/data\n")),(0,o.kt)("p",null,"Depending on how you control the system, this might need ",(0,o.kt)("strong",{parentName:"p"},"sudo"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -rf ~/.lightning/data\n")),(0,o.kt)("h2",{id:"update-the-configtoml-with-user-home-path"},"Update the ",(0,o.kt)("inlineCode",{parentName:"h2"},"config.toml")," with user home path"),(0,o.kt)(s.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,o.kt)("h2",{id:"restart-the-service"},"Restart the service"),(0,o.kt)("p",null,"Once the cargo build process is completed, you have to restart the service. We're assuming you are using non-root user as ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"recommended"),", you won't use ",(0,o.kt)("strong",{parentName:"p"},"sudo")," to start the service. The command will look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl restart lightning\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you have installed the Fleek Network lightning manually, the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"installation instructions")," recommended setting up a systemd service for the Fleek Network process. If you haven't, you're advised to check the instructions provided.")),(0,o.kt)("h2",{id:"health-checkup"},"Health checkup"),(0,o.kt)("p",null,"Do a quick health check by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'curl -w "\\p" localhost:4069/health\n')),(0,o.kt)("p",null,"If successful, you should get the response ",(0,o.kt)("inlineCode",{parentName:"p"},"OK"),", as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"OK\n")),(0,o.kt)(r.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}k.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294);const o=e=>{let{image:t,name:n,title:o,url:r}=e;return a.createElement("section",{className:"author_card"},a.createElement("div",null,a.createElement("span",{className:"avatar"},a.createElement("a",{href:r,target:"_blank",alt:n},a.createElement("img",{src:t,alt:n}))),a.createElement("div",null,a.createElement("span",{className:"name"},a.createElement("a",{href:r,target:"_blank",alt:n},n)),a.createElement("span",{className:"title"},o),a.createElement("span",{className:"discord"},"Got questions? Find us on ",a.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4402],{3905:(e,t,n)=>{n.d(t,{Zo:()=>c,kt:()=>m});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function l(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var s=a.createContext({}),p=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):l(l({},t),e)),n},c=function(e){var t=p(e.components);return a.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},d=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,r=e.originalType,s=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),h=p(n),d=o,m=h["".concat(s,".").concat(d)]||h[d]||u[d]||r;return n?a.createElement(m,l(l({ref:t},c),{},{components:n})):a.createElement(m,l({ref:t},c))}));function m(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var r=n.length,l=new Array(r);l[0]=d;var i={};for(var s in t)hasOwnProperty.call(t,s)&&(i[s]=t[s]);i.originalType=e,i[h]="string"==typeof e?e:o,l[1]=i;for(var p=2;p{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,o.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,o.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,o.kt)("p",null,"Here's an example of how to do it using ",(0,o.kt)("strong",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,o.kt)("p",null,"For example, if your username is ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("p",null,"Once modified, you can run a ",(0,o.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,o.kt)("p",null,"For our example where we opted in for the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{title:"Warning",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}i.isMDXComponent=!0},3813:(e,t,n)=>{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"The flag ",(0,o.kt)("inlineCode",{parentName:"p"},"-c")," in the ",(0,o.kt)("inlineCode",{parentName:"p"},"lightning.service")," ",(0,o.kt)("strong",{parentName:"p"},"ExecStart"),", is to provide the toml configuration file path e.g. defaults to ",(0,o.kt)("inlineCode",{parentName:"p"},"~/.lightning/config.toml"),". This is to avoid the path being determined dynamically (given path base ~ or $HOME), as users might control the systemctl service as a ",(0,o.kt)("strong",{parentName:"p"},"user")," or ",(0,o.kt)("strong",{parentName:"p"},"sudoer"),". For example, a ",(0,o.kt)("strong",{parentName:"p"},"sudoer")," would have the ",(0,o.kt)("strong",{parentName:"p"},"configuration")," set to ",(0,o.kt)("inlineCode",{parentName:"p"},"/root/.lightning/config.toml")," or ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/username/.lightning/config.toml")," depending on using ",(0,o.kt)("strong",{parentName:"p"},"sudo")," which might cause some confusion to some users.")))}i.isMDXComponent=!0},2300:(e,t,n)=>{n.d(t,{ZP:()=>i});var a=n(7462),o=(n(7294),n(3905));const r={toc:[]},l="wrapper";function i(e){let{components:t,...n}=e;return(0,o.kt)(l,(0,a.Z)({},r,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"You should be following the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user-1"},"create a user")," recommendation. For our example, we have the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),"."),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you have chosen a different username, replace ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," by the correct username you have selected.")),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("p",null,"Find and replace all instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"~")," in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml"),". Here's an example using ",(0,o.kt)("inlineCode",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"The ",(0,o.kt)("inlineCode",{parentName:"p"},"config.toml")," example below is a shorter version of what you'll encounter, yours might look different. We do this to keep the guide simple to read. Do not copy and replace with the version demonstrated here.")),(0,o.kt)("p",null,"Once changed, all the instances of ",(0,o.kt)("inlineCode",{parentName:"p"},"~/")," should be replaced by your user path e.g. ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/"),". For our example, the output would look like the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "/home/lgtn/.lightning/data/app_db"\n\n[consensus]\nstore_path = "/home/lgtn/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "/home/lgtn/.lightning/blockstore"\n\n[resolver]\nstore_path = "/home/lgtn/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "/home/lgtn/.lightning/keystore/consensus.pem"\nnode_key_path = "/home/lgtn/.lightning/keystore/node.pem"\n')))}i.isMDXComponent=!0},1054:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>u,contentTitle:()=>c,default:()=>k,frontMatter:()=>p,metadata:()=>h,toc:()=>d});var a=n(7462),o=(n(7294),n(3905)),r=n(3872),l=n(2300),i=n(3813),s=n(3242);const p={title:"Update CLI from source code",slug:"update-cli-from-source-code",hide_title:!0,tags:["references","help","update","upgrade","fix"]},c=void 0,h={unversionedId:"Lightning CLI/update-cli-from-source-code",id:"Lightning CLI/update-cli-from-source-code",title:"Update CLI from source code",description:"\x3c!--",source:"@site/references/Lightning CLI/update-cli-from-source-code.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/update-cli-from-source-code",permalink:"/references/Lightning CLI/update-cli-from-source-code",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/update-cli-from-source-code.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"update",permalink:"/references/tags/update"},{label:"upgrade",permalink:"/references/tags/upgrade"},{label:"fix",permalink:"/references/tags/fix"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Update CLI from source code",slug:"update-cli-from-source-code",hide_title:!0,tags:["references","help","update","upgrade","fix"]},sidebar:"defaultSidebar",previous:{title:"Uninstall Lightning CLI",permalink:"/references/Lightning CLI/uninstall-lightning-cli"},next:{title:"Shutting down persistance",permalink:"/references/Systemd/shutting-down-persistance"}},u={},d=[{value:"Switch to the installation user",id:"switch-to-the-installation-user",level:2},{value:"Change directory to the source code",id:"change-directory-to-the-source-code",level:2},{value:"Checkout to branch",id:"checkout-to-branch",level:2},{value:"Pull the latest changes",id:"pull-the-latest-changes",level:2},{value:"Build binary from the source",id:"build-binary-from-the-source",level:2},{value:"Update the symlink",id:"update-the-symlink",level:2},{value:"Set user path in config.toml",id:"set-user-path-in-configtoml",level:2},{value:"Update the systemd service unit",id:"update-the-systemd-service-unit",level:2},{value:"Clear the data",id:"clear-the-data",level:2},{value:"Update the config.toml with user home path",id:"update-the-configtoml-with-user-home-path",level:2},{value:"Restart the service",id:"restart-the-service",level:2},{value:"Health checkup",id:"health-checkup",level:2}],m={toc:d},g="wrapper";function k(e){let{components:t,...n}=e;return(0,o.kt)(g,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Although the step-by-step instructions described here are simple to follow, this process is available as an automated script. To use it execute the following command in your server terminal and follow the instructions:"),(0,o.kt)("pre",{parentName:"admonition"},(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"curl -sS https://get.fleek.network/update | bash\n"))),(0,o.kt)("h2",{id:"switch-to-the-installation-user"},"Switch to the installation user"),(0,o.kt)("p",null,"Switch to the username you've used throughout the installation process."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"su \n")),(0,o.kt)("p",null,"For example, if you used the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," it'll look like the following command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"su lgtn\n")),(0,o.kt)("h2",{id:"change-directory-to-the-source-code"},"Change directory to the source code"),(0,o.kt)("p",null,"If you have installed it via the recommended process or instructions, then the default location where the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"source code")," is stored is ",(0,o.kt)("inlineCode",{parentName:"p"},"~/fleek-network/lightning"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~/fleek-network/lightning\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Notice that we use ",(0,o.kt)("inlineCode",{parentName:"p"},"~"),", which refers to ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME"),". You must use the username used for the installation process. For example, on ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/requirements#server"},"Ubuntu")," if you use the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),", the pathname for ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME")," is ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn"),".")),(0,o.kt)("h2",{id:"checkout-to-branch"},"Checkout to branch"),(0,o.kt)("p",null,"Make sure that you are checked in to the correct branch. For the current testnet phase that'd be ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),". If you use any other branch name, your node will not function correctly. Use the branch name ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git checkout testnet-alpha-0\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We try to update our documentation promptly but sometimes are a bit behind on any changes we might make in real-time. If you find any typos, such as the wrong branch name, help us by letting us know! Find us in Fleek Network section of our ",(0,o.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"Discord"),".")),(0,o.kt)("h2",{id:"pull-the-latest-changes"},"Pull the latest changes"),(0,o.kt)("p",null,"Before make sure that you stash or clear any changes you may have in the working directory, as otherwise, ",(0,o.kt)("inlineCode",{parentName:"p"},"git")," will let you know about local changes\u2013if you'd like to learn more about it read the ",(0,o.kt)("a",{parentName:"p",href:"https://git-scm.com/docs/git-stash"},"git stash document"),"."),(0,o.kt)("p",null,"A quick way to clean is to ",(0,o.kt)("inlineCode",{parentName:"p"},"stash")," the changes, for example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git stash \n")),(0,o.kt)("p",null,"To pull the latest changes use the ",(0,o.kt)("inlineCode",{parentName:"p"},"git pull")," command, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git pull origin testnet-alpha-0\n")),(0,o.kt)("p",null,"Alternatively, to have to stash and pull, you can reset the repository to the origin."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"git fetch origin testnet-alpha-0\ngit reset --hard origin/testnet-alpha-0\ngit clean -f\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We are using the branch named ",(0,o.kt)("inlineCode",{parentName:"p"},"testnet-alpha-0"),", which is specific to the early testnet launch. Change to the correct branch name according to needs. For example, in the future the mainnet version will go on branch name ",(0,o.kt)("inlineCode",{parentName:"p"},"main"),".")),(0,o.kt)("h2",{id:"build-binary-from-the-source"},"Build binary from the source"),(0,o.kt)("p",null,"To build the binary from the source code, we execute the cargo build command:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cargo +stable build --release\n")),(0,o.kt)("h2",{id:"update-the-symlink"},"Update the symlink"),(0,o.kt)("p",null,"Start by removing the existing one:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sudo rm -f "/usr/local/bin/lgtn"\n')),(0,o.kt)("p",null,"Create a new symlink that links the new build binary to ",(0,o.kt)("inlineCode",{parentName:"p"},"/usr/local/bin/lgtn"),", as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo ln -s ~/fleek-network/lightning/target/release/lightning-node /usr/local/bin/lgtn\n")),(0,o.kt)("h2",{id:"set-user-path-in-configtoml"},"Set user path in config.toml"),(0,o.kt)(l.ZP,{mdxType:"SetUserPathInConfigToml"}),(0,o.kt)("h2",{id:"update-the-systemd-service-unit"},"Update the systemd service unit"),(0,o.kt)("p",null,"Open and edit the ",(0,o.kt)("inlineCode",{parentName:"p"},"/etc/systemd/system/lightning.service")," file."),(0,o.kt)("p",null,"1) Replace ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with the username. For example, in the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"documentation")," we use the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn"),"."),(0,o.kt)("p",null,"2) Make sure that the ",(0,o.kt)("inlineCode",{parentName:"p"},"ExecStart")," is set correctly"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)(i.ZP,{mdxType:"NoteExecStartFlagCConfigPath"}),(0,o.kt)("p",null,"When complete make sure the file is saved. Followed by a systemctl daemon reload:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,o.kt)("h2",{id:"clear-the-data"},"Clear the data"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"rm -rf ~/.lightning/data\n")),(0,o.kt)("p",null,"Depending on how you control the system, this might need ",(0,o.kt)("strong",{parentName:"p"},"sudo"),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -rf ~/.lightning/data\n")),(0,o.kt)("h2",{id:"update-the-configtoml-with-user-home-path"},"Update the ",(0,o.kt)("inlineCode",{parentName:"h2"},"config.toml")," with user home path"),(0,o.kt)(s.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,o.kt)("h2",{id:"restart-the-service"},"Restart the service"),(0,o.kt)("p",null,"Once the cargo build process is completed, you have to restart the service. We're assuming you are using non-root user as ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"recommended"),", you won't use ",(0,o.kt)("strong",{parentName:"p"},"sudo")," to start the service. The command will look as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl restart lightning\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"If you have installed the Fleek Network lightning manually, the ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"installation instructions")," recommended setting up a systemd service for the Fleek Network process. If you haven't, you're advised to check the instructions provided.")),(0,o.kt)("h2",{id:"health-checkup"},"Health checkup"),(0,o.kt)("p",null,"Do a quick health check by running:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'curl -w "\\p" localhost:4069/health\n')),(0,o.kt)("p",null,"If successful, you should get the response ",(0,o.kt)("inlineCode",{parentName:"p"},"OK"),", as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"OK\n")),(0,o.kt)(r.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}k.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>o});var a=n(7294);const o=e=>{let{image:t,name:n,title:o,url:r}=e;return a.createElement("section",{className:"author_card"},a.createElement("div",null,a.createElement("span",{className:"avatar"},a.createElement("a",{href:r,target:"_blank",alt:n},a.createElement("img",{src:t,alt:n}))),a.createElement("div",null,a.createElement("span",{className:"name"},a.createElement("a",{href:r,target:"_blank",alt:n},n)),a.createElement("span",{className:"title"},o),a.createElement("span",{className:"discord"},"Got questions? Find us on ",a.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/4d7007b2.d0439b6b.js b/assets/js/4d7007b2.5d79f29d.js similarity index 98% rename from assets/js/4d7007b2.d0439b6b.js rename to assets/js/4d7007b2.5d79f29d.js index 3a01f2e8d..8356f9e86 100644 --- a/assets/js/4d7007b2.d0439b6b.js +++ b/assets/js/4d7007b2.5d79f29d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6272],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(s,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i=r.p+"assets/images/banner-references-a0368a847f1d60e338779105f44a9e9a.png",a={title:"About references",hide_title:!0,sidebar_position:1,tags:["References","Help"]},c=void 0,s={unversionedId:"index",id:"index",title:"About references",description:"The references provide concise instructions to interface with the system, broken down into commands or small pieces for quick reference.",source:"@site/references/index.md",sourceDirName:".",slug:"/",permalink:"/references/",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/index.md",tags:[{label:"References",permalink:"/references/tags/references"},{label:"Help",permalink:"/references/tags/help"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",sidebarPosition:1,frontMatter:{title:"About references",hide_title:!0,sidebar_position:1,tags:["References","Help"]},sidebar:"defaultSidebar",next:{title:"Error linking with cc",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1"}},l={},p=[],f={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("img",{className:"banner",src:i}),(0,o.kt)("p",null,"The references provide concise instructions to interface with the system, broken down into commands or small pieces for quick reference."),(0,o.kt)("p",null,"It differs from ",(0,o.kt)("a",{parentName:"p",href:"/guides"},"Guides")," which is more descriptive or verbose when providing instructions and how-to's."),(0,o.kt)("p",null,"To start, find references by consulting the available categories to locate the appropriate content on the sidebar. Our references are also available as a result when using the search feature located at the very top of the documentation site."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6272],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var s=n.createContext({}),l=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=l(e.components);return n.createElement(s.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,i=e.originalType,s=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),f=l(r),d=o,m=f["".concat(s,".").concat(d)]||f[d]||u[d]||i;return r?n.createElement(m,a(a({ref:t},p),{},{components:r})):n.createElement(m,a({ref:t},p))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var i=r.length,a=new Array(i);a[0]=d;var c={};for(var s in t)hasOwnProperty.call(t,s)&&(c[s]=t[s]);c.originalType=e,c[f]="string"==typeof e?e:o,a[1]=c;for(var l=2;l{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const i=r.p+"assets/images/banner-references-a0368a847f1d60e338779105f44a9e9a.png",a={title:"About references",hide_title:!0,sidebar_position:1,tags:["References","Help"]},c=void 0,s={unversionedId:"index",id:"index",title:"About references",description:"The references provide concise instructions to interface with the system, broken down into commands or small pieces for quick reference.",source:"@site/references/index.md",sourceDirName:".",slug:"/",permalink:"/references/",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/index.md",tags:[{label:"References",permalink:"/references/tags/references"},{label:"Help",permalink:"/references/tags/help"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",sidebarPosition:1,frontMatter:{title:"About references",hide_title:!0,sidebar_position:1,tags:["References","Help"]},sidebar:"defaultSidebar",next:{title:"Error linking with cc",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1"}},l={},p=[],f={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},f,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("img",{className:"banner",src:i}),(0,o.kt)("p",null,"The references provide concise instructions to interface with the system, broken down into commands or small pieces for quick reference."),(0,o.kt)("p",null,"It differs from ",(0,o.kt)("a",{parentName:"p",href:"/guides"},"Guides")," which is more descriptive or verbose when providing instructions and how-to's."),(0,o.kt)("p",null,"To start, find references by consulting the available categories to locate the appropriate content on the sidebar. Our references are also available as a result when using the search feature located at the very top of the documentation site."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/507ab7d0.e46e86fc.js b/assets/js/507ab7d0.e46e86fc.js deleted file mode 100644 index bafb7f430..000000000 --- a/assets/js/507ab7d0.e46e86fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6128],{1618:e=>{e.exports=JSON.parse('{"label":"migration","permalink":"/guides/tags/migration","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file diff --git a/assets/js/5b6134d1.49400344.js b/assets/js/5b6134d1.4d6a6b20.js similarity index 99% rename from assets/js/5b6134d1.49400344.js rename to assets/js/5b6134d1.4d6a6b20.js index e86a3c6d2..70ea8a130 100644 --- a/assets/js/5b6134d1.49400344.js +++ b/assets/js/5b6134d1.4d6a6b20.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[9752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>h,kt:()=>c});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},h=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=p(n),g=o,c=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return n?r.createElement(c,i(i({ref:t},h),{},{components:n})):r.createElement(c,i({ref:t},h))}));function c(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.d(t,{ZP:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,o.kt)(i,(0,r.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,o.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,o.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,o.kt)("p",null,"Here's an example of how to do it using ",(0,o.kt)("strong",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,o.kt)("p",null,"For example, if your username is ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("p",null,"Once modified, you can run a ",(0,o.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,o.kt)("p",null,"For our example where we opted in for the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{title:"Warning",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}s.isMDXComponent=!0},5852:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>c,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var r=n(7462),o=(n(7294),n(3905)),a=n(3872),i=n(3242);const s={title:"File permissions and Ownership",slug:"file-permissions-and-ownership",hide_title:!0,tags:["ownership","file permissions","sudoer","root"]},l=void 0,p={unversionedId:"Lightning CLI/file-permissions-and-ownership",id:"Lightning CLI/file-permissions-and-ownership",title:"File permissions and Ownership",description:"\x3c!--",source:"@site/references/Lightning CLI/file-permissions-and-ownership.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/file-permissions-and-ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/file-permissions-and-ownership.md",tags:[{label:"ownership",permalink:"/references/tags/ownership"},{label:"file permissions",permalink:"/references/tags/file-permissions"},{label:"sudoer",permalink:"/references/tags/sudoer"},{label:"root",permalink:"/references/tags/root"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"File permissions and Ownership",slug:"file-permissions-and-ownership",hide_title:!0,tags:["ownership","file permissions","sudoer","root"]},sidebar:"defaultSidebar",previous:{title:"Error linking with cc",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1"},next:{title:"Keys not found",permalink:"/references/Lightning CLI/keys-not-found"}},h={},d=[{value:"Ownership",id:"ownership",level:2},{value:"Using sudo to delegate permissions",id:"using-sudo-to-delegate-permissions",level:2},{value:"User $HOME directory",id:"user-home-directory",level:2},{value:"Set the locations of the user paths",id:"set-the-locations-of-the-user-paths",level:2},{value:"Set the configuration flag -c on the service unit file",id:"set-the-configuration-flag--c-on-the-service-unit-file",level:2}],u={toc:d},g="wrapper";function c(e){let{components:t,...n}=e;return(0,o.kt)(g,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"ownership"},"Ownership"),(0,o.kt)("p",null,"The user who installs the Fleek Network Lightning CLI matters, as it can own or delegate ownership of the dependencies and applications being installed."),(0,o.kt)("p",null,"For example, if you have followed the install document recommendations and have:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Created a user ",(0,o.kt)("strong",{parentName:"li"},"lgtn")),(0,o.kt)("li",{parentName:"ul"},"Switched to the user ",(0,o.kt)("strong",{parentName:"li"},"lgtn")),(0,o.kt)("li",{parentName:"ul"},"Executed the installation process as ",(0,o.kt)("strong",{parentName:"li"},"lgtn")," ")),(0,o.kt)("p",null,"You'll find that it owns the following directories under the user home (/home/lgtn):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 10:27 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 12:29 .cargo\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 6 lgtn lgtn 4096 Sep 11 12:29 .rustup\ndrwxrwxr-x 3 lgtn lgtn 4096 Sep 11 12:28 fleek-network\n")),(0,o.kt)("p",null,"Above, we have the listing properties set as ",(0,o.kt)("strong",{parentName:"p"},"drwxrwxr-x")," and the ownership ",(0,o.kt)("strong",{parentName:"p"},"lgtn:lgtn"),"."),(0,o.kt)("p",null,"On the other hand, if you have done the installation process as ",(0,o.kt)("strong",{parentName:"p"},"root")," superuser, you'll find that:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The location of the directories and files goes under the ",(0,o.kt)("inlineCode",{parentName:"li"},"/root")," pathname"),(0,o.kt)("li",{parentName:"ul"},"The ownership is set to ",(0,o.kt)("strong",{parentName:"li"},"root:root"))),(0,o.kt)("p",null,"Learn more about ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions"},"file permissions")," from the ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/"},"Linux Foundation"),"."),(0,o.kt)("p",null,"To learn more about file permission on Linux, read the ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions"},"Understanding Linux File Permissions"),"."),(0,o.kt)("h2",{id:"using-sudo-to-delegate-permissions"},"Using sudo to delegate permissions"),(0,o.kt)("p",null,"Consider file ownership and permissions to understand where the keystore is located. Take close attention when executing commands as an admin\u2013with or without ",(0,o.kt)("strong",{parentName:"p"},"super user")," (root) or ",(0,o.kt)("strong",{parentName:"p"},"sudo"),"."),(0,o.kt)("p",null,"If a command is executed without ",(0,o.kt)("strong",{parentName:"p"},"sudo")," then the generated output goes onto the ",(0,o.kt)("strong",{parentName:"p"},"user")," home."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn keys generate\n")),(0,o.kt)("p",null,"Resulting in having the ",(0,o.kt)("strong",{parentName:"p"},"keystore")," saved onto ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/username/.lightning/keystore"),"."),(0,o.kt)("p",null,"On the other hand, if a command is executed with ",(0,o.kt)("strong",{parentName:"p"},"sudo")," then the generated output is delegated to ",(0,o.kt)("strong",{parentName:"p"},"root")," directory."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo lgtn keys generate\n")),(0,o.kt)("p",null,"Resulting in having the ",(0,o.kt)("strong",{parentName:"p"},"keystore")," saved onto ",(0,o.kt)("inlineCode",{parentName:"p"},"/root/.lightning/keystore"),"."),(0,o.kt)("h2",{id:"user-home-directory"},"User $HOME directory"),(0,o.kt)("p",null,"The home directory is a directory that contains the personal files of a particular user of the system. On Linux, the ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME")," environment variable is set by the login program, which sets the user `$HOME`` accordingly. A user's home goes by the username, the user who's logged in."),(0,o.kt)("p",null,"For this reason, a user can change to the home directory by executing:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd $HOME\n")),(0,o.kt)("p",null,"A shorthand allows a user to refer to their home directory simply as ",(0,o.kt)("inlineCode",{parentName:"p"},"~")," (tilde), as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We can find that the HOME or ~ (tilde) is highly dependent on the user who's logged in. Since we know that the user might delegate to ",(0,o.kt)("strong",{parentName:"p"},"root")," by the usage of ",(0,o.kt)("strong",{parentName:"p"},"sudo"),", this can help troubleshoot and explain the location of our files e.g. the keystore. In the section ",(0,o.kt)("a",{parentName:"p",href:"#set-the-locations-of-the-user-paths"},"Set the locations of the user paths"),", we learn how to define the location of our user configuration paths to avoid confusion. By doing it we ensure that when running the service, the service picks the correct configuration paths for our user.")),(0,o.kt)("p",null,"To learn more about the user $HOME directory read the wikipedia ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Home_directory"},"Home directory")," document."),(0,o.kt)("h2",{id:"set-the-locations-of-the-user-paths"},"Set the locations of the user paths"),(0,o.kt)(i.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,o.kt)("h2",{id:"set-the-configuration-flag--c-on-the-service-unit-file"},"Set the configuration flag -c on the service unit file"),(0,o.kt)("p",null,"The following section assumes that a System service unit has been declared and you're using systemctl to control the service, as described in our ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"Systemd Service Setup")," install section."),(0,o.kt)("p",null,"Open and edit the ",(0,o.kt)("strong",{parentName:"p"},"/etc/systemd/system/lightning.service")," file."),(0,o.kt)("p",null,"1) Replace ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with YOUR username. For example, in the documentation we use the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),", which means we'd replace ",(0,o.kt)("inlineCode",{parentName:"p"},"User=")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"User=lgtn"),"."),(0,o.kt)("p",null,"2) Make sure that the ExecStart is set correctly, including the ",(0,o.kt)("inlineCode",{parentName:"p"},"-c")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home//.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)("p",null,"For our example, as the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn")," it would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=lgtn\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)("p",null,"When complete make sure the file is saved and the systemctl daemon is reloaded, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,o.kt)("p",null,"Consequently, when a user manages the service via the systemctl, the Lightning CLI process will read the configuration file settings provided above. It includes the location of the user preferences, such as the keystore location amongst others, preventing confusion regardless of ",(0,o.kt)("strong",{parentName:"p"},"root")," delegation."),(0,o.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}c.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294);const o=e=>{let{image:t,name:n,title:o,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},o),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[9752],{3905:(e,t,n)=>{n.d(t,{Zo:()=>h,kt:()=>c});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),p=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},h=function(e){var t=p(e.components);return r.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,h=s(e,["components","mdxType","originalType","parentName"]),d=p(n),g=o,c=d["".concat(l,".").concat(g)]||d[g]||u[g]||a;return n?r.createElement(c,i(i({ref:t},h),{},{components:n})):r.createElement(c,i({ref:t},h))}));function c(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.d(t,{ZP:()=>s});var r=n(7462),o=(n(7294),n(3905));const a={toc:[]},i="wrapper";function s(e){let{components:t,...n}=e;return(0,o.kt)(i,(0,r.Z)({},a,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("p",null,"In the ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml")," you'll find some and more of the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The configuration properties and values presented above are a shorter version of what you'll find on your ",(0,o.kt)("strong",{parentName:"p"},"configuration.toml"),". We keep it short to make it easier to follow, do not copy and paste.")),(0,o.kt)("p",null,"Find and replace all instances of ~ in the config file ",(0,o.kt)("inlineCode",{parentName:"p"},"/home//.lightning/config.toml"),". "),(0,o.kt)("p",null,"Here's an example of how to do it using ",(0,o.kt)("strong",{parentName:"p"},"sed"),":"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home//.lightning|g" "/home//.lightning/config.toml"\n')),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"Replace the ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with your username. For example, if you have followed the recommendation to ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#create-a-user"},"create a user")," it would look like ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/lgtn/.lightning/config.toml")," for the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),".")),(0,o.kt)("p",null,"For example, if your username is ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that'd look like this:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},'sed -i "s|~/.lightning|/home/lgtn/.lightning|g" "/home/lgtn/.lightning/config.toml"\n')),(0,o.kt)("p",null,"Once modified, you can run a ",(0,o.kt)("inlineCode",{parentName:"p"},"cat")," to see the content of the files to confirm it has been updated."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cat /home/lgtn/.lightning/config.toml\n")),(0,o.kt)("p",null,"For our example where we opted in for the username ",(0,o.kt)("inlineCode",{parentName:"p"},"lgtn")," that would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-toml"},'[BLANK]\n\n[application]\ndb_path = "~/.lightning/data/app_db"\n\n[consensus]\nstore_path = "~/.lightning/data/narwhal_store"\n\n[fsstore]\nroot = "~/.lightning/blockstore"\n\n[resolver]\nstore_path = "~/.lightning/data/resolver_store"\n\n[signer]\nconsensus_key_path = "~/.lightning/keystore/consensus.pem"\nnode_key_path = "~/.lightning/keystore/node.pem"\n')),(0,o.kt)("admonition",{title:"Warning",type:"caution"},(0,o.kt)("p",{parentName:"admonition"},"Bear in mind that we are keeping the content of the file short to make it easier to read and follow. The content of your configuration file should look slightly different, amongst these it should contain other properties and values. You should not copy and replace the content of your files with the ones presented here.")))}s.isMDXComponent=!0},5852:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>h,contentTitle:()=>l,default:()=>c,frontMatter:()=>s,metadata:()=>p,toc:()=>d});var r=n(7462),o=(n(7294),n(3905)),a=n(3872),i=n(3242);const s={title:"File permissions and Ownership",slug:"file-permissions-and-ownership",hide_title:!0,tags:["ownership","file permissions","sudoer","root"]},l=void 0,p={unversionedId:"Lightning CLI/file-permissions-and-ownership",id:"Lightning CLI/file-permissions-and-ownership",title:"File permissions and Ownership",description:"\x3c!--",source:"@site/references/Lightning CLI/file-permissions-and-ownership.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/file-permissions-and-ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/file-permissions-and-ownership.md",tags:[{label:"ownership",permalink:"/references/tags/ownership"},{label:"file permissions",permalink:"/references/tags/file-permissions"},{label:"sudoer",permalink:"/references/tags/sudoer"},{label:"root",permalink:"/references/tags/root"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"File permissions and Ownership",slug:"file-permissions-and-ownership",hide_title:!0,tags:["ownership","file permissions","sudoer","root"]},sidebar:"defaultSidebar",previous:{title:"Error linking with cc",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1"},next:{title:"Keys not found",permalink:"/references/Lightning CLI/keys-not-found"}},h={},d=[{value:"Ownership",id:"ownership",level:2},{value:"Using sudo to delegate permissions",id:"using-sudo-to-delegate-permissions",level:2},{value:"User $HOME directory",id:"user-home-directory",level:2},{value:"Set the locations of the user paths",id:"set-the-locations-of-the-user-paths",level:2},{value:"Set the configuration flag -c on the service unit file",id:"set-the-configuration-flag--c-on-the-service-unit-file",level:2}],u={toc:d},g="wrapper";function c(e){let{components:t,...n}=e;return(0,o.kt)(g,(0,r.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"ownership"},"Ownership"),(0,o.kt)("p",null,"The user who installs the Fleek Network Lightning CLI matters, as it can own or delegate ownership of the dependencies and applications being installed."),(0,o.kt)("p",null,"For example, if you have followed the install document recommendations and have:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"Created a user ",(0,o.kt)("strong",{parentName:"li"},"lgtn")),(0,o.kt)("li",{parentName:"ul"},"Switched to the user ",(0,o.kt)("strong",{parentName:"li"},"lgtn")),(0,o.kt)("li",{parentName:"ul"},"Executed the installation process as ",(0,o.kt)("strong",{parentName:"li"},"lgtn")," ")),(0,o.kt)("p",null,"You'll find that it owns the following directories under the user home (/home/lgtn):"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"drwxr-x--- 6 lgtn lgtn 4096 Sep 12 10:27 .\ndrwxr-xr-x 3 root root 4096 Sep 11 12:28 ..\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 12:29 .cargo\ndrwxrwxr-x 5 lgtn lgtn 4096 Sep 11 15:25 .lightning\ndrwxrwxr-x 6 lgtn lgtn 4096 Sep 11 12:29 .rustup\ndrwxrwxr-x 3 lgtn lgtn 4096 Sep 11 12:28 fleek-network\n")),(0,o.kt)("p",null,"Above, we have the listing properties set as ",(0,o.kt)("strong",{parentName:"p"},"drwxrwxr-x")," and the ownership ",(0,o.kt)("strong",{parentName:"p"},"lgtn:lgtn"),"."),(0,o.kt)("p",null,"On the other hand, if you have done the installation process as ",(0,o.kt)("strong",{parentName:"p"},"root")," superuser, you'll find that:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"The location of the directories and files goes under the ",(0,o.kt)("inlineCode",{parentName:"li"},"/root")," pathname"),(0,o.kt)("li",{parentName:"ul"},"The ownership is set to ",(0,o.kt)("strong",{parentName:"li"},"root:root"))),(0,o.kt)("p",null,"Learn more about ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions"},"file permissions")," from the ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/"},"Linux Foundation"),"."),(0,o.kt)("p",null,"To learn more about file permission on Linux, read the ",(0,o.kt)("a",{parentName:"p",href:"https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions"},"Understanding Linux File Permissions"),"."),(0,o.kt)("h2",{id:"using-sudo-to-delegate-permissions"},"Using sudo to delegate permissions"),(0,o.kt)("p",null,"Consider file ownership and permissions to understand where the keystore is located. Take close attention when executing commands as an admin\u2013with or without ",(0,o.kt)("strong",{parentName:"p"},"super user")," (root) or ",(0,o.kt)("strong",{parentName:"p"},"sudo"),"."),(0,o.kt)("p",null,"If a command is executed without ",(0,o.kt)("strong",{parentName:"p"},"sudo")," then the generated output goes onto the ",(0,o.kt)("strong",{parentName:"p"},"user")," home."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"lgtn keys generate\n")),(0,o.kt)("p",null,"Resulting in having the ",(0,o.kt)("strong",{parentName:"p"},"keystore")," saved onto ",(0,o.kt)("inlineCode",{parentName:"p"},"/home/username/.lightning/keystore"),"."),(0,o.kt)("p",null,"On the other hand, if a command is executed with ",(0,o.kt)("strong",{parentName:"p"},"sudo")," then the generated output is delegated to ",(0,o.kt)("strong",{parentName:"p"},"root")," directory."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo lgtn keys generate\n")),(0,o.kt)("p",null,"Resulting in having the ",(0,o.kt)("strong",{parentName:"p"},"keystore")," saved onto ",(0,o.kt)("inlineCode",{parentName:"p"},"/root/.lightning/keystore"),"."),(0,o.kt)("h2",{id:"user-home-directory"},"User $HOME directory"),(0,o.kt)("p",null,"The home directory is a directory that contains the personal files of a particular user of the system. On Linux, the ",(0,o.kt)("inlineCode",{parentName:"p"},"$HOME")," environment variable is set by the login program, which sets the user `$HOME`` accordingly. A user's home goes by the username, the user who's logged in."),(0,o.kt)("p",null,"For this reason, a user can change to the home directory by executing:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd $HOME\n")),(0,o.kt)("p",null,"A shorthand allows a user to refer to their home directory simply as ",(0,o.kt)("inlineCode",{parentName:"p"},"~")," (tilde), as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"cd ~\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"We can find that the HOME or ~ (tilde) is highly dependent on the user who's logged in. Since we know that the user might delegate to ",(0,o.kt)("strong",{parentName:"p"},"root")," by the usage of ",(0,o.kt)("strong",{parentName:"p"},"sudo"),", this can help troubleshoot and explain the location of our files e.g. the keystore. In the section ",(0,o.kt)("a",{parentName:"p",href:"#set-the-locations-of-the-user-paths"},"Set the locations of the user paths"),", we learn how to define the location of our user configuration paths to avoid confusion. By doing it we ensure that when running the service, the service picks the correct configuration paths for our user.")),(0,o.kt)("p",null,"To learn more about the user $HOME directory read the wikipedia ",(0,o.kt)("a",{parentName:"p",href:"https://en.wikipedia.org/wiki/Home_directory"},"Home directory")," document."),(0,o.kt)("h2",{id:"set-the-locations-of-the-user-paths"},"Set the locations of the user paths"),(0,o.kt)(i.ZP,{mdxType:"FindAndReplaceConfigWithUserPaths"}),(0,o.kt)("h2",{id:"set-the-configuration-flag--c-on-the-service-unit-file"},"Set the configuration flag -c on the service unit file"),(0,o.kt)("p",null,"The following section assumes that a System service unit has been declared and you're using systemctl to control the service, as described in our ",(0,o.kt)("a",{parentName:"p",href:"/docs/node/install#systemd-service-setup"},"Systemd Service Setup")," install section."),(0,o.kt)("p",null,"Open and edit the ",(0,o.kt)("strong",{parentName:"p"},"/etc/systemd/system/lightning.service")," file."),(0,o.kt)("p",null,"1) Replace ",(0,o.kt)("inlineCode",{parentName:"p"},"")," with YOUR username. For example, in the documentation we use the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn"),", which means we'd replace ",(0,o.kt)("inlineCode",{parentName:"p"},"User=")," with ",(0,o.kt)("inlineCode",{parentName:"p"},"User=lgtn"),"."),(0,o.kt)("p",null,"2) Make sure that the ExecStart is set correctly, including the ",(0,o.kt)("inlineCode",{parentName:"p"},"-c")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home//.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=TMPDIR=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)("p",null,"For our example, as the username ",(0,o.kt)("strong",{parentName:"p"},"lgtn")," it would look like:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"[Unit]\nDescription=Fleek Network Node lightning service\n\n[Service]\nUser=lgtn\nType=simple\nMemoryHigh=32G\nRestartSec=15s\nRestart=always\nExecStart=lgtn -c /home/lgtn/.lightning/config.toml run\nStandardOutput=append:/var/log/lightning/output.log\nStandardError=append:/var/log/lightning/diagnostic.log\nEnvironment=/var/tmp\n\n[Install]\nWantedBy=multi-user.target\n")),(0,o.kt)("p",null,"When complete make sure the file is saved and the systemctl daemon is reloaded, as follows:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,o.kt)("p",null,"Consequently, when a user manages the service via the systemctl, the Lightning CLI process will read the configuration file settings provided above. It includes the location of the user preferences, such as the keystore location amongst others, preventing confusion regardless of ",(0,o.kt)("strong",{parentName:"p"},"root")," delegation."),(0,o.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}c.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>o});var r=n(7294);const o=e=>{let{image:t,name:n,title:o,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},o),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/5d08f08d.ca451cf1.js b/assets/js/5d08f08d.3c6e741c.js similarity index 64% rename from assets/js/5d08f08d.ca451cf1.js rename to assets/js/5d08f08d.3c6e741c.js index 51f0541d4..d20cbee8a 100644 --- a/assets/js/5d08f08d.ca451cf1.js +++ b/assets/js/5d08f08d.3c6e741c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[659],{340:e=>{e.exports=JSON.parse('{"label":"Guide","permalink":"/guides/tags/guide","allTagsPath":"/guides/tags","count":2,"items":[{"id":"Node Operators/getting-started-guide","title":"Getting Started","description":"A first look at what Fleek Network is, why it\'s important, and a simple tutorial of running and interacting with a node on your local machine!","permalink":"/guides/Node Operators/getting-started"},{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[659],{340:e=>{e.exports=JSON.parse('{"label":"Guide","permalink":"/guides/tags/guide","allTagsPath":"/guides/tags","count":2,"items":[{"id":"Node Operators/getting-started-guide","title":"Getting Started","description":"A first look at what Fleek Network is, why it\'s important, and a simple tutorial of running and interacting with a node on your local machine!","permalink":"/guides/Node Operators/getting-started"},{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/transfering-setup-ownership"}]}')}}]); \ No newline at end of file diff --git a/assets/js/5ec90731.f6a49b70.js b/assets/js/5ec90731.f6a49b70.js new file mode 100644 index 000000000..6a069edc4 --- /dev/null +++ b/assets/js/5ec90731.f6a49b70.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[8942],{5440:e=>{e.exports=JSON.parse('{"label":"transfer","permalink":"/guides/tags/transfer","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/transfering-setup-ownership"}]}')}}]); \ No newline at end of file diff --git a/assets/js/6be32138.6c9cea17.js b/assets/js/6be32138.8137ceb0.js similarity index 99% rename from assets/js/6be32138.6c9cea17.js rename to assets/js/6be32138.8137ceb0.js index 61419c0f7..e175d1549 100644 --- a/assets/js/6be32138.6c9cea17.js +++ b/assets/js/6be32138.8137ceb0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3396],{3905:(e,t,i)=>{i.d(t,{Zo:()=>h,kt:()=>f});var o=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function r(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function a(e){for(var t=1;t=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=o.createContext({}),c=function(e){var t=o.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},h=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var i=e.components,n=e.mdxType,r=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(i),u=n,f=p["".concat(s,".").concat(u)]||p[u]||m[u]||r;return i?o.createElement(f,a(a({ref:t},h),{},{components:i})):o.createElement(f,a({ref:t},h))}));function f(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=i.length,a=new Array(r);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:n,a[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=i(7462),n=(i(7294),i(3905));const r={title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]},a=void 0,l={permalink:"/blog/bloom-and-cuckoo-filters-for-cache-summarization",source:"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md",title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",date:"2023-09-12T16:57:42.000Z",formattedDate:"September 12, 2023",tags:[{label:"fleek network",permalink:"/blog/tags/fleek-network"},{label:"blog",permalink:"/blog/tags/blog"},{label:"engineering",permalink:"/blog/tags/engineering"},{label:"content routing",permalink:"/blog/tags/content-routing"}],readingTime:10.355,hasTruncateMarker:!0,authors:[{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"}],frontMatter:{title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]}},s={image:i(4221).Z,authorsImageUrls:[void 0]},c=[{value:"Background",id:"background",level:2},{value:"Bloom Filters",id:"bloom-filters",level:2},{value:"Cuckoo Filters",id:"cuckoo-filters",level:2},{value:"Benchmarking",id:"benchmarking",level:2},{value:"Experimental Setup",id:"experimental-setup",level:2},{value:"Memory Footprint",id:"memory-footprint",level:2},{value:"Lookup Performance",id:"lookup-performance",level:2},{value:"Insertion Performance",id:"insertion-performance",level:2},{value:"Capacity and Scaling",id:"capacity-and-scaling",level:2},{value:"Other Filters",id:"other-filters",level:2},{value:"Conclusion",id:"conclusion",level:2},{value:"References",id:"references",level:3}],h={toc:c},p="wrapper";function m(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,o.Z)({},h,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case."),(0,n.kt)("h2",{id:"background"},"Background"),(0,n.kt)("p",null,"Nodes on Fleek Network currently use Counting Bloom filters to summarize their cached content. These cache summaries are exchanged with other nodes in order to facilitate content routing."),(0,n.kt)("p",null,"If a particular node does not store a requested piece of content, it can use the Bloom filters that it received from its peers to check if a peer stores the requested content."),(0,n.kt)("p",null,"We are using Counting Bloom filters rather than regular Bloom filters because we need to be able to remove elements from the filter to support cache eviction."),(0,n.kt)("h2",{id:"bloom-filters"},"Bloom Filters"),(0,n.kt)("p",null,"A Bloom filter is a space-efficient probabilistic data structure that can be used to perform approximate set membership queries.\nThe answer to an approximate set membership query is not ",(0,n.kt)("inlineCode",{parentName:"p"},"no")," or ",(0,n.kt)("inlineCode",{parentName:"p"},"yes,")," but rather ",(0,n.kt)("inlineCode",{parentName:"p"},"no")," or ",(0,n.kt)("inlineCode",{parentName:"p"},"probably.")," This ",(0,n.kt)("inlineCode",{parentName:"p"},"probably")," is quantified with the false positive rate. "),(0,n.kt)("p",null,"One of the convenient features of Bloom filters is that they can be configured to have a specific false positive rate.\nOf course, there is a tradeoff here; the lower the false positive rate, the larger the memory footprint. Bloom filters support two operations: ",(0,n.kt)("inlineCode",{parentName:"p"},"insert")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"contains.")," "),(0,n.kt)("p",null,"A Bloom filter is represented by an array of m bits together with k independent hash functions. To insert an element into the filter, it is hashed with each of the k hash functions.\nThe resulting hashes are interpreted as integers (modulo m) to obtain k array positions. The bits at these positions are then set to 1 (if there aren't already 1).",(0,n.kt)("br",{parentName:"p"}),"\n","To check whether or not an element is contained in the filter, the element is hashed k times with the different hash functions."),(0,n.kt)("p",null,"If all bits at the resulting array positions are 1, the element is assumed to be present. If any of the k bits are zero, we can be certain that the queried element is not present in the set."),(0,n.kt)("p",null,"However, even if all bits are 1, it might still be the case that the bits were set by a combination of other elements. This is where the aforementioned false positive rate comes into play. "),(0,n.kt)("p",null,"Since we also need a ",(0,n.kt)("inlineCode",{parentName:"p"},"remove")," operation for our use case, we have been using Counting Bloom filters, a variant of Bloom filters.\nCounting Bloom filters retain most of the properties that regular Bloom filters have. The ",(0,n.kt)("inlineCode",{parentName:"p"},"remove")," operation comes at the cost of an increased memory footprint."),(0,n.kt)("p",null,"Each position in the array is no longer a single bit but a group of bits representing a counter.\nWhenever an element is inserted into the filter, the counters for all k positions are incremented by 1. To remove an element, we decrement the counters."),(0,n.kt)("h2",{id:"cuckoo-filters"},"Cuckoo Filters"),(0,n.kt)("p",null,"Bloom filters are the most known members of a class of data structures called Approximate Membership Query Filters (AMQ Filters).\nA relatively recent addition to this class is the Cuckoo filter ","[1]",". Cuckoo filters share many similarities with Bloom filters, especially Counting Bloom filters."),(0,n.kt)("p",null,"They are space-efficient and can be used for approximate set membership queries. Cuckoo filters also support the operations ",(0,n.kt)("inlineCode",{parentName:"p"},"insert,")," ",(0,n.kt)("inlineCode",{parentName:"p"},"contains,")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"remove,")," and have configurable false positive rates. "),(0,n.kt)("p",null,"Cuckoo filters are based on Cuckoo hash tables ","[2]"," and leverage an optimization called partial-key cuckoo hashing. A basic Cuckoo hash table consists of an array of buckets.\nWe determine two candidate buckets for each element using two different hash functions, h1 and h2. "),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"contains")," operation will check if either bucket contains the element.\nFor insertion, if either bucket is empty, the element will be inserted into the empty bucket."),(0,n.kt)("p",null,"If neither bucket is empty, one of the buckets is selected, and the existing element is removed and inserted into its alternate location.\nThis may trigger another relocation if the alternate location is not empty. "),(0,n.kt)("p",null,"Although the insertion operation may perform a sequence of relocations, the amortized runtime is O(1). "),(0,n.kt)("p",null,"Most implementations of Cuckoo hash tables and, consequently, Cuckoo filters will use buckets that can hold multiple elements, as proposed in ","[3]","."),(0,n.kt)("p",null,"For Cuckoo filters, the hash table size is reduced by only storing fingerprints - a bit string calculated from an element's hash - rather than key-value pairs."),(0,n.kt)("p",null,"The fingerprint size is derived from the desired false positive rate.",(0,n.kt)("br",{parentName:"p"}),"\n","A problem that arises is that, to relocate existing fingerprints using the Cuckoo hashing approach described above, we need the original hash from which the fingerprint was derived."),(0,n.kt)("p",null,"Of course, we could store this hash somewhere, but the whole point of using fingerprints is to reduce the memory footprint of the filter."),(0,n.kt)("p",null,"The solution to this predicament is the aforementioned partial-key cuckoo hashing, a technique for determining an element's alternate location using only its fingerprint.",(0,n.kt)("br",{parentName:"p"}),"\n","For a given element x, the two candidate buckets are computed as follows: "),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(9440).Z,width:"1324",height:"194"})),(0,n.kt)("p",null,"An important property of this technique is that h1(x) can also be computed from h2(x) and the fingerprint."),(0,n.kt)("h2",{id:"benchmarking"},"Benchmarking"),(0,n.kt)("p",null,"As this post mentioned, we are not aiming for a general comparison of Counting Bloom and Cuckoo filters."),(0,n.kt)("p",null,"Instead, we want to determine which filter suits our specific use case better. The two main properties we are looking for are space efficiency and lookup performance. "),(0,n.kt)("p",null,"Space efficiency is important because nodes frequently update their cache and have to communicate these changes with their peers. These messages should take up as little bandwidth as possible."),(0,n.kt)("p",null,"Lookup speed is also important because Fleek Network aims to serve user requests as quickly as possible. Checking whether a peer has some content stored in their cache summary should not be a bottleneck. "),(0,n.kt)("h2",{id:"experimental-setup"},"Experimental Setup"),(0,n.kt)("p",null,"We are using our own Counting Bloom filter ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/ursa/blob/483f4d56cbaa5e83182454d2c1db6f6af7c54912/crates/ursa-network/src/utils/bloom_filter.rs#L11"},"implementation")," and\n",(0,n.kt)("a",{parentName:"p",href:"https://github.com/sile/scalable_cuckoo_filter"},"this")," Cuckoo filter implementation in Rust (the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/efficient/cuckoofilter"},"original")," implementation is in C++). All experiments\nwere performed on a Linux machine with 16 GB RAM and an Intel Core i7 (10th Gen). Whenever the experiment is probabilistic, we repeat the experiment 20 times and report the mean and standard deviation."),(0,n.kt)("h2",{id:"memory-footprint"},"Memory Footprint"),(0,n.kt)("p",null,"For both Counting Bloom filters and Cuckoo filters, the memory footprint is determined by two factors: the filter's capacity and the desired false positive rate. In the first experiment, we examine the impact that\nthese factors have on the memory footprint. "),(0,n.kt)("p",null,"To this end, we fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The result is shown in Fig. 1.\nThe size of Bloom filters scales linearly with the capacity. Cuckoo filters are more space-efficient. This result is consistent with the experiments reported in ","[1]","."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(5441).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 1: We fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The y-axis shows the size of the filters in Megabytes.")),(0,n.kt)("p",null,"Next, we fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. Fig. 2 shows that Cuckoo filters are more space-efficient."),(0,n.kt)("p",null,"The gap between Counting Bloom filters and Cuckoo filters grows as the false positive rate decreases. This is also consistent with experiments in ","[1]","."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(9844).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 2: We fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. The y-axis shows the size of the filters in Megabytes.")),(0,n.kt)("h2",{id:"lookup-performance"},"Lookup Performance"),(0,n.kt)("p",null,"We first add elements to both filters until the capacity is reached. We then measure the lookup performance for different ratios of positive and negative lookups."),(0,n.kt)("p",null,"A positive lookup is for an existing element, and a negative lookup is for an element not contained in the filter. We perform 100K lookups for each ratio and report the average lookup duration and standard deviation. "),(0,n.kt)("p",null,"Fig. 3 shows the results. Bloom filters perform slightly better on average than Cuckoo filters. This result is inconsistent with ","[1]",",\nwhere Cuckoo filters were reported to have a better lookup performance than Bloom filters. It should be noted here that the authors in ","[1]"," use the original C++ Cuckoo filter implementation and their own unreleased Bloom filter implementation. In contrast, we use a Rust Cuckoo filter implementation and our Bloom filter implementation. We cannot easily determine the reason for this discrepancy."),(0,n.kt)("p",null,"However, the performance difference is negligible."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(8915).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 3: Lookup performance for different ratios of positive and negative lookups. For example, ratio 0.25 indicates that 25% of lookups are positive and 75% are negative.\nThe shaded region indicates the standard deviation.")),(0,n.kt)("h2",{id:"insertion-performance"},"Insertion Performance"),(0,n.kt)("p",null,"Less critical than lookup performance but still important for our purposes is insertion performance. We measure how the insertion performance varies for different occupancy levels.\nFig. 4 shows the results. The insertion performance is constant across all levels of occupancy for Bloom filters."),(0,n.kt)("p",null,"For Cuckoo filters, the performance decreases as the filter becomes fuller because more relocations are required. In Fig. 4, the performance for Bloom filters is not constant. It quickly increases and then remains constant. This can be explained by CPU caching. "),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(989).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 4: Insertion performance for different occupancy levels. The shaded region indicates the standard deviation.")),(0,n.kt)("h2",{id:"capacity-and-scaling"},"Capacity and Scaling"),(0,n.kt)("p",null,"We have mentioned the capacity of a filter several times now. An interesting case is what happens when a filter's capacity is exceeded.\nBloom filters and Cuckoo filters behave differently in this scenario."),(0,n.kt)("p",null,"For Bloom filters, the ",(0,n.kt)("inlineCode",{parentName:"p"},"insertion")," operation always succeeds. However, the false positive rate will rapidly increase as we exceed the filter's capacity. While Bloom filters fail silently, Cuckoo filters are more explicit. Most implementations have a maximum number of\nrelocations that will be performed for an insertion. The ",(0,n.kt)("inlineCode",{parentName:"p"},"insertion")," operation will return an error if more relocations are required. "),(0,n.kt)("p",null,"For both filters, we can avoid this problem by simply initializing the filter with a sufficiently large capacity. However, this will increase the memory footprint of the filter."),(0,n.kt)("p",null,"Furthermore, it is difficult to predict how many elements a node on Fleek Network will cache. It is also likely that the number of cached elements will greatly vary for different nodes. "),(0,n.kt)("p",null,"Fortunately, a variant of Bloom filters called Scalable Bloom Filters ","[4]"," can adapt dynamically to the number of elements stored while guaranteeing a maximum false positive rate."),(0,n.kt)("p",null,"The proposed technique is also applicable to Cuckoo filters."),(0,n.kt)("h2",{id:"other-filters"},"Other Filters"),(0,n.kt)("p",null,"While we only looked at Bloom filters and Cuckoo filters, there are other AMQ filters that we want to mention here briefly:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},"Quotient filters ","[5, 6]",": Compact hash tables that support insertion, lookup, and deletion. Less space-efficient than Bloom filters and Cuckoo filters. ")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},"XOR filters ","[7]",": More space-efficient than Bloom filters and Cuckoo filters. However, they are static, meaning the filter has to be rebuilt if additional elements are added. "))),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"We examined whether Counting Bloom filters or Cuckoo filters are more suitable for summarizing caches on Fleek Network. Cuckoo filters are more space-efficient, especially for lower false positive rates. Bloom filters have a slightly better insertion and lookup performance for the implementations we tested."),(0,n.kt)("p",null,"Both filters can be adapted to grow and shrink in size dynamically. Since the difference in insertion and lookup performance is negligible while Cuckoo filters are significantly more space-efficient, we favor Cuckoo filters for our use case. "),(0,n.kt)("h3",{id:"references"},"References"),(0,n.kt)("p",null,"[1]"," Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher. Cuckoo Filter: Practically Better Than Bloom.\nIn Proceedings of the 10th ACM International Conference on emerging Networking Experiments and Technologies (CoNEXT 14). Association for Computing Machinery, New York, NY, USA, pp. 75-88, 2014. "),(0,n.kt)("p",null,"[2]"," Rasmus Pagha and Flemming Friche Rodler. Cuckoo hashing. Journal of Algorithms, 51(2), pp. 122-144, 2004. "),(0,n.kt)("p",null,"[3]"," Martin Dietzfelbinger and Christoph Weidling. Balanced Allocation and Dictionaries with Tightly Packed Constant Size Bins. Theoretical Computer Science, 380(1), pp. 47-68, 2007. "),(0,n.kt)("p",null,"[4]"," Paulo S. Almeida, Carlos Baquero, Nuno Pregui\xe7a, and David Hutchison. Scalable Bloom Filters. Information Processing Letters, 101(6), pp. 255-261, 2007. "),(0,n.kt)("p",null,"[5]"," John G. Cleary. Compact hash tables using bidirectional linear probing. IEEE Transactions on Computers. 33(9), pp. 828-834, 1984. "),(0,n.kt)("p",null,"[6]"," Anna Pagh, Rasmus Pagh, and S. Srinivasa Rao. An optimal Bloom filter replacement. Proceedings of the Sixteenth Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 823-829, 2005. "),(0,n.kt)("p",null,"[7]"," Thomas Mueller Graf and Daniel Lemire. Xor Filters: Faster and Smaller Than Bloom and Cuckoo Filters. ACM Journal of Experimental Algorithmics. 25, pp. 1-16, 2020."))}m.isMDXComponent=!0},4221:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/bloom-79da0db687b4fb2060758838b9c44513.png"},5441:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/capacity-size-5c2576bd69db0e5b510781e7cc1c5257.png"},9844:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/fp-rate-size-fbb54b2450b4a91e28c97d8adf0253e8.png"},989:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/insert-3ff48d4c63724adcf399f81b29607691.png"},8915:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/lookup-e36011237d8602b5f6c36fe5dd145bf5.png"},9440:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/math-formul-a247d4df475b26b1e7cbb2acfc0ab8c2.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3396],{3905:(e,t,i)=>{i.d(t,{Zo:()=>h,kt:()=>f});var o=i(7294);function n(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function r(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,o)}return i}function a(e){for(var t=1;t=0||(n[i]=e[i]);return n}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(n[i]=e[i])}return n}var s=o.createContext({}),c=function(e){var t=o.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):a(a({},t),e)),i},h=function(e){var t=c(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var i=e.components,n=e.mdxType,r=e.originalType,s=e.parentName,h=l(e,["components","mdxType","originalType","parentName"]),p=c(i),u=n,f=p["".concat(s,".").concat(u)]||p[u]||m[u]||r;return i?o.createElement(f,a(a({ref:t},h),{},{components:i})):o.createElement(f,a({ref:t},h))}));function f(e,t){var i=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var r=i.length,a=new Array(r);a[0]=u;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:n,a[1]=l;for(var c=2;c{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var o=i(7462),n=(i(7294),i(3905));const r={title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]},a=void 0,l={permalink:"/blog/bloom-and-cuckoo-filters-for-cache-summarization",source:"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md",title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",date:"2023-09-13T11:07:59.000Z",formattedDate:"September 13, 2023",tags:[{label:"fleek network",permalink:"/blog/tags/fleek-network"},{label:"blog",permalink:"/blog/tags/blog"},{label:"engineering",permalink:"/blog/tags/engineering"},{label:"content routing",permalink:"/blog/tags/content-routing"}],readingTime:10.355,hasTruncateMarker:!0,authors:[{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"}],frontMatter:{title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]}},s={image:i(4221).Z,authorsImageUrls:[void 0]},c=[{value:"Background",id:"background",level:2},{value:"Bloom Filters",id:"bloom-filters",level:2},{value:"Cuckoo Filters",id:"cuckoo-filters",level:2},{value:"Benchmarking",id:"benchmarking",level:2},{value:"Experimental Setup",id:"experimental-setup",level:2},{value:"Memory Footprint",id:"memory-footprint",level:2},{value:"Lookup Performance",id:"lookup-performance",level:2},{value:"Insertion Performance",id:"insertion-performance",level:2},{value:"Capacity and Scaling",id:"capacity-and-scaling",level:2},{value:"Other Filters",id:"other-filters",level:2},{value:"Conclusion",id:"conclusion",level:2},{value:"References",id:"references",level:3}],h={toc:c},p="wrapper";function m(e){let{components:t,...r}=e;return(0,n.kt)(p,(0,o.Z)({},h,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case."),(0,n.kt)("h2",{id:"background"},"Background"),(0,n.kt)("p",null,"Nodes on Fleek Network currently use Counting Bloom filters to summarize their cached content. These cache summaries are exchanged with other nodes in order to facilitate content routing."),(0,n.kt)("p",null,"If a particular node does not store a requested piece of content, it can use the Bloom filters that it received from its peers to check if a peer stores the requested content."),(0,n.kt)("p",null,"We are using Counting Bloom filters rather than regular Bloom filters because we need to be able to remove elements from the filter to support cache eviction."),(0,n.kt)("h2",{id:"bloom-filters"},"Bloom Filters"),(0,n.kt)("p",null,"A Bloom filter is a space-efficient probabilistic data structure that can be used to perform approximate set membership queries.\nThe answer to an approximate set membership query is not ",(0,n.kt)("inlineCode",{parentName:"p"},"no")," or ",(0,n.kt)("inlineCode",{parentName:"p"},"yes,")," but rather ",(0,n.kt)("inlineCode",{parentName:"p"},"no")," or ",(0,n.kt)("inlineCode",{parentName:"p"},"probably.")," This ",(0,n.kt)("inlineCode",{parentName:"p"},"probably")," is quantified with the false positive rate. "),(0,n.kt)("p",null,"One of the convenient features of Bloom filters is that they can be configured to have a specific false positive rate.\nOf course, there is a tradeoff here; the lower the false positive rate, the larger the memory footprint. Bloom filters support two operations: ",(0,n.kt)("inlineCode",{parentName:"p"},"insert")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"contains.")," "),(0,n.kt)("p",null,"A Bloom filter is represented by an array of m bits together with k independent hash functions. To insert an element into the filter, it is hashed with each of the k hash functions.\nThe resulting hashes are interpreted as integers (modulo m) to obtain k array positions. The bits at these positions are then set to 1 (if there aren't already 1).",(0,n.kt)("br",{parentName:"p"}),"\n","To check whether or not an element is contained in the filter, the element is hashed k times with the different hash functions."),(0,n.kt)("p",null,"If all bits at the resulting array positions are 1, the element is assumed to be present. If any of the k bits are zero, we can be certain that the queried element is not present in the set."),(0,n.kt)("p",null,"However, even if all bits are 1, it might still be the case that the bits were set by a combination of other elements. This is where the aforementioned false positive rate comes into play. "),(0,n.kt)("p",null,"Since we also need a ",(0,n.kt)("inlineCode",{parentName:"p"},"remove")," operation for our use case, we have been using Counting Bloom filters, a variant of Bloom filters.\nCounting Bloom filters retain most of the properties that regular Bloom filters have. The ",(0,n.kt)("inlineCode",{parentName:"p"},"remove")," operation comes at the cost of an increased memory footprint."),(0,n.kt)("p",null,"Each position in the array is no longer a single bit but a group of bits representing a counter.\nWhenever an element is inserted into the filter, the counters for all k positions are incremented by 1. To remove an element, we decrement the counters."),(0,n.kt)("h2",{id:"cuckoo-filters"},"Cuckoo Filters"),(0,n.kt)("p",null,"Bloom filters are the most known members of a class of data structures called Approximate Membership Query Filters (AMQ Filters).\nA relatively recent addition to this class is the Cuckoo filter ","[1]",". Cuckoo filters share many similarities with Bloom filters, especially Counting Bloom filters."),(0,n.kt)("p",null,"They are space-efficient and can be used for approximate set membership queries. Cuckoo filters also support the operations ",(0,n.kt)("inlineCode",{parentName:"p"},"insert,")," ",(0,n.kt)("inlineCode",{parentName:"p"},"contains,")," and ",(0,n.kt)("inlineCode",{parentName:"p"},"remove,")," and have configurable false positive rates. "),(0,n.kt)("p",null,"Cuckoo filters are based on Cuckoo hash tables ","[2]"," and leverage an optimization called partial-key cuckoo hashing. A basic Cuckoo hash table consists of an array of buckets.\nWe determine two candidate buckets for each element using two different hash functions, h1 and h2. "),(0,n.kt)("p",null,"The ",(0,n.kt)("inlineCode",{parentName:"p"},"contains")," operation will check if either bucket contains the element.\nFor insertion, if either bucket is empty, the element will be inserted into the empty bucket."),(0,n.kt)("p",null,"If neither bucket is empty, one of the buckets is selected, and the existing element is removed and inserted into its alternate location.\nThis may trigger another relocation if the alternate location is not empty. "),(0,n.kt)("p",null,"Although the insertion operation may perform a sequence of relocations, the amortized runtime is O(1). "),(0,n.kt)("p",null,"Most implementations of Cuckoo hash tables and, consequently, Cuckoo filters will use buckets that can hold multiple elements, as proposed in ","[3]","."),(0,n.kt)("p",null,"For Cuckoo filters, the hash table size is reduced by only storing fingerprints - a bit string calculated from an element's hash - rather than key-value pairs."),(0,n.kt)("p",null,"The fingerprint size is derived from the desired false positive rate.",(0,n.kt)("br",{parentName:"p"}),"\n","A problem that arises is that, to relocate existing fingerprints using the Cuckoo hashing approach described above, we need the original hash from which the fingerprint was derived."),(0,n.kt)("p",null,"Of course, we could store this hash somewhere, but the whole point of using fingerprints is to reduce the memory footprint of the filter."),(0,n.kt)("p",null,"The solution to this predicament is the aforementioned partial-key cuckoo hashing, a technique for determining an element's alternate location using only its fingerprint.",(0,n.kt)("br",{parentName:"p"}),"\n","For a given element x, the two candidate buckets are computed as follows: "),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(9440).Z,width:"1324",height:"194"})),(0,n.kt)("p",null,"An important property of this technique is that h1(x) can also be computed from h2(x) and the fingerprint."),(0,n.kt)("h2",{id:"benchmarking"},"Benchmarking"),(0,n.kt)("p",null,"As this post mentioned, we are not aiming for a general comparison of Counting Bloom and Cuckoo filters."),(0,n.kt)("p",null,"Instead, we want to determine which filter suits our specific use case better. The two main properties we are looking for are space efficiency and lookup performance. "),(0,n.kt)("p",null,"Space efficiency is important because nodes frequently update their cache and have to communicate these changes with their peers. These messages should take up as little bandwidth as possible."),(0,n.kt)("p",null,"Lookup speed is also important because Fleek Network aims to serve user requests as quickly as possible. Checking whether a peer has some content stored in their cache summary should not be a bottleneck. "),(0,n.kt)("h2",{id:"experimental-setup"},"Experimental Setup"),(0,n.kt)("p",null,"We are using our own Counting Bloom filter ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/ursa/blob/483f4d56cbaa5e83182454d2c1db6f6af7c54912/crates/ursa-network/src/utils/bloom_filter.rs#L11"},"implementation")," and\n",(0,n.kt)("a",{parentName:"p",href:"https://github.com/sile/scalable_cuckoo_filter"},"this")," Cuckoo filter implementation in Rust (the ",(0,n.kt)("a",{parentName:"p",href:"https://github.com/efficient/cuckoofilter"},"original")," implementation is in C++). All experiments\nwere performed on a Linux machine with 16 GB RAM and an Intel Core i7 (10th Gen). Whenever the experiment is probabilistic, we repeat the experiment 20 times and report the mean and standard deviation."),(0,n.kt)("h2",{id:"memory-footprint"},"Memory Footprint"),(0,n.kt)("p",null,"For both Counting Bloom filters and Cuckoo filters, the memory footprint is determined by two factors: the filter's capacity and the desired false positive rate. In the first experiment, we examine the impact that\nthese factors have on the memory footprint. "),(0,n.kt)("p",null,"To this end, we fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The result is shown in Fig. 1.\nThe size of Bloom filters scales linearly with the capacity. Cuckoo filters are more space-efficient. This result is consistent with the experiments reported in ","[1]","."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(5441).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 1: We fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The y-axis shows the size of the filters in Megabytes.")),(0,n.kt)("p",null,"Next, we fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. Fig. 2 shows that Cuckoo filters are more space-efficient."),(0,n.kt)("p",null,"The gap between Counting Bloom filters and Cuckoo filters grows as the false positive rate decreases. This is also consistent with experiments in ","[1]","."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(9844).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 2: We fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. The y-axis shows the size of the filters in Megabytes.")),(0,n.kt)("h2",{id:"lookup-performance"},"Lookup Performance"),(0,n.kt)("p",null,"We first add elements to both filters until the capacity is reached. We then measure the lookup performance for different ratios of positive and negative lookups."),(0,n.kt)("p",null,"A positive lookup is for an existing element, and a negative lookup is for an element not contained in the filter. We perform 100K lookups for each ratio and report the average lookup duration and standard deviation. "),(0,n.kt)("p",null,"Fig. 3 shows the results. Bloom filters perform slightly better on average than Cuckoo filters. This result is inconsistent with ","[1]",",\nwhere Cuckoo filters were reported to have a better lookup performance than Bloom filters. It should be noted here that the authors in ","[1]"," use the original C++ Cuckoo filter implementation and their own unreleased Bloom filter implementation. In contrast, we use a Rust Cuckoo filter implementation and our Bloom filter implementation. We cannot easily determine the reason for this discrepancy."),(0,n.kt)("p",null,"However, the performance difference is negligible."),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(8915).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 3: Lookup performance for different ratios of positive and negative lookups. For example, ratio 0.25 indicates that 25% of lookups are positive and 75% are negative.\nThe shaded region indicates the standard deviation.")),(0,n.kt)("h2",{id:"insertion-performance"},"Insertion Performance"),(0,n.kt)("p",null,"Less critical than lookup performance but still important for our purposes is insertion performance. We measure how the insertion performance varies for different occupancy levels.\nFig. 4 shows the results. The insertion performance is constant across all levels of occupancy for Bloom filters."),(0,n.kt)("p",null,"For Cuckoo filters, the performance decreases as the filter becomes fuller because more relocations are required. In Fig. 4, the performance for Bloom filters is not constant. It quickly increases and then remains constant. This can be explained by CPU caching. "),(0,n.kt)("p",null,(0,n.kt)("img",{src:i(989).Z,width:"640",height:"480"})),(0,n.kt)("blockquote",null,(0,n.kt)("p",{parentName:"blockquote"},"Figure 4: Insertion performance for different occupancy levels. The shaded region indicates the standard deviation.")),(0,n.kt)("h2",{id:"capacity-and-scaling"},"Capacity and Scaling"),(0,n.kt)("p",null,"We have mentioned the capacity of a filter several times now. An interesting case is what happens when a filter's capacity is exceeded.\nBloom filters and Cuckoo filters behave differently in this scenario."),(0,n.kt)("p",null,"For Bloom filters, the ",(0,n.kt)("inlineCode",{parentName:"p"},"insertion")," operation always succeeds. However, the false positive rate will rapidly increase as we exceed the filter's capacity. While Bloom filters fail silently, Cuckoo filters are more explicit. Most implementations have a maximum number of\nrelocations that will be performed for an insertion. The ",(0,n.kt)("inlineCode",{parentName:"p"},"insertion")," operation will return an error if more relocations are required. "),(0,n.kt)("p",null,"For both filters, we can avoid this problem by simply initializing the filter with a sufficiently large capacity. However, this will increase the memory footprint of the filter."),(0,n.kt)("p",null,"Furthermore, it is difficult to predict how many elements a node on Fleek Network will cache. It is also likely that the number of cached elements will greatly vary for different nodes. "),(0,n.kt)("p",null,"Fortunately, a variant of Bloom filters called Scalable Bloom Filters ","[4]"," can adapt dynamically to the number of elements stored while guaranteeing a maximum false positive rate."),(0,n.kt)("p",null,"The proposed technique is also applicable to Cuckoo filters."),(0,n.kt)("h2",{id:"other-filters"},"Other Filters"),(0,n.kt)("p",null,"While we only looked at Bloom filters and Cuckoo filters, there are other AMQ filters that we want to mention here briefly:"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},"Quotient filters ","[5, 6]",": Compact hash tables that support insertion, lookup, and deletion. Less space-efficient than Bloom filters and Cuckoo filters. ")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("p",{parentName:"li"},"XOR filters ","[7]",": More space-efficient than Bloom filters and Cuckoo filters. However, they are static, meaning the filter has to be rebuilt if additional elements are added. "))),(0,n.kt)("h2",{id:"conclusion"},"Conclusion"),(0,n.kt)("p",null,"We examined whether Counting Bloom filters or Cuckoo filters are more suitable for summarizing caches on Fleek Network. Cuckoo filters are more space-efficient, especially for lower false positive rates. Bloom filters have a slightly better insertion and lookup performance for the implementations we tested."),(0,n.kt)("p",null,"Both filters can be adapted to grow and shrink in size dynamically. Since the difference in insertion and lookup performance is negligible while Cuckoo filters are significantly more space-efficient, we favor Cuckoo filters for our use case. "),(0,n.kt)("h3",{id:"references"},"References"),(0,n.kt)("p",null,"[1]"," Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher. Cuckoo Filter: Practically Better Than Bloom.\nIn Proceedings of the 10th ACM International Conference on emerging Networking Experiments and Technologies (CoNEXT 14). Association for Computing Machinery, New York, NY, USA, pp. 75-88, 2014. "),(0,n.kt)("p",null,"[2]"," Rasmus Pagha and Flemming Friche Rodler. Cuckoo hashing. Journal of Algorithms, 51(2), pp. 122-144, 2004. "),(0,n.kt)("p",null,"[3]"," Martin Dietzfelbinger and Christoph Weidling. Balanced Allocation and Dictionaries with Tightly Packed Constant Size Bins. Theoretical Computer Science, 380(1), pp. 47-68, 2007. "),(0,n.kt)("p",null,"[4]"," Paulo S. Almeida, Carlos Baquero, Nuno Pregui\xe7a, and David Hutchison. Scalable Bloom Filters. Information Processing Letters, 101(6), pp. 255-261, 2007. "),(0,n.kt)("p",null,"[5]"," John G. Cleary. Compact hash tables using bidirectional linear probing. IEEE Transactions on Computers. 33(9), pp. 828-834, 1984. "),(0,n.kt)("p",null,"[6]"," Anna Pagh, Rasmus Pagh, and S. Srinivasa Rao. An optimal Bloom filter replacement. Proceedings of the Sixteenth Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 823-829, 2005. "),(0,n.kt)("p",null,"[7]"," Thomas Mueller Graf and Daniel Lemire. Xor Filters: Faster and Smaller Than Bloom and Cuckoo Filters. ACM Journal of Experimental Algorithmics. 25, pp. 1-16, 2020."))}m.isMDXComponent=!0},4221:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/bloom-79da0db687b4fb2060758838b9c44513.png"},5441:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/capacity-size-5c2576bd69db0e5b510781e7cc1c5257.png"},9844:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/fp-rate-size-fbb54b2450b4a91e28c97d8adf0253e8.png"},989:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/insert-3ff48d4c63724adcf399f81b29607691.png"},8915:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/lookup-e36011237d8602b5f6c36fe5dd145bf5.png"},9440:(e,t,i)=>{i.d(t,{Z:()=>o});const o=i.p+"assets/images/math-formul-a247d4df475b26b1e7cbb2acfc0ab8c2.png"}}]); \ No newline at end of file diff --git a/assets/js/84cbd6c9.e5b417d2.js b/assets/js/84cbd6c9.3c01fe76.js similarity index 58% rename from assets/js/84cbd6c9.e5b417d2.js rename to assets/js/84cbd6c9.3c01fe76.js index 5b19f8970..fa43961f9 100644 --- a/assets/js/84cbd6c9.e5b417d2.js +++ b/assets/js/84cbd6c9.3c01fe76.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3336],{4793:e=>{e.exports=JSON.parse('[{"label":"Guides","permalink":"/guides/tags/guides","count":1},{"label":"Help","permalink":"/guides/tags/help","count":1},{"label":"Fleek Network","permalink":"/guides/tags/fleek-network","count":1},{"label":"Edge computing","permalink":"/guides/tags/edge-computing","count":1},{"label":"Guide","permalink":"/guides/tags/guide","count":2},{"label":"Getting Started","permalink":"/guides/tags/getting-started","count":1},{"label":"migration","permalink":"/guides/tags/migration","count":1},{"label":"migrate","permalink":"/guides/tags/migrate","count":1},{"label":"ownership","permalink":"/guides/tags/ownership","count":1},{"label":"setup","permalink":"/guides/tags/setup","count":1},{"label":"configuration","permalink":"/guides/tags/configuration","count":1}]')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3336],{4793:e=>{e.exports=JSON.parse('[{"label":"Guides","permalink":"/guides/tags/guides","count":1},{"label":"Help","permalink":"/guides/tags/help","count":1},{"label":"Fleek Network","permalink":"/guides/tags/fleek-network","count":1},{"label":"Edge computing","permalink":"/guides/tags/edge-computing","count":1},{"label":"Guide","permalink":"/guides/tags/guide","count":2},{"label":"Getting Started","permalink":"/guides/tags/getting-started","count":1},{"label":"transfer","permalink":"/guides/tags/transfer","count":1},{"label":"ownership","permalink":"/guides/tags/ownership","count":1},{"label":"setup","permalink":"/guides/tags/setup","count":1},{"label":"configuration","permalink":"/guides/tags/configuration","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/8a92e787.2ff8da0a.js b/assets/js/8a92e787.b29f91dc.js similarity index 98% rename from assets/js/8a92e787.2ff8da0a.js rename to assets/js/8a92e787.b29f91dc.js index 9b25715db..80c257d43 100644 --- a/assets/js/8a92e787.2ff8da0a.js +++ b/assets/js/8a92e787.b29f91dc.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[2517],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var c=r.createContext({}),i=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=i(e.components);return r.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=i(n),g=s,m=d["".concat(c,".").concat(g)]||d[g]||p[g]||a;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var a=n.length,o=new Array(a);o[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[d]="string"==typeof e?e:s,o[1]=l;for(var i=2;i{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=n(7462),s=(n(7294),n(3905)),a=n(3872);const o={title:"Shutting down persistance",slug:"shutting-down-persistance",hide_title:!0,tags:["reference","shutdown","frozen","idle","service error","systemctl","systemd"]},l=void 0,c={unversionedId:"Systemd/shutting-down-persistance",id:"Systemd/shutting-down-persistance",title:"Shutting down persistance",description:"\x3c!--",source:"@site/references/Systemd/shutting-down-persistance.md",sourceDirName:"Systemd",slug:"/Systemd/shutting-down-persistance",permalink:"/references/Systemd/shutting-down-persistance",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Systemd/shutting-down-persistance.md",tags:[{label:"reference",permalink:"/references/tags/reference"},{label:"shutdown",permalink:"/references/tags/shutdown"},{label:"frozen",permalink:"/references/tags/frozen"},{label:"idle",permalink:"/references/tags/idle"},{label:"service error",permalink:"/references/tags/service-error"},{label:"systemctl",permalink:"/references/tags/systemctl"},{label:"systemd",permalink:"/references/tags/systemd"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Shutting down persistance",slug:"shutting-down-persistance",hide_title:!0,tags:["reference","shutdown","frozen","idle","service error","systemctl","systemd"]},sidebar:"defaultSidebar",previous:{title:"Update CLI from source code",permalink:"/references/Lightning CLI/update-cli-from-source-code"},next:{title:"User service",permalink:"/references/Systemd/user-service"}},i={},u=[{value:"Systemd Service as frozen or idle",id:"systemd-service-as-frozen-or-idle",level:2}],d={toc:u},p="wrapper";function g(e){let{components:t,...n}=e;return(0,s.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h2",{id:"systemd-service-as-frozen-or-idle"},"Systemd Service as frozen or idle"),(0,s.kt)("p",null,"If you have a ",(0,s.kt)("inlineCode",{parentName:"p"},"Shutting node down")," message on the service log, the process is likely failing to respond to Systemd shut down command by failing to terminate all the child processes that were started by the service."),(0,s.kt)("p",null,"The logs should be similar to the following:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"2023-09-11 18:02:07 | ERROR | lightning_consensus::consensus - core/consensus/src/consensus.rs:371 - node: XsE9KtedDRUGv22MLHvy8qcc52QsWGWJYY1LBnWhglg=\n2023-09-11 18:02:07 | ERROR | lightning_consensus::consensus - core/consensus/src/consensus.rs:371 - node: zBmZaycvQsdFRfe0p5Rig/KgyYPD4yNKQTPDo7JrugM=\n2023-09-11 18:02:07 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:373 - ##################\n2023-09-11 18:02:07 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:374 - ********************************\nRPC server starting up\nlistening on 0.0.0.0:4069\nShutting node down.\nShutting node down.\nShutting node down.\nShutting node down.\nShutting node down.\n")),(0,s.kt)("p",null,"To resolve this issue, start by executing a new ",(0,s.kt)("inlineCode",{parentName:"p"},"shutdown")," command as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl stop lightning\n")),(0,s.kt)("p",null,"If you need to delegate to root, then use the ",(0,s.kt)("strong",{parentName:"p"},"sudo")," keyword, as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl stop lightning\n")),(0,s.kt)("p",null,"Once completed, clear the logs to avoid confusion as the log aggregates messages past and current."),(0,s.kt)("p",null,"Delete all the log files (output.log and diagnostic.log) by running:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -f /var/log/lightning/*.log\n")),(0,s.kt)("p",null,"Launch the service:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl start lightning\n")),(0,s.kt)("p",null,"If you need to delegate to root, then use the ",(0,s.kt)("strong",{parentName:"p"},"sudo")," keyword, as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl start lightning\n")),(0,s.kt)("p",null,"You can watch the log output of the service by running:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"tail -f /var/log/lightning/output.log\n")),(0,s.kt)("p",null,"The output should be similar to:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"2023-09-12 13:53:51 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:373 - ##################\n2023-09-12 13:53:51 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:374 - ********************************\n")),(0,s.kt)("p",null,"Alternatively, you can watch the diagnostic.log"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"tail -f /var/log/lightning/diagnostic.log\n")),(0,s.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}g.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>s});var r=n(7294);const s=e=>{let{image:t,name:n,title:s,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},s),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[2517],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>m});var r=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 o(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var c=r.createContext({}),i=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=i(e.components);return r.createElement(c.Provider,{value:t},e.children)},d="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,s=e.mdxType,a=e.originalType,c=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),d=i(n),g=s,m=d["".concat(c,".").concat(g)]||d[g]||p[g]||a;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function m(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var a=n.length,o=new Array(a);o[0]=g;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[d]="string"==typeof e?e:s,o[1]=l;for(var i=2;i{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>l,default:()=>g,frontMatter:()=>o,metadata:()=>c,toc:()=>u});var r=n(7462),s=(n(7294),n(3905)),a=n(3872);const o={title:"Shutting down persistance",slug:"shutting-down-persistance",hide_title:!0,tags:["reference","shutdown","frozen","idle","service error","systemctl","systemd"]},l=void 0,c={unversionedId:"Systemd/shutting-down-persistance",id:"Systemd/shutting-down-persistance",title:"Shutting down persistance",description:"\x3c!--",source:"@site/references/Systemd/shutting-down-persistance.md",sourceDirName:"Systemd",slug:"/Systemd/shutting-down-persistance",permalink:"/references/Systemd/shutting-down-persistance",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Systemd/shutting-down-persistance.md",tags:[{label:"reference",permalink:"/references/tags/reference"},{label:"shutdown",permalink:"/references/tags/shutdown"},{label:"frozen",permalink:"/references/tags/frozen"},{label:"idle",permalink:"/references/tags/idle"},{label:"service error",permalink:"/references/tags/service-error"},{label:"systemctl",permalink:"/references/tags/systemctl"},{label:"systemd",permalink:"/references/tags/systemd"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Shutting down persistance",slug:"shutting-down-persistance",hide_title:!0,tags:["reference","shutdown","frozen","idle","service error","systemctl","systemd"]},sidebar:"defaultSidebar",previous:{title:"Update CLI from source code",permalink:"/references/Lightning CLI/update-cli-from-source-code"},next:{title:"User service",permalink:"/references/Systemd/user-service"}},i={},u=[{value:"Systemd Service as frozen or idle",id:"systemd-service-as-frozen-or-idle",level:2}],d={toc:u},p="wrapper";function g(e){let{components:t,...n}=e;return(0,s.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h2",{id:"systemd-service-as-frozen-or-idle"},"Systemd Service as frozen or idle"),(0,s.kt)("p",null,"If you have a ",(0,s.kt)("inlineCode",{parentName:"p"},"Shutting node down")," message on the service log, the process is likely failing to respond to Systemd shut down command by failing to terminate all the child processes that were started by the service."),(0,s.kt)("p",null,"The logs should be similar to the following:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"2023-09-11 18:02:07 | ERROR | lightning_consensus::consensus - core/consensus/src/consensus.rs:371 - node: XsE9KtedDRUGv22MLHvy8qcc52QsWGWJYY1LBnWhglg=\n2023-09-11 18:02:07 | ERROR | lightning_consensus::consensus - core/consensus/src/consensus.rs:371 - node: zBmZaycvQsdFRfe0p5Rig/KgyYPD4yNKQTPDo7JrugM=\n2023-09-11 18:02:07 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:373 - ##################\n2023-09-11 18:02:07 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:374 - ********************************\nRPC server starting up\nlistening on 0.0.0.0:4069\nShutting node down.\nShutting node down.\nShutting node down.\nShutting node down.\nShutting node down.\n")),(0,s.kt)("p",null,"To resolve this issue, start by executing a new ",(0,s.kt)("inlineCode",{parentName:"p"},"shutdown")," command as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl stop lightning\n")),(0,s.kt)("p",null,"If you need to delegate to root, then use the ",(0,s.kt)("strong",{parentName:"p"},"sudo")," keyword, as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl stop lightning\n")),(0,s.kt)("p",null,"Once completed, clear the logs to avoid confusion as the log aggregates messages past and current."),(0,s.kt)("p",null,"Delete all the log files (output.log and diagnostic.log) by running:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo rm -f /var/log/lightning/*.log\n")),(0,s.kt)("p",null,"Launch the service:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl start lightning\n")),(0,s.kt)("p",null,"If you need to delegate to root, then use the ",(0,s.kt)("strong",{parentName:"p"},"sudo")," keyword, as follows:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl start lightning\n")),(0,s.kt)("p",null,"You can watch the log output of the service by running:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"tail -f /var/log/lightning/output.log\n")),(0,s.kt)("p",null,"The output should be similar to:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"2023-09-12 13:53:51 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:373 - ##################\n2023-09-12 13:53:51 | WARN | lightning_consensus::consensus - core/consensus/src/consensus.rs:374 - ********************************\n")),(0,s.kt)("p",null,"Alternatively, you can watch the diagnostic.log"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-sh"},"tail -f /var/log/lightning/diagnostic.log\n")),(0,s.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}g.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>s});var r=n(7294);const s=e=>{let{image:t,name:n,title:s,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},s),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.a4e6c1b1.js b/assets/js/b2f554cd.a240283d.js similarity index 99% rename from assets/js/b2f554cd.a4e6c1b1.js rename to assets/js/b2f554cd.a240283d.js index 006cb4c51..ba70b48c3 100644 --- a/assets/js/b2f554cd.a4e6c1b1.js +++ b/assets/js/b2f554cd.a240283d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"bloom-and-cuckoo-filters-for-cache-summarization","metadata":{"permalink":"/blog/bloom-and-cuckoo-filters-for-cache-summarization","source":"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md","title":"Bloom Filters and Cuckoo Filters for Cache Summarization","description":"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.","date":"2023-09-12T16:57:42.000Z","formattedDate":"September 12, 2023","tags":[{"label":"fleek network","permalink":"/blog/tags/fleek-network"},{"label":"blog","permalink":"/blog/tags/blog"},{"label":"engineering","permalink":"/blog/tags/engineering"},{"label":"content routing","permalink":"/blog/tags/content-routing"}],"readingTime":10.355,"hasTruncateMarker":true,"authors":[{"name":"Matthias Wright","title":"Software Engineer","url":"https://github.com/matthias-wright","image_url":"https://github.com/matthias-wright.png","imageURL":"https://github.com/matthias-wright.png"}],"frontMatter":{"title":"Bloom Filters and Cuckoo Filters for Cache Summarization","description":"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.","slug":"bloom-and-cuckoo-filters-for-cache-summarization","image":"./assets/bloom-cuckoo/bloom.png?202301181528","authors":{"name":"Matthias Wright","title":"Software Engineer","url":"https://github.com/matthias-wright","image_url":"https://github.com/matthias-wright.png","imageURL":"https://github.com/matthias-wright.png"},"tags":["fleek network","blog","engineering","content routing"]}},"content":"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nNodes on Fleek Network currently use Counting Bloom filters to summarize their cached content. These cache summaries are exchanged with other nodes in order to facilitate content routing.\\n\\nIf a particular node does not store a requested piece of content, it can use the Bloom filters that it received from its peers to check if a peer stores the requested content.\\n\\nWe are using Counting Bloom filters rather than regular Bloom filters because we need to be able to remove elements from the filter to support cache eviction.\\n\\n## Bloom Filters\\n\\nA Bloom filter is a space-efficient probabilistic data structure that can be used to perform approximate set membership queries.\\nThe answer to an approximate set membership query is not `no` or `yes,` but rather `no` or `probably.` This `probably` is quantified with the false positive rate. \\n\\nOne of the convenient features of Bloom filters is that they can be configured to have a specific false positive rate.\\nOf course, there is a tradeoff here; the lower the false positive rate, the larger the memory footprint. Bloom filters support two operations: `insert` and `contains.` \\n\\nA Bloom filter is represented by an array of m bits together with k independent hash functions. To insert an element into the filter, it is hashed with each of the k hash functions.\\nThe resulting hashes are interpreted as integers (modulo m) to obtain k array positions. The bits at these positions are then set to 1 (if there aren\'t already 1). \\nTo check whether or not an element is contained in the filter, the element is hashed k times with the different hash functions.\\n\\nIf all bits at the resulting array positions are 1, the element is assumed to be present. If any of the k bits are zero, we can be certain that the queried element is not present in the set.\\n\\nHowever, even if all bits are 1, it might still be the case that the bits were set by a combination of other elements. This is where the aforementioned false positive rate comes into play. \\n\\nSince we also need a `remove` operation for our use case, we have been using Counting Bloom filters, a variant of Bloom filters.\\nCounting Bloom filters retain most of the properties that regular Bloom filters have. The `remove` operation comes at the cost of an increased memory footprint.\\n\\nEach position in the array is no longer a single bit but a group of bits representing a counter.\\nWhenever an element is inserted into the filter, the counters for all k positions are incremented by 1. To remove an element, we decrement the counters.\\n\\n## Cuckoo Filters\\n\\nBloom filters are the most known members of a class of data structures called Approximate Membership Query Filters (AMQ Filters).\\nA relatively recent addition to this class is the Cuckoo filter [1]. Cuckoo filters share many similarities with Bloom filters, especially Counting Bloom filters.\\n\\nThey are space-efficient and can be used for approximate set membership queries. Cuckoo filters also support the operations `insert,` `contains,` and `remove,` and have configurable false positive rates. \\n\\nCuckoo filters are based on Cuckoo hash tables [2] and leverage an optimization called partial-key cuckoo hashing. A basic Cuckoo hash table consists of an array of buckets.\\nWe determine two candidate buckets for each element using two different hash functions, h1 and h2. \\n\\nThe `contains` operation will check if either bucket contains the element.\\nFor insertion, if either bucket is empty, the element will be inserted into the empty bucket.\\n\\nIf neither bucket is empty, one of the buckets is selected, and the existing element is removed and inserted into its alternate location.\\nThis may trigger another relocation if the alternate location is not empty. \\n\\nAlthough the insertion operation may perform a sequence of relocations, the amortized runtime is O(1). \\n\\nMost implementations of Cuckoo hash tables and, consequently, Cuckoo filters will use buckets that can hold multiple elements, as proposed in [3].\\n\\nFor Cuckoo filters, the hash table size is reduced by only storing fingerprints - a bit string calculated from an element\'s hash - rather than key-value pairs.\\n\\nThe fingerprint size is derived from the desired false positive rate. \\nA problem that arises is that, to relocate existing fingerprints using the Cuckoo hashing approach described above, we need the original hash from which the fingerprint was derived.\\n\\nOf course, we could store this hash somewhere, but the whole point of using fingerprints is to reduce the memory footprint of the filter.\\n\\nThe solution to this predicament is the aforementioned partial-key cuckoo hashing, a technique for determining an element\'s alternate location using only its fingerprint. \\nFor a given element x, the two candidate buckets are computed as follows: \\n\\n\\n\x3c!-- \\nTODO: Install math forms renderer, till then use img\\n\\n$h_1(x) = \\\\text{hash}(x)$\\n\\n$h_2(x) = h_1(x) \\\\oplus \\\\text{hash}(\\\\text{fingerprint}(x))$\\n--\x3e\\n\\n![](./assets/bloom-cuckoo/math-formul.png?202301181528)\\n\\nAn important property of this technique is that h1(x) can also be computed from h2(x) and the fingerprint.\\n\\n## Benchmarking\\n\\nAs this post mentioned, we are not aiming for a general comparison of Counting Bloom and Cuckoo filters.\\n\\nInstead, we want to determine which filter suits our specific use case better. The two main properties we are looking for are space efficiency and lookup performance. \\n\\nSpace efficiency is important because nodes frequently update their cache and have to communicate these changes with their peers. These messages should take up as little bandwidth as possible.\\n\\nLookup speed is also important because Fleek Network aims to serve user requests as quickly as possible. Checking whether a peer has some content stored in their cache summary should not be a bottleneck. \\n\\n## Experimental Setup\\n\\nWe are using our own Counting Bloom filter [implementation](https://github.com/fleek-network/ursa/blob/483f4d56cbaa5e83182454d2c1db6f6af7c54912/crates/ursa-network/src/utils/bloom_filter.rs#L11) and \\n[this](https://github.com/sile/scalable_cuckoo_filter) Cuckoo filter implementation in Rust (the [original](https://github.com/efficient/cuckoofilter) implementation is in C++). All experiments\\nwere performed on a Linux machine with 16 GB RAM and an Intel Core i7 (10th Gen). Whenever the experiment is probabilistic, we repeat the experiment 20 times and report the mean and standard deviation.\\n\\n## Memory Footprint\\n\\nFor both Counting Bloom filters and Cuckoo filters, the memory footprint is determined by two factors: the filter\'s capacity and the desired false positive rate. In the first experiment, we examine the impact that\\nthese factors have on the memory footprint. \\n\\nTo this end, we fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The result is shown in Fig. 1. \\nThe size of Bloom filters scales linearly with the capacity. Cuckoo filters are more space-efficient. This result is consistent with the experiments reported in [1].\\n\\n![](./assets/bloom-cuckoo/capacity-size.png?202301121718)\\n\\n> Figure 1: We fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The y-axis shows the size of the filters in Megabytes.\\n\\nNext, we fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. Fig. 2 shows that Cuckoo filters are more space-efficient.\\n\\nThe gap between Counting Bloom filters and Cuckoo filters grows as the false positive rate decreases. This is also consistent with experiments in [1].\\n\\n![](./assets/bloom-cuckoo/fp-rate-size.png?202301121718)\\n\\n> Figure 2: We fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. The y-axis shows the size of the filters in Megabytes.\\n\\n## Lookup Performance\\n\\nWe first add elements to both filters until the capacity is reached. We then measure the lookup performance for different ratios of positive and negative lookups.\\n\\nA positive lookup is for an existing element, and a negative lookup is for an element not contained in the filter. We perform 100K lookups for each ratio and report the average lookup duration and standard deviation. \\n\\nFig. 3 shows the results. Bloom filters perform slightly better on average than Cuckoo filters. This result is inconsistent with [1],\\nwhere Cuckoo filters were reported to have a better lookup performance than Bloom filters. It should be noted here that the authors in [1] use the original C++ Cuckoo filter implementation and their own unreleased Bloom filter implementation. In contrast, we use a Rust Cuckoo filter implementation and our Bloom filter implementation. We cannot easily determine the reason for this discrepancy.\\n\\nHowever, the performance difference is negligible.\\n\\n![](./assets/bloom-cuckoo/lookup.png?202301121718)\\n\\n> Figure 3: Lookup performance for different ratios of positive and negative lookups. For example, ratio 0.25 indicates that 25% of lookups are positive and 75% are negative.\\nThe shaded region indicates the standard deviation.\\n\\n## Insertion Performance\\n\\nLess critical than lookup performance but still important for our purposes is insertion performance. We measure how the insertion performance varies for different occupancy levels.\\nFig. 4 shows the results. The insertion performance is constant across all levels of occupancy for Bloom filters.\\n\\nFor Cuckoo filters, the performance decreases as the filter becomes fuller because more relocations are required. In Fig. 4, the performance for Bloom filters is not constant. It quickly increases and then remains constant. This can be explained by CPU caching. \\n\\n![](./assets/bloom-cuckoo/insert.png?202301121718)\\n\\n> Figure 4: Insertion performance for different occupancy levels. The shaded region indicates the standard deviation.\\n\\n## Capacity and Scaling\\n\\nWe have mentioned the capacity of a filter several times now. An interesting case is what happens when a filter\'s capacity is exceeded.\\nBloom filters and Cuckoo filters behave differently in this scenario.\\n\\nFor Bloom filters, the `insertion` operation always succeeds. However, the false positive rate will rapidly increase as we exceed the filter\'s capacity. While Bloom filters fail silently, Cuckoo filters are more explicit. Most implementations have a maximum number of\\nrelocations that will be performed for an insertion. The `insertion` operation will return an error if more relocations are required. \\n\\nFor both filters, we can avoid this problem by simply initializing the filter with a sufficiently large capacity. However, this will increase the memory footprint of the filter.\\n\\nFurthermore, it is difficult to predict how many elements a node on Fleek Network will cache. It is also likely that the number of cached elements will greatly vary for different nodes. \\n\\nFortunately, a variant of Bloom filters called Scalable Bloom Filters [4] can adapt dynamically to the number of elements stored while guaranteeing a maximum false positive rate.\\n\\nThe proposed technique is also applicable to Cuckoo filters.\\n\\n## Other Filters\\n\\nWhile we only looked at Bloom filters and Cuckoo filters, there are other AMQ filters that we want to mention here briefly:\\n\\n* Quotient filters [5, 6]: Compact hash tables that support insertion, lookup, and deletion. Less space-efficient than Bloom filters and Cuckoo filters. \\n\\n* XOR filters [7]: More space-efficient than Bloom filters and Cuckoo filters. However, they are static, meaning the filter has to be rebuilt if additional elements are added. \\n\\n## Conclusion\\n\\nWe examined whether Counting Bloom filters or Cuckoo filters are more suitable for summarizing caches on Fleek Network. Cuckoo filters are more space-efficient, especially for lower false positive rates. Bloom filters have a slightly better insertion and lookup performance for the implementations we tested.\\n\\nBoth filters can be adapted to grow and shrink in size dynamically. Since the difference in insertion and lookup performance is negligible while Cuckoo filters are significantly more space-efficient, we favor Cuckoo filters for our use case. \\n\\n### References\\n\\n[1] Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher. Cuckoo Filter: Practically Better Than Bloom.\\nIn Proceedings of the 10th ACM International Conference on emerging Networking Experiments and Technologies (CoNEXT 14). Association for Computing Machinery, New York, NY, USA, pp. 75-88, 2014. \\n\\n[2] Rasmus Pagha and Flemming Friche Rodler. Cuckoo hashing. Journal of Algorithms, 51(2), pp. 122-144, 2004. \\n\\n[3] Martin Dietzfelbinger and Christoph Weidling. Balanced Allocation and Dictionaries with Tightly Packed Constant Size Bins. Theoretical Computer Science, 380(1), pp. 47-68, 2007. \\n\\n[4] Paulo S. Almeida, Carlos Baquero, Nuno Pregui\xe7a, and David Hutchison. Scalable Bloom Filters. Information Processing Letters, 101(6), pp. 255-261, 2007. \\n\\n[5] John G. Cleary. Compact hash tables using bidirectional linear probing. IEEE Transactions on Computers. 33(9), pp. 828-834, 1984. \\n\\n[6] Anna Pagh, Rasmus Pagh, and S. Srinivasa Rao. An optimal Bloom filter replacement. Proceedings of the Sixteenth Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 823-829, 2005. \\n \\n[7] Thomas Mueller Graf and Daniel Lemire. Xor Filters: Faster and Smaller Than Bloom and Cuckoo Filters. ACM Journal of Experimental Algorithmics. 25, pp. 1-16, 2020."}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1477],{10:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"bloom-and-cuckoo-filters-for-cache-summarization","metadata":{"permalink":"/blog/bloom-and-cuckoo-filters-for-cache-summarization","source":"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md","title":"Bloom Filters and Cuckoo Filters for Cache Summarization","description":"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.","date":"2023-09-13T11:07:59.000Z","formattedDate":"September 13, 2023","tags":[{"label":"fleek network","permalink":"/blog/tags/fleek-network"},{"label":"blog","permalink":"/blog/tags/blog"},{"label":"engineering","permalink":"/blog/tags/engineering"},{"label":"content routing","permalink":"/blog/tags/content-routing"}],"readingTime":10.355,"hasTruncateMarker":true,"authors":[{"name":"Matthias Wright","title":"Software Engineer","url":"https://github.com/matthias-wright","image_url":"https://github.com/matthias-wright.png","imageURL":"https://github.com/matthias-wright.png"}],"frontMatter":{"title":"Bloom Filters and Cuckoo Filters for Cache Summarization","description":"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.","slug":"bloom-and-cuckoo-filters-for-cache-summarization","image":"./assets/bloom-cuckoo/bloom.png?202301181528","authors":{"name":"Matthias Wright","title":"Software Engineer","url":"https://github.com/matthias-wright","image_url":"https://github.com/matthias-wright.png","imageURL":"https://github.com/matthias-wright.png"},"tags":["fleek network","blog","engineering","content routing"]}},"content":"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case.\\n\\n\x3c!--truncate--\x3e\\n\\n## Background\\n\\nNodes on Fleek Network currently use Counting Bloom filters to summarize their cached content. These cache summaries are exchanged with other nodes in order to facilitate content routing.\\n\\nIf a particular node does not store a requested piece of content, it can use the Bloom filters that it received from its peers to check if a peer stores the requested content.\\n\\nWe are using Counting Bloom filters rather than regular Bloom filters because we need to be able to remove elements from the filter to support cache eviction.\\n\\n## Bloom Filters\\n\\nA Bloom filter is a space-efficient probabilistic data structure that can be used to perform approximate set membership queries.\\nThe answer to an approximate set membership query is not `no` or `yes,` but rather `no` or `probably.` This `probably` is quantified with the false positive rate. \\n\\nOne of the convenient features of Bloom filters is that they can be configured to have a specific false positive rate.\\nOf course, there is a tradeoff here; the lower the false positive rate, the larger the memory footprint. Bloom filters support two operations: `insert` and `contains.` \\n\\nA Bloom filter is represented by an array of m bits together with k independent hash functions. To insert an element into the filter, it is hashed with each of the k hash functions.\\nThe resulting hashes are interpreted as integers (modulo m) to obtain k array positions. The bits at these positions are then set to 1 (if there aren\'t already 1). \\nTo check whether or not an element is contained in the filter, the element is hashed k times with the different hash functions.\\n\\nIf all bits at the resulting array positions are 1, the element is assumed to be present. If any of the k bits are zero, we can be certain that the queried element is not present in the set.\\n\\nHowever, even if all bits are 1, it might still be the case that the bits were set by a combination of other elements. This is where the aforementioned false positive rate comes into play. \\n\\nSince we also need a `remove` operation for our use case, we have been using Counting Bloom filters, a variant of Bloom filters.\\nCounting Bloom filters retain most of the properties that regular Bloom filters have. The `remove` operation comes at the cost of an increased memory footprint.\\n\\nEach position in the array is no longer a single bit but a group of bits representing a counter.\\nWhenever an element is inserted into the filter, the counters for all k positions are incremented by 1. To remove an element, we decrement the counters.\\n\\n## Cuckoo Filters\\n\\nBloom filters are the most known members of a class of data structures called Approximate Membership Query Filters (AMQ Filters).\\nA relatively recent addition to this class is the Cuckoo filter [1]. Cuckoo filters share many similarities with Bloom filters, especially Counting Bloom filters.\\n\\nThey are space-efficient and can be used for approximate set membership queries. Cuckoo filters also support the operations `insert,` `contains,` and `remove,` and have configurable false positive rates. \\n\\nCuckoo filters are based on Cuckoo hash tables [2] and leverage an optimization called partial-key cuckoo hashing. A basic Cuckoo hash table consists of an array of buckets.\\nWe determine two candidate buckets for each element using two different hash functions, h1 and h2. \\n\\nThe `contains` operation will check if either bucket contains the element.\\nFor insertion, if either bucket is empty, the element will be inserted into the empty bucket.\\n\\nIf neither bucket is empty, one of the buckets is selected, and the existing element is removed and inserted into its alternate location.\\nThis may trigger another relocation if the alternate location is not empty. \\n\\nAlthough the insertion operation may perform a sequence of relocations, the amortized runtime is O(1). \\n\\nMost implementations of Cuckoo hash tables and, consequently, Cuckoo filters will use buckets that can hold multiple elements, as proposed in [3].\\n\\nFor Cuckoo filters, the hash table size is reduced by only storing fingerprints - a bit string calculated from an element\'s hash - rather than key-value pairs.\\n\\nThe fingerprint size is derived from the desired false positive rate. \\nA problem that arises is that, to relocate existing fingerprints using the Cuckoo hashing approach described above, we need the original hash from which the fingerprint was derived.\\n\\nOf course, we could store this hash somewhere, but the whole point of using fingerprints is to reduce the memory footprint of the filter.\\n\\nThe solution to this predicament is the aforementioned partial-key cuckoo hashing, a technique for determining an element\'s alternate location using only its fingerprint. \\nFor a given element x, the two candidate buckets are computed as follows: \\n\\n\\n\x3c!-- \\nTODO: Install math forms renderer, till then use img\\n\\n$h_1(x) = \\\\text{hash}(x)$\\n\\n$h_2(x) = h_1(x) \\\\oplus \\\\text{hash}(\\\\text{fingerprint}(x))$\\n--\x3e\\n\\n![](./assets/bloom-cuckoo/math-formul.png?202301181528)\\n\\nAn important property of this technique is that h1(x) can also be computed from h2(x) and the fingerprint.\\n\\n## Benchmarking\\n\\nAs this post mentioned, we are not aiming for a general comparison of Counting Bloom and Cuckoo filters.\\n\\nInstead, we want to determine which filter suits our specific use case better. The two main properties we are looking for are space efficiency and lookup performance. \\n\\nSpace efficiency is important because nodes frequently update their cache and have to communicate these changes with their peers. These messages should take up as little bandwidth as possible.\\n\\nLookup speed is also important because Fleek Network aims to serve user requests as quickly as possible. Checking whether a peer has some content stored in their cache summary should not be a bottleneck. \\n\\n## Experimental Setup\\n\\nWe are using our own Counting Bloom filter [implementation](https://github.com/fleek-network/ursa/blob/483f4d56cbaa5e83182454d2c1db6f6af7c54912/crates/ursa-network/src/utils/bloom_filter.rs#L11) and \\n[this](https://github.com/sile/scalable_cuckoo_filter) Cuckoo filter implementation in Rust (the [original](https://github.com/efficient/cuckoofilter) implementation is in C++). All experiments\\nwere performed on a Linux machine with 16 GB RAM and an Intel Core i7 (10th Gen). Whenever the experiment is probabilistic, we repeat the experiment 20 times and report the mean and standard deviation.\\n\\n## Memory Footprint\\n\\nFor both Counting Bloom filters and Cuckoo filters, the memory footprint is determined by two factors: the filter\'s capacity and the desired false positive rate. In the first experiment, we examine the impact that\\nthese factors have on the memory footprint. \\n\\nTo this end, we fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The result is shown in Fig. 1. \\nThe size of Bloom filters scales linearly with the capacity. Cuckoo filters are more space-efficient. This result is consistent with the experiments reported in [1].\\n\\n![](./assets/bloom-cuckoo/capacity-size.png?202301121718)\\n\\n> Figure 1: We fix the false positive rate and initialize the filters with capacities ranging from 100K to 1M. The y-axis shows the size of the filters in Megabytes.\\n\\nNext, we fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. Fig. 2 shows that Cuckoo filters are more space-efficient.\\n\\nThe gap between Counting Bloom filters and Cuckoo filters grows as the false positive rate decreases. This is also consistent with experiments in [1].\\n\\n![](./assets/bloom-cuckoo/fp-rate-size.png?202301121718)\\n\\n> Figure 2: We fix the capacity and initialize the filters with false positive rates ranging from 0.0001 to 0.5. The y-axis shows the size of the filters in Megabytes.\\n\\n## Lookup Performance\\n\\nWe first add elements to both filters until the capacity is reached. We then measure the lookup performance for different ratios of positive and negative lookups.\\n\\nA positive lookup is for an existing element, and a negative lookup is for an element not contained in the filter. We perform 100K lookups for each ratio and report the average lookup duration and standard deviation. \\n\\nFig. 3 shows the results. Bloom filters perform slightly better on average than Cuckoo filters. This result is inconsistent with [1],\\nwhere Cuckoo filters were reported to have a better lookup performance than Bloom filters. It should be noted here that the authors in [1] use the original C++ Cuckoo filter implementation and their own unreleased Bloom filter implementation. In contrast, we use a Rust Cuckoo filter implementation and our Bloom filter implementation. We cannot easily determine the reason for this discrepancy.\\n\\nHowever, the performance difference is negligible.\\n\\n![](./assets/bloom-cuckoo/lookup.png?202301121718)\\n\\n> Figure 3: Lookup performance for different ratios of positive and negative lookups. For example, ratio 0.25 indicates that 25% of lookups are positive and 75% are negative.\\nThe shaded region indicates the standard deviation.\\n\\n## Insertion Performance\\n\\nLess critical than lookup performance but still important for our purposes is insertion performance. We measure how the insertion performance varies for different occupancy levels.\\nFig. 4 shows the results. The insertion performance is constant across all levels of occupancy for Bloom filters.\\n\\nFor Cuckoo filters, the performance decreases as the filter becomes fuller because more relocations are required. In Fig. 4, the performance for Bloom filters is not constant. It quickly increases and then remains constant. This can be explained by CPU caching. \\n\\n![](./assets/bloom-cuckoo/insert.png?202301121718)\\n\\n> Figure 4: Insertion performance for different occupancy levels. The shaded region indicates the standard deviation.\\n\\n## Capacity and Scaling\\n\\nWe have mentioned the capacity of a filter several times now. An interesting case is what happens when a filter\'s capacity is exceeded.\\nBloom filters and Cuckoo filters behave differently in this scenario.\\n\\nFor Bloom filters, the `insertion` operation always succeeds. However, the false positive rate will rapidly increase as we exceed the filter\'s capacity. While Bloom filters fail silently, Cuckoo filters are more explicit. Most implementations have a maximum number of\\nrelocations that will be performed for an insertion. The `insertion` operation will return an error if more relocations are required. \\n\\nFor both filters, we can avoid this problem by simply initializing the filter with a sufficiently large capacity. However, this will increase the memory footprint of the filter.\\n\\nFurthermore, it is difficult to predict how many elements a node on Fleek Network will cache. It is also likely that the number of cached elements will greatly vary for different nodes. \\n\\nFortunately, a variant of Bloom filters called Scalable Bloom Filters [4] can adapt dynamically to the number of elements stored while guaranteeing a maximum false positive rate.\\n\\nThe proposed technique is also applicable to Cuckoo filters.\\n\\n## Other Filters\\n\\nWhile we only looked at Bloom filters and Cuckoo filters, there are other AMQ filters that we want to mention here briefly:\\n\\n* Quotient filters [5, 6]: Compact hash tables that support insertion, lookup, and deletion. Less space-efficient than Bloom filters and Cuckoo filters. \\n\\n* XOR filters [7]: More space-efficient than Bloom filters and Cuckoo filters. However, they are static, meaning the filter has to be rebuilt if additional elements are added. \\n\\n## Conclusion\\n\\nWe examined whether Counting Bloom filters or Cuckoo filters are more suitable for summarizing caches on Fleek Network. Cuckoo filters are more space-efficient, especially for lower false positive rates. Bloom filters have a slightly better insertion and lookup performance for the implementations we tested.\\n\\nBoth filters can be adapted to grow and shrink in size dynamically. Since the difference in insertion and lookup performance is negligible while Cuckoo filters are significantly more space-efficient, we favor Cuckoo filters for our use case. \\n\\n### References\\n\\n[1] Bin Fan, Dave G. Andersen, Michael Kaminsky, and Michael D. Mitzenmacher. Cuckoo Filter: Practically Better Than Bloom.\\nIn Proceedings of the 10th ACM International Conference on emerging Networking Experiments and Technologies (CoNEXT 14). Association for Computing Machinery, New York, NY, USA, pp. 75-88, 2014. \\n\\n[2] Rasmus Pagha and Flemming Friche Rodler. Cuckoo hashing. Journal of Algorithms, 51(2), pp. 122-144, 2004. \\n\\n[3] Martin Dietzfelbinger and Christoph Weidling. Balanced Allocation and Dictionaries with Tightly Packed Constant Size Bins. Theoretical Computer Science, 380(1), pp. 47-68, 2007. \\n\\n[4] Paulo S. Almeida, Carlos Baquero, Nuno Pregui\xe7a, and David Hutchison. Scalable Bloom Filters. Information Processing Letters, 101(6), pp. 255-261, 2007. \\n\\n[5] John G. Cleary. Compact hash tables using bidirectional linear probing. IEEE Transactions on Computers. 33(9), pp. 828-834, 1984. \\n\\n[6] Anna Pagh, Rasmus Pagh, and S. Srinivasa Rao. An optimal Bloom filter replacement. Proceedings of the Sixteenth Annual ACM-SIAM Symposium on Discrete Algorithms, pp. 823-829, 2005. \\n \\n[7] Thomas Mueller Graf and Daniel Lemire. Xor Filters: Faster and Smaller Than Bloom and Cuckoo Filters. ACM Journal of Experimental Algorithmics. 25, pp. 1-16, 2020."}]}')}}]); \ No newline at end of file diff --git a/assets/js/b35f1b7f.ba499ed0.js b/assets/js/b35f1b7f.7bff8be2.js similarity index 98% rename from assets/js/b35f1b7f.ba499ed0.js rename to assets/js/b35f1b7f.7bff8be2.js index fdb0e21f6..16d8c26c5 100644 --- a/assets/js/b35f1b7f.ba499ed0.js +++ b/assets/js/b35f1b7f.7bff8be2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[7706],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>h});var s=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,s)}return r}function l(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var o=s.createContext({}),u=function(e){var t=s.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return s.createElement(o.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},d=s.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,o=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=n,h=p["".concat(o,".").concat(d)]||p[d]||m[d]||a;return r?s.createElement(h,l(l({ref:t},c),{},{components:r})):s.createElement(h,l({ref:t},c))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,l=new Array(a);l[0]=d;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[p]="string"==typeof e?e:n,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var s=r(7462),n=(r(7294),r(3905)),a=r(3872);const l={title:"User service",slug:"user-service",hide_title:!0,tags:["references","help","user service","unit","systemctl","systemd"]},i=void 0,o={unversionedId:"Systemd/user-service",id:"Systemd/user-service",title:"User service",description:"\x3c!--",source:"@site/references/Systemd/user-service.md",sourceDirName:"Systemd",slug:"/Systemd/user-service",permalink:"/references/Systemd/user-service",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Systemd/user-service.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"user service",permalink:"/references/tags/user-service"},{label:"unit",permalink:"/references/tags/unit"},{label:"systemctl",permalink:"/references/tags/systemctl"},{label:"systemd",permalink:"/references/tags/systemd"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"User service",slug:"user-service",hide_title:!0,tags:["references","help","user service","unit","systemctl","systemd"]},sidebar:"defaultSidebar",previous:{title:"Shutting down persistance",permalink:"/references/Systemd/shutting-down-persistance"}},u={},c=[{value:"Check --user support",id:"check---user-support",level:2},{value:"Put the service unit in the user service",id:"put-the-service-unit-in-the-user-service",level:2},{value:"Systemd service control as --user",id:"systemd-service-control-as---user",level:2},{value:"Problem statement",id:"problem-statement",level:2}],p={toc:c},m="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,s.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"A user should have the ability to run a Systemd user service unit without having to use ",(0,n.kt)("inlineCode",{parentName:"p"},"sudo")," to control it."),(0,n.kt)("h2",{id:"check---user-support"},"Check ",(0,n.kt)("inlineCode",{parentName:"h2"},"--user")," support"),(0,n.kt)("p",null,"Use the ",(0,n.kt)("inlineCode",{parentName:"p"},"--user")," flag when getting the list of unit files."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user list-unit-files\n")),(0,n.kt)("p",null,"It should return a list of unit files."),(0,n.kt)("h2",{id:"put-the-service-unit-in-the-user-service"},"Put the service unit in the user service"),(0,n.kt)("p",null,"Create the Systemd user units directory:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mkdir -p /etc/systemd/system/user\n")),(0,n.kt)("p",null,"Move the ",(0,n.kt)("inlineCode",{parentName:"p"},"lightning.service")," to the system user unit service directory:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"mv /etc/systemd/system/lightning.service /etc/systemd/system/user/lightning.service\n")),(0,n.kt)("p",null,"Check the ",(0,n.kt)("strong",{parentName:"p"},"Load path when running in user mode (--user)")," in ",(0,n.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.unit.html"},"Systemd unit")," for other alternative user paths, or to understand how it works to customize your server accordingly."),(0,n.kt)("p",null,"##\xa0Reload daemon"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,n.kt)("h2",{id:"systemd-service-control-as---user"},"Systemd service control as ",(0,n.kt)("inlineCode",{parentName:"h2"},"--user")),(0,n.kt)("p",null,"Reload the Systemctl daemon by executing the command:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user daemon-reload\n")),(0,n.kt)("p",null,"Enable the service for starting up on system boot:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user enable lightning.service\n")),(0,n.kt)("p",null,"Start the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user start lightning\n")),(0,n.kt)("p",null,"Stop the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user stop lightning\n")),(0,n.kt)("p",null,"Restart the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user restart lightning\n")),(0,n.kt)("p",null,"Check the service status by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user status lightning.service\n")),(0,n.kt)("h2",{id:"problem-statement"},"Problem statement"),(0,n.kt)("p",null,"On tests done in a DigitalOcean Ubuntu 22.x, we had setup user-level services which were operated with ",(0,n.kt)("inlineCode",{parentName:"p"},"--user"),". When the commands were executed as ",(0,n.kt)("inlineCode",{parentName:"p"},"--user")," it failed with:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"Failed to connect to bus: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)\n")),(0,n.kt)("p",null,"The user should be able to operate as user, it shouldn't be required to connect on behalf of other users. This means that even for a simple command, such as to retrieve the list of unit files:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user list-unit-files\n")),(0,n.kt)("p",null,"We'd get the error:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"Failed to connect to bus: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)\n")),(0,n.kt)("p",null,"For any of the supported user unit locations e.g. $HOME/.config/systemd/user as documented in ",(0,n.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.unit.html"},"Systemd unit documentation"),", the result is the error above."),(0,n.kt)("p",null,"This is related to the load paths when running in user mode (--user), as described in the discussion ",(0,n.kt)("a",{parentName:"p",href:"https://unix.stackexchange.com/questions/224992/where-do-i-put-my-systemd-unit-file/367237#367237"},"here"),"."),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"User-dependent")),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_CONFIG_HOME/systemd/user")," User configuration (only used when $XDG_CONFIG_HOME is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$HOME/.config/systemd/user")," User configuration (only used when $XDG_CONFIG_HOME is not set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_RUNTIME_DIR/systemd/user")," Runtime units (only used when $XDG_RUNTIME_DIR is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_DATA_HOME/systemd/user")," Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$HOME/.local/share/systemd/user")," Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)"),(0,n.kt)("p",null,"For example, if we check the ",(0,n.kt)("inlineCode",{parentName:"p"},"$XDG_RUNTIME_DIR")," in a DigitalOcean box, we get the following output:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"/run/user/0\n")),(0,n.kt)("p",null,"For this reason and to provide support for a wider audience of users and systems, we've stuck to sudo to execute the service, but this should not be a requirement and is not recommended."),(0,n.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}d.isMDXComponent=!0},3872:(e,t,r)=>{r.d(t,{Z:()=>n});var s=r(7294);const n=e=>{let{image:t,name:r,title:n,url:a}=e;return s.createElement("section",{className:"author_card"},s.createElement("div",null,s.createElement("span",{className:"avatar"},s.createElement("a",{href:a,target:"_blank",alt:r},s.createElement("img",{src:t,alt:r}))),s.createElement("div",null,s.createElement("span",{className:"name"},s.createElement("a",{href:a,target:"_blank",alt:r},r)),s.createElement("span",{className:"title"},n),s.createElement("span",{className:"discord"},"Got questions? Find us on ",s.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[7706],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>h});var s=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);t&&(s=s.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,s)}return r}function l(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(s=0;s=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var o=s.createContext({}),u=function(e){var t=s.useContext(o),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},c=function(e){var t=u(e.components);return s.createElement(o.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return s.createElement(s.Fragment,{},t)}},d=s.forwardRef((function(e,t){var r=e.components,n=e.mdxType,a=e.originalType,o=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=n,h=p["".concat(o,".").concat(d)]||p[d]||m[d]||a;return r?s.createElement(h,l(l({ref:t},c),{},{components:r})):s.createElement(h,l({ref:t},c))}));function h(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var a=r.length,l=new Array(a);l[0]=d;var i={};for(var o in t)hasOwnProperty.call(t,o)&&(i[o]=t[o]);i.originalType=e,i[p]="string"==typeof e?e:n,l[1]=i;for(var u=2;u{r.r(t),r.d(t,{assets:()=>u,contentTitle:()=>i,default:()=>d,frontMatter:()=>l,metadata:()=>o,toc:()=>c});var s=r(7462),n=(r(7294),r(3905)),a=r(3872);const l={title:"User service",slug:"user-service",hide_title:!0,tags:["references","help","user service","unit","systemctl","systemd"]},i=void 0,o={unversionedId:"Systemd/user-service",id:"Systemd/user-service",title:"User service",description:"\x3c!--",source:"@site/references/Systemd/user-service.md",sourceDirName:"Systemd",slug:"/Systemd/user-service",permalink:"/references/Systemd/user-service",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Systemd/user-service.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"user service",permalink:"/references/tags/user-service"},{label:"unit",permalink:"/references/tags/unit"},{label:"systemctl",permalink:"/references/tags/systemctl"},{label:"systemd",permalink:"/references/tags/systemd"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"User service",slug:"user-service",hide_title:!0,tags:["references","help","user service","unit","systemctl","systemd"]},sidebar:"defaultSidebar",previous:{title:"Shutting down persistance",permalink:"/references/Systemd/shutting-down-persistance"}},u={},c=[{value:"Check --user support",id:"check---user-support",level:2},{value:"Put the service unit in the user service",id:"put-the-service-unit-in-the-user-service",level:2},{value:"Systemd service control as --user",id:"systemd-service-control-as---user",level:2},{value:"Problem statement",id:"problem-statement",level:2}],p={toc:c},m="wrapper";function d(e){let{components:t,...r}=e;return(0,n.kt)(m,(0,s.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"A user should have the ability to run a Systemd user service unit without having to use ",(0,n.kt)("inlineCode",{parentName:"p"},"sudo")," to control it."),(0,n.kt)("h2",{id:"check---user-support"},"Check ",(0,n.kt)("inlineCode",{parentName:"h2"},"--user")," support"),(0,n.kt)("p",null,"Use the ",(0,n.kt)("inlineCode",{parentName:"p"},"--user")," flag when getting the list of unit files."),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user list-unit-files\n")),(0,n.kt)("p",null,"It should return a list of unit files."),(0,n.kt)("h2",{id:"put-the-service-unit-in-the-user-service"},"Put the service unit in the user service"),(0,n.kt)("p",null,"Create the Systemd user units directory:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"sudo mkdir -p /etc/systemd/system/user\n")),(0,n.kt)("p",null,"Move the ",(0,n.kt)("inlineCode",{parentName:"p"},"lightning.service")," to the system user unit service directory:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"mv /etc/systemd/system/lightning.service /etc/systemd/system/user/lightning.service\n")),(0,n.kt)("p",null,"Check the ",(0,n.kt)("strong",{parentName:"p"},"Load path when running in user mode (--user)")," in ",(0,n.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.unit.html"},"Systemd unit")," for other alternative user paths, or to understand how it works to customize your server accordingly."),(0,n.kt)("p",null,"##\xa0Reload daemon"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,n.kt)("h2",{id:"systemd-service-control-as---user"},"Systemd service control as ",(0,n.kt)("inlineCode",{parentName:"h2"},"--user")),(0,n.kt)("p",null,"Reload the Systemctl daemon by executing the command:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user daemon-reload\n")),(0,n.kt)("p",null,"Enable the service for starting up on system boot:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user enable lightning.service\n")),(0,n.kt)("p",null,"Start the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user start lightning\n")),(0,n.kt)("p",null,"Stop the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user stop lightning\n")),(0,n.kt)("p",null,"Restart the service by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user restart lightning\n")),(0,n.kt)("p",null,"Check the service status by:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user status lightning.service\n")),(0,n.kt)("h2",{id:"problem-statement"},"Problem statement"),(0,n.kt)("p",null,"On tests done in a DigitalOcean Ubuntu 22.x, we had setup user-level services which were operated with ",(0,n.kt)("inlineCode",{parentName:"p"},"--user"),". When the commands were executed as ",(0,n.kt)("inlineCode",{parentName:"p"},"--user")," it failed with:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"Failed to connect to bus: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)\n")),(0,n.kt)("p",null,"The user should be able to operate as user, it shouldn't be required to connect on behalf of other users. This means that even for a simple command, such as to retrieve the list of unit files:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"systemctl --user list-unit-files\n")),(0,n.kt)("p",null,"We'd get the error:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"Failed to connect to bus: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)\n")),(0,n.kt)("p",null,"For any of the supported user unit locations e.g. $HOME/.config/systemd/user as documented in ",(0,n.kt)("a",{parentName:"p",href:"https://www.freedesktop.org/software/systemd/man/systemd.unit.html"},"Systemd unit documentation"),", the result is the error above."),(0,n.kt)("p",null,"This is related to the load paths when running in user mode (--user), as described in the discussion ",(0,n.kt)("a",{parentName:"p",href:"https://unix.stackexchange.com/questions/224992/where-do-i-put-my-systemd-unit-file/367237#367237"},"here"),"."),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"User-dependent")),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_CONFIG_HOME/systemd/user")," User configuration (only used when $XDG_CONFIG_HOME is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$HOME/.config/systemd/user")," User configuration (only used when $XDG_CONFIG_HOME is not set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_RUNTIME_DIR/systemd/user")," Runtime units (only used when $XDG_RUNTIME_DIR is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$XDG_DATA_HOME/systemd/user")," Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is set)"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"$HOME/.local/share/systemd/user")," Units of packages that have been installed in the home directory (only used when $XDG_DATA_HOME is not set)"),(0,n.kt)("p",null,"For example, if we check the ",(0,n.kt)("inlineCode",{parentName:"p"},"$XDG_RUNTIME_DIR")," in a DigitalOcean box, we get the following output:"),(0,n.kt)("pre",null,(0,n.kt)("code",{parentName:"pre",className:"language-sh"},"/run/user/0\n")),(0,n.kt)("p",null,"For this reason and to provide support for a wider audience of users and systems, we've stuck to sudo to execute the service, but this should not be a requirement and is not recommended."),(0,n.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}d.isMDXComponent=!0},3872:(e,t,r)=>{r.d(t,{Z:()=>n});var s=r(7294);const n=e=>{let{image:t,name:r,title:n,url:a}=e;return s.createElement("section",{className:"author_card"},s.createElement("div",null,s.createElement("span",{className:"avatar"},s.createElement("a",{href:a,target:"_blank",alt:r},s.createElement("img",{src:t,alt:r}))),s.createElement("div",null,s.createElement("span",{className:"name"},s.createElement("a",{href:a,target:"_blank",alt:r},r)),s.createElement("span",{className:"title"},n),s.createElement("span",{className:"discord"},"Got questions? Find us on ",s.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/b8466c91.1d301634.js b/assets/js/b8466c91.1d301634.js deleted file mode 100644 index 1c72bb05e..000000000 --- a/assets/js/b8466c91.1d301634.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4939],{942:e=>{e.exports=JSON.parse('{"label":"setup","permalink":"/guides/tags/setup","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b8466c91.b9b0588b.js b/assets/js/b8466c91.b9b0588b.js new file mode 100644 index 000000000..edadb9868 --- /dev/null +++ b/assets/js/b8466c91.b9b0588b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4939],{942:e=>{e.exports=JSON.parse('{"label":"setup","permalink":"/guides/tags/setup","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/transfering-setup-ownership"}]}')}}]); \ No newline at end of file diff --git a/assets/js/d1b78a4d.29570cf0.js b/assets/js/d1b78a4d.bc432b6b.js similarity index 98% rename from assets/js/d1b78a4d.29570cf0.js rename to assets/js/d1b78a4d.bc432b6b.js index 87e012ef2..ca992c5cf 100644 --- a/assets/js/d1b78a4d.29570cf0.js +++ b/assets/js/d1b78a4d.bc432b6b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3023],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>f});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function a(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=o.createContext({}),s=function(e){var t=o.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},m=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=s(r),p=n,f=u["".concat(c,".").concat(p)]||u[p]||g[p]||i;return r?o.createElement(f,a(a({ref:t},m),{},{components:r})):o.createElement(f,a({ref:t},m))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,a=new Array(i);a[0]=p;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:n,a[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=r(7462),n=(r(7294),r(3905));const i={title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]},a=void 0,l={permalink:"/blog/bloom-and-cuckoo-filters-for-cache-summarization",source:"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md",title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",date:"2023-09-12T16:57:42.000Z",formattedDate:"September 12, 2023",tags:[{label:"fleek network",permalink:"/blog/tags/fleek-network"},{label:"blog",permalink:"/blog/tags/blog"},{label:"engineering",permalink:"/blog/tags/engineering"},{label:"content routing",permalink:"/blog/tags/content-routing"}],readingTime:10.355,hasTruncateMarker:!0,authors:[{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"}],frontMatter:{title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]}},c={image:r(4221).Z,authorsImageUrls:[void 0]},s=[],m={toc:s},u="wrapper";function g(e){let{components:t,...r}=e;return(0,n.kt)(u,(0,o.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case."))}g.isMDXComponent=!0},4221:(e,t,r)=>{r.d(t,{Z:()=>o});const o=r.p+"assets/images/bloom-79da0db687b4fb2060758838b9c44513.png"}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3023],{3905:(e,t,r)=>{r.d(t,{Zo:()=>m,kt:()=>f});var o=r(7294);function n(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function i(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,o)}return r}function a(e){for(var t=1;t=0||(n[r]=e[r]);return n}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(n[r]=e[r])}return n}var c=o.createContext({}),s=function(e){var t=o.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},m=function(e){var t=s(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",g={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},p=o.forwardRef((function(e,t){var r=e.components,n=e.mdxType,i=e.originalType,c=e.parentName,m=l(e,["components","mdxType","originalType","parentName"]),u=s(r),p=n,f=u["".concat(c,".").concat(p)]||u[p]||g[p]||i;return r?o.createElement(f,a(a({ref:t},m),{},{components:r})):o.createElement(f,a({ref:t},m))}));function f(e,t){var r=arguments,n=t&&t.mdxType;if("string"==typeof e||n){var i=r.length,a=new Array(i);a[0]=p;var l={};for(var c in t)hasOwnProperty.call(t,c)&&(l[c]=t[c]);l.originalType=e,l[u]="string"==typeof e?e:n,a[1]=l;for(var s=2;s{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>g,frontMatter:()=>i,metadata:()=>l,toc:()=>s});var o=r(7462),n=(r(7294),r(3905));const i={title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]},a=void 0,l={permalink:"/blog/bloom-and-cuckoo-filters-for-cache-summarization",source:"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md",title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",date:"2023-09-13T11:07:59.000Z",formattedDate:"September 13, 2023",tags:[{label:"fleek network",permalink:"/blog/tags/fleek-network"},{label:"blog",permalink:"/blog/tags/blog"},{label:"engineering",permalink:"/blog/tags/engineering"},{label:"content routing",permalink:"/blog/tags/content-routing"}],readingTime:10.355,hasTruncateMarker:!0,authors:[{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"}],frontMatter:{title:"Bloom Filters and Cuckoo Filters for Cache Summarization",description:"Summary of our experiment informing whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters.",slug:"bloom-and-cuckoo-filters-for-cache-summarization",image:"./assets/bloom-cuckoo/bloom.png?202301181528",authors:{name:"Matthias Wright",title:"Software Engineer",url:"https://github.com/matthias-wright",image_url:"https://github.com/matthias-wright.png",imageURL:"https://github.com/matthias-wright.png"},tags:["fleek network","blog","engineering","content routing"]}},c={image:r(4221).Z,authorsImageUrls:[void 0]},s=[],m={toc:s},u="wrapper";function g(e){let{components:t,...r}=e;return(0,n.kt)(u,(0,o.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"Disclaimer: This is not a general comparison between Bloom filters and Cuckoo filters. This blog post summarizes some of the experiments we conducted to decide whether or not we should replace our implementation of Counting Bloom filters with Cuckoo filters, for a specific use case."))}g.isMDXComponent=!0},4221:(e,t,r)=>{r.d(t,{Z:()=>o});const o=r.p+"assets/images/bloom-79da0db687b4fb2060758838b9c44513.png"}}]); \ No newline at end of file diff --git a/assets/js/d8be0e5a.03a46161.js b/assets/js/d8be0e5a.686ccb83.js similarity index 98% rename from assets/js/d8be0e5a.03a46161.js rename to assets/js/d8be0e5a.686ccb83.js index 72014c4df..b3767dbd2 100644 --- a/assets/js/d8be0e5a.03a46161.js +++ b/assets/js/d8be0e5a.686ccb83.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1706],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=c(r),f=i,h=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function h(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,l=new Array(a);l[0]=f;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:i,l[1]=o;for(var c=2;c{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905)),a=r(3872);const l={title:"Error linking with cc",slug:"error-linking-with-cc-failed-exist-status-1",hide_title:!0,tags:["references","help","update","upgrade","fix"]},o=void 0,s={unversionedId:"Lightning CLI/error-linking-with-cc-failed",id:"Lightning CLI/error-linking-with-cc-failed",title:"Error linking with cc",description:"\x3c!--",source:"@site/references/Lightning CLI/error-linking-with-cc-failed.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/error-linking-with-cc-failed-exist-status-1",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/error-linking-with-cc-failed.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"update",permalink:"/references/tags/update"},{label:"upgrade",permalink:"/references/tags/upgrade"},{label:"fix",permalink:"/references/tags/fix"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Error linking with cc",slug:"error-linking-with-cc-failed-exist-status-1",hide_title:!0,tags:["references","help","update","upgrade","fix"]},sidebar:"defaultSidebar",previous:{title:"About references",permalink:"/references/"},next:{title:"File permissions and Ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership"}},c={},p=[{value:"Check if CPU is supported",id:"check-if-cpu-is-supported",level:2},{value:"Linking with cc error",id:"linking-with-cc-error",level:2},{value:"Update",id:"update",level:2},{value:"Install gcc:",id:"install-gcc",level:2},{value:"Remove previous installation files",id:"remove-previous-installation-files",level:2},{value:"Run the installation script",id:"run-the-installation-script",level:2}],u={toc:p},d="wrapper";function f(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"check-if-cpu-is-supported"},"Check if CPU is supported"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"uname -i\n")),(0,i.kt)("admonition",{title:"WARNING",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Given the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.fleek.network/docs/node/requirements/#specs"},"CPU requirements"),", currently we're mainly supporting ",(0,i.kt)("inlineCode",{parentName:"p"},"GenuineIntel")," and there have been reports of failure to build the binary on ",(0,i.kt)("inlineCode",{parentName:"p"},"AMD"),". The `ARM64`` is a different architecture, thus not supported. Any contribution or feedback to provide support is appreciated. Feel free to let us know on our ",(0,i.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"Discord channel"),".")),(0,i.kt)("h2",{id:"linking-with-cc-error"},"Linking with cc error"),(0,i.kt)("p",null,"A user who finds the error ",(0,i.kt)("inlineCode",{parentName:"p"},"linking with cc failed"),", will have to install the required dependencies."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"error: linking with `cc` failed: exit status: 1\nerror: could not compile `fleek-service-ping-example` (lib) due to previous error\n")),(0,i.kt)("h2",{id:"update"},"Update"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get update\n")),(0,i.kt)("h2",{id:"install-gcc"},"Install ",(0,i.kt)("inlineCode",{parentName:"h2"},"gcc"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get install gcc\n")),(0,i.kt)("h2",{id:"remove-previous-installation-files"},"Remove previous installation files"),(0,i.kt)("p",null,"You can re-run the installation process. If you are using the assisted installer, it'll complain that the source code directory already exists. Since you've probably cloned the source code repository locally, you'll have to remove it manually. If you need help, find the instructions in the ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/uninstall-lightning-cli"},"reference"),"."),(0,i.kt)("h2",{id:"run-the-installation-script"},"Run the installation script"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"curl https://get.fleek.network | bash\n")),(0,i.kt)("p",null,"Alternatively, read the ",(0,i.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation instructions")," for more information."),(0,i.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}f.isMDXComponent=!0},3872:(e,t,r)=>{r.d(t,{Z:()=>i});var n=r(7294);const i=e=>{let{image:t,name:r,title:i,url:a}=e;return n.createElement("section",{className:"author_card"},n.createElement("div",null,n.createElement("span",{className:"avatar"},n.createElement("a",{href:a,target:"_blank",alt:r},n.createElement("img",{src:t,alt:r}))),n.createElement("div",null,n.createElement("span",{className:"name"},n.createElement("a",{href:a,target:"_blank",alt:r},r)),n.createElement("span",{className:"title"},i),n.createElement("span",{className:"discord"},"Got questions? Find us on ",n.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[1706],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>h});var n=r(7294);function i(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function l(e){for(var t=1;t=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}var s=n.createContext({}),c=function(e){var t=n.useContext(s),r=t;return e&&(r="function"==typeof e?e(t):l(l({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},f=n.forwardRef((function(e,t){var r=e.components,i=e.mdxType,a=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),u=c(r),f=i,h=u["".concat(s,".").concat(f)]||u[f]||d[f]||a;return r?n.createElement(h,l(l({ref:t},p),{},{components:r})):n.createElement(h,l({ref:t},p))}));function h(e,t){var r=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=r.length,l=new Array(a);l[0]=f;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:i,l[1]=o;for(var c=2;c{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>f,frontMatter:()=>l,metadata:()=>s,toc:()=>p});var n=r(7462),i=(r(7294),r(3905)),a=r(3872);const l={title:"Error linking with cc",slug:"error-linking-with-cc-failed-exist-status-1",hide_title:!0,tags:["references","help","update","upgrade","fix"]},o=void 0,s={unversionedId:"Lightning CLI/error-linking-with-cc-failed",id:"Lightning CLI/error-linking-with-cc-failed",title:"Error linking with cc",description:"\x3c!--",source:"@site/references/Lightning CLI/error-linking-with-cc-failed.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/error-linking-with-cc-failed-exist-status-1",permalink:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/error-linking-with-cc-failed.md",tags:[{label:"references",permalink:"/references/tags/references"},{label:"help",permalink:"/references/tags/help"},{label:"update",permalink:"/references/tags/update"},{label:"upgrade",permalink:"/references/tags/upgrade"},{label:"fix",permalink:"/references/tags/fix"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Error linking with cc",slug:"error-linking-with-cc-failed-exist-status-1",hide_title:!0,tags:["references","help","update","upgrade","fix"]},sidebar:"defaultSidebar",previous:{title:"About references",permalink:"/references/"},next:{title:"File permissions and Ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership"}},c={},p=[{value:"Check if CPU is supported",id:"check-if-cpu-is-supported",level:2},{value:"Linking with cc error",id:"linking-with-cc-error",level:2},{value:"Update",id:"update",level:2},{value:"Install gcc:",id:"install-gcc",level:2},{value:"Remove previous installation files",id:"remove-previous-installation-files",level:2},{value:"Run the installation script",id:"run-the-installation-script",level:2}],u={toc:p},d="wrapper";function f(e){let{components:t,...r}=e;return(0,i.kt)(d,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h2",{id:"check-if-cpu-is-supported"},"Check if CPU is supported"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"uname -i\n")),(0,i.kt)("admonition",{title:"WARNING",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Given the ",(0,i.kt)("a",{parentName:"p",href:"https://docs.fleek.network/docs/node/requirements/#specs"},"CPU requirements"),", currently we're mainly supporting ",(0,i.kt)("inlineCode",{parentName:"p"},"GenuineIntel")," and there have been reports of failure to build the binary on ",(0,i.kt)("inlineCode",{parentName:"p"},"AMD"),". The `ARM64`` is a different architecture, thus not supported. Any contribution or feedback to provide support is appreciated. Feel free to let us know on our ",(0,i.kt)("a",{parentName:"p",href:"https://discord.gg/fleekxyz"},"Discord channel"),".")),(0,i.kt)("h2",{id:"linking-with-cc-error"},"Linking with cc error"),(0,i.kt)("p",null,"A user who finds the error ",(0,i.kt)("inlineCode",{parentName:"p"},"linking with cc failed"),", will have to install the required dependencies."),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"error: linking with `cc` failed: exit status: 1\nerror: could not compile `fleek-service-ping-example` (lib) due to previous error\n")),(0,i.kt)("h2",{id:"update"},"Update"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get update\n")),(0,i.kt)("h2",{id:"install-gcc"},"Install ",(0,i.kt)("inlineCode",{parentName:"h2"},"gcc"),":"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"sudo apt-get install gcc\n")),(0,i.kt)("h2",{id:"remove-previous-installation-files"},"Remove previous installation files"),(0,i.kt)("p",null,"You can re-run the installation process. If you are using the assisted installer, it'll complain that the source code directory already exists. Since you've probably cloned the source code repository locally, you'll have to remove it manually. If you need help, find the instructions in the ",(0,i.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/uninstall-lightning-cli"},"reference"),"."),(0,i.kt)("h2",{id:"run-the-installation-script"},"Run the installation script"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-sh"},"curl https://get.fleek.network | bash\n")),(0,i.kt)("p",null,"Alternatively, read the ",(0,i.kt)("a",{parentName:"p",href:"/docs/node/install#manual-installation"},"manual installation instructions")," for more information."),(0,i.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}f.isMDXComponent=!0},3872:(e,t,r)=>{r.d(t,{Z:()=>i});var n=r(7294);const i=e=>{let{image:t,name:r,title:i,url:a}=e;return n.createElement("section",{className:"author_card"},n.createElement("div",null,n.createElement("span",{className:"avatar"},n.createElement("a",{href:a,target:"_blank",alt:r},n.createElement("img",{src:t,alt:r}))),n.createElement("div",null,n.createElement("span",{className:"name"},n.createElement("a",{href:a,target:"_blank",alt:r},r)),n.createElement("span",{className:"title"},i),n.createElement("span",{className:"discord"},"Got questions? Find us on ",n.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/e1f64676.22d300a2.js b/assets/js/e1f64676.a14f546f.js similarity index 98% rename from assets/js/e1f64676.22d300a2.js rename to assets/js/e1f64676.a14f546f.js index 59d49a550..11db03187 100644 --- a/assets/js/e1f64676.22d300a2.js +++ b/assets/js/e1f64676.a14f546f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3120],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,l=e.mdxType,a=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(n),g=l,d=m["".concat(s,".").concat(g)]||m[g]||u[g]||a;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var a=n.length,i=new Array(a);i[0]=g;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[m]="string"==typeof e?e:l,i[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),l=(n(7294),n(3905)),a=n(3872);const i={title:"Uninstall Lightning CLI",slug:"uninstall-lightning-cli",hide_title:!0,tags:["References","Help","Uninstall","Remove","Delete","Clear","Clean"]},o=void 0,s={unversionedId:"Lightning CLI/uninstall-lightning-cli",id:"Lightning CLI/uninstall-lightning-cli",title:"Uninstall Lightning CLI",description:"\x3c!--",source:"@site/references/Lightning CLI/uninstall-lightning-cli.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/uninstall-lightning-cli",permalink:"/references/Lightning CLI/uninstall-lightning-cli",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/uninstall-lightning-cli.md",tags:[{label:"References",permalink:"/references/tags/references"},{label:"Help",permalink:"/references/tags/help"},{label:"Uninstall",permalink:"/references/tags/uninstall"},{label:"Remove",permalink:"/references/tags/remove"},{label:"Delete",permalink:"/references/tags/delete"},{label:"Clear",permalink:"/references/tags/clear"},{label:"Clean",permalink:"/references/tags/clean"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Uninstall Lightning CLI",slug:"uninstall-lightning-cli",hide_title:!0,tags:["References","Help","Uninstall","Remove","Delete","Clear","Clean"]},sidebar:"defaultSidebar",previous:{title:"Permission denied (os error 13)",permalink:"/references/Lightning CLI/permission-denied-os-error-13"},next:{title:"Update CLI from source code",permalink:"/references/Lightning CLI/update-cli-from-source-code"}},c={},p=[{value:"Remove symLink",id:"remove-symlink",level:2},{value:"Delete the local source code",id:"delete-the-local-source-code",level:2},{value:"Disable the systemd service",id:"disable-the-systemd-service",level:2},{value:"Clear the lightning config directory",id:"clear-the-lightning-config-directory",level:2},{value:"Uninstall Cargo and Rust",id:"uninstall-cargo-and-rust",level:2}],m={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,l.kt)(u,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h2",{id:"remove-symlink"},"Remove symLink"),(0,l.kt)("p",null,"To remove a symbolic link, use either the rm or unlink command followed by the name of the symlink as an argument. Here's an example with ",(0,l.kt)("inlineCode",{parentName:"p"},"unlink"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"unlink /usr/local/bin/lgtn\n")),(0,l.kt)("h2",{id:"delete-the-local-source-code"},"Delete the local source code"),(0,l.kt)("p",null,"Delete the local source code which was copied from the remote ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"repository"),". You can delete it recursively by:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/fleek-network/lightning\n")),(0,l.kt)("p",null,"\ud83d\udca1 Use the flag ",(0,l.kt)("inlineCode",{parentName:"p"},"f")," to force remove by skipping any prompts, e.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf ")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"The default install location is ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/fleek-network/lightning"),". If you have selected a different location to store the repository, change the target path.")),(0,l.kt)("h2",{id:"disable-the-systemd-service"},"Disable the systemd service"),(0,l.kt)("p",null,"To disable the Fleek Network Lightning Systemd's service, start by stopping the service."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl stop lightning.service\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"You can replace ",(0,l.kt)("inlineCode",{parentName:"p"},"lightning.service")," by ",(0,l.kt)("inlineCode",{parentName:"p"},"lightning"),".")),(0,l.kt)("p",null,"Disable the lightning service"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl disable lightning.service\n")),(0,l.kt)("p",null,"If you have used the recommended procedures in the ",(0,l.kt)("a",{parentName:"p",href:"/docs/node/install"},"install")," documentation you'll have to remove the Systemd unit (file that defines the service)."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm /etc/systemd/system/lightning.service\n")),(0,l.kt)("p",null,"Reload the Systemd service daemon"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,l.kt)("h2",{id:"clear-the-lightning-config-directory"},"Clear the lightning config directory"),(0,l.kt)("p",null,"The Fleek Network lightning config directory is where the configuration, keystore\u2013the location where your private key is hosted\u2013and other system files are stored."),(0,l.kt)("admonition",{title:"WARNING",type:"caution"},(0,l.kt)("p",{parentName:"admonition"},"Make sure to backup any sensitive data, such as the keystore (private keys), as you won't be able to recover the keys by any other means. If you have any funds associated with it, it'll be lost forever. The Fleek Network team or anyone else will not be able to help recover keys. Your keys, your responsibility.")),(0,l.kt)("p",null,"Alternatively, instead of deleting you can move the files to a custom directory name such as",(0,l.kt)("inlineCode",{parentName:"p"},".lightning.backupDATESTAMP"),", e.g. the example below we've used the date ",(0,l.kt)("inlineCode",{parentName:"p"},"2023-09-06-1205")," as that was the time this text was written:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"mv ~/.lightning ~/.lightning.backup202309061205\n")),(0,l.kt)("p",null,"To clear the lightning config directory remove any files recursively by running the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/.lightning/*\n")),(0,l.kt)("p",null,"\ud83d\udca1 Use the flag ",(0,l.kt)("inlineCode",{parentName:"p"},"f")," to force remove by skipping any prompts, e.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf /*")),(0,l.kt)("p",null,"Alternatively, delete the ",(0,l.kt)("inlineCode",{parentName:"p"},"~/.lightning")," directory:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/.lightning\n")),(0,l.kt)("h2",{id:"uninstall-cargo-and-rust"},"Uninstall Cargo and Rust"),(0,l.kt)("p",null,"To uninstall rustc, rustup and cargo run the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rustup self uninstall\n")),(0,l.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}g.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>l});var r=n(7294);const l=e=>{let{image:t,name:n,title:l,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},l),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[3120],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var r=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(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 i(e){for(var t=1;t=0||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=r.createContext({}),c=function(e){var t=r.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return r.createElement(s.Provider,{value:t},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,l=e.mdxType,a=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(n),g=l,d=m["".concat(s,".").concat(g)]||m[g]||u[g]||a;return n?r.createElement(d,i(i({ref:t},p),{},{components:n})):r.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var a=n.length,i=new Array(a);i[0]=g;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[m]="string"==typeof e?e:l,i[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>g,frontMatter:()=>i,metadata:()=>s,toc:()=>p});var r=n(7462),l=(n(7294),n(3905)),a=n(3872);const i={title:"Uninstall Lightning CLI",slug:"uninstall-lightning-cli",hide_title:!0,tags:["References","Help","Uninstall","Remove","Delete","Clear","Clean"]},o=void 0,s={unversionedId:"Lightning CLI/uninstall-lightning-cli",id:"Lightning CLI/uninstall-lightning-cli",title:"Uninstall Lightning CLI",description:"\x3c!--",source:"@site/references/Lightning CLI/uninstall-lightning-cli.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/uninstall-lightning-cli",permalink:"/references/Lightning CLI/uninstall-lightning-cli",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/uninstall-lightning-cli.md",tags:[{label:"References",permalink:"/references/tags/references"},{label:"Help",permalink:"/references/tags/help"},{label:"Uninstall",permalink:"/references/tags/uninstall"},{label:"Remove",permalink:"/references/tags/remove"},{label:"Delete",permalink:"/references/tags/delete"},{label:"Clear",permalink:"/references/tags/clear"},{label:"Clean",permalink:"/references/tags/clean"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Uninstall Lightning CLI",slug:"uninstall-lightning-cli",hide_title:!0,tags:["References","Help","Uninstall","Remove","Delete","Clear","Clean"]},sidebar:"defaultSidebar",previous:{title:"Permission denied (os error 13)",permalink:"/references/Lightning CLI/permission-denied-os-error-13"},next:{title:"Update CLI from source code",permalink:"/references/Lightning CLI/update-cli-from-source-code"}},c={},p=[{value:"Remove symLink",id:"remove-symlink",level:2},{value:"Delete the local source code",id:"delete-the-local-source-code",level:2},{value:"Disable the systemd service",id:"disable-the-systemd-service",level:2},{value:"Clear the lightning config directory",id:"clear-the-lightning-config-directory",level:2},{value:"Uninstall Cargo and Rust",id:"uninstall-cargo-and-rust",level:2}],m={toc:p},u="wrapper";function g(e){let{components:t,...n}=e;return(0,l.kt)(u,(0,r.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h2",{id:"remove-symlink"},"Remove symLink"),(0,l.kt)("p",null,"To remove a symbolic link, use either the rm or unlink command followed by the name of the symlink as an argument. Here's an example with ",(0,l.kt)("inlineCode",{parentName:"p"},"unlink"),":"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"unlink /usr/local/bin/lgtn\n")),(0,l.kt)("h2",{id:"delete-the-local-source-code"},"Delete the local source code"),(0,l.kt)("p",null,"Delete the local source code which was copied from the remote ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/fleek-network/lightning"},"repository"),". You can delete it recursively by:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/fleek-network/lightning\n")),(0,l.kt)("p",null,"\ud83d\udca1 Use the flag ",(0,l.kt)("inlineCode",{parentName:"p"},"f")," to force remove by skipping any prompts, e.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf ")),(0,l.kt)("admonition",{type:"note"},(0,l.kt)("p",{parentName:"admonition"},"The default install location is ",(0,l.kt)("inlineCode",{parentName:"p"},"$HOME/fleek-network/lightning"),". If you have selected a different location to store the repository, change the target path.")),(0,l.kt)("h2",{id:"disable-the-systemd-service"},"Disable the systemd service"),(0,l.kt)("p",null,"To disable the Fleek Network Lightning Systemd's service, start by stopping the service."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl stop lightning.service\n")),(0,l.kt)("admonition",{type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"You can replace ",(0,l.kt)("inlineCode",{parentName:"p"},"lightning.service")," by ",(0,l.kt)("inlineCode",{parentName:"p"},"lightning"),".")),(0,l.kt)("p",null,"Disable the lightning service"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl disable lightning.service\n")),(0,l.kt)("p",null,"If you have used the recommended procedures in the ",(0,l.kt)("a",{parentName:"p",href:"/docs/node/install"},"install")," documentation you'll have to remove the Systemd unit (file that defines the service)."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm /etc/systemd/system/lightning.service\n")),(0,l.kt)("p",null,"Reload the Systemd service daemon"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"sudo systemctl daemon-reload\n")),(0,l.kt)("h2",{id:"clear-the-lightning-config-directory"},"Clear the lightning config directory"),(0,l.kt)("p",null,"The Fleek Network lightning config directory is where the configuration, keystore\u2013the location where your private key is hosted\u2013and other system files are stored."),(0,l.kt)("admonition",{title:"WARNING",type:"caution"},(0,l.kt)("p",{parentName:"admonition"},"Make sure to backup any sensitive data, such as the keystore (private keys), as you won't be able to recover the keys by any other means. If you have any funds associated with it, it'll be lost forever. The Fleek Network team or anyone else will not be able to help recover keys. Your keys, your responsibility.")),(0,l.kt)("p",null,"Alternatively, instead of deleting you can move the files to a custom directory name such as",(0,l.kt)("inlineCode",{parentName:"p"},".lightning.backupDATESTAMP"),", e.g. the example below we've used the date ",(0,l.kt)("inlineCode",{parentName:"p"},"2023-09-06-1205")," as that was the time this text was written:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"mv ~/.lightning ~/.lightning.backup202309061205\n")),(0,l.kt)("p",null,"To clear the lightning config directory remove any files recursively by running the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/.lightning/*\n")),(0,l.kt)("p",null,"\ud83d\udca1 Use the flag ",(0,l.kt)("inlineCode",{parentName:"p"},"f")," to force remove by skipping any prompts, e.g. ",(0,l.kt)("inlineCode",{parentName:"p"},"rm -rf /*")),(0,l.kt)("p",null,"Alternatively, delete the ",(0,l.kt)("inlineCode",{parentName:"p"},"~/.lightning")," directory:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rm -r ~/.lightning\n")),(0,l.kt)("h2",{id:"uninstall-cargo-and-rust"},"Uninstall Cargo and Rust"),(0,l.kt)("p",null,"To uninstall rustc, rustup and cargo run the following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-sh"},"rustup self uninstall\n")),(0,l.kt)(a.Z,{name:"Helder Oliveira",image:"https://github.com/heldrida.png",title:"Software Developer + DX",url:"https://github.com/heldrida",mdxType:"Author"}))}g.isMDXComponent=!0},3872:(e,t,n)=>{n.d(t,{Z:()=>l});var r=n(7294);const l=e=>{let{image:t,name:n,title:l,url:a}=e;return r.createElement("section",{className:"author_card"},r.createElement("div",null,r.createElement("span",{className:"avatar"},r.createElement("a",{href:a,target:"_blank",alt:n},r.createElement("img",{src:t,alt:n}))),r.createElement("div",null,r.createElement("span",{className:"name"},r.createElement("a",{href:a,target:"_blank",alt:n},n)),r.createElement("span",{className:"title"},l),r.createElement("span",{className:"discord"},"Got questions? Find us on ",r.createElement("a",{href:"https://discord.gg/fleekxyz",target:"_blank"},"Discord!")))))}}}]); \ No newline at end of file diff --git a/assets/js/ed7afecf.dd6bae0f.js b/assets/js/ed7afecf.dd6bae0f.js deleted file mode 100644 index 64891c46f..000000000 --- a/assets/js/ed7afecf.dd6bae0f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6042],{2842:e=>{e.exports=JSON.parse('{"label":"migrate","permalink":"/guides/tags/migrate","allTagsPath":"/guides/tags","count":1,"items":[{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","permalink":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user"}]}')}}]); \ No newline at end of file diff --git a/assets/js/fa69a7f4.1bb6f346.js b/assets/js/fa69a7f4.1bb6f346.js new file mode 100644 index 000000000..4d9fd85bb --- /dev/null +++ b/assets/js/fa69a7f4.1bb6f346.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6798],{2469:e=>{e.exports=JSON.parse('{"pluginId":"guides","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"defaultSidebar":[{"type":"link","label":"About guides","href":"/guides/","docId":"index"},{"type":"category","label":"Node Operators","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Getting Started","href":"/guides/Node Operators/getting-started","docId":"Node Operators/getting-started-guide"},{"type":"link","label":"Transfering setup ownership","href":"/guides/Node Operators/transfering-setup-ownership","docId":"Node Operators/transfering-setup-ownership"}]}]},"docs":{"index":{"id":"index","title":"About guides","description":"The guides provide step-by-step instructions and descriptions to help understand how and why you\'d have to do or execute certain commands or processes.","sidebar":"defaultSidebar"},"Node Operators/getting-started-guide":{"id":"Node Operators/getting-started-guide","title":"Getting Started","description":"A first look at what Fleek Network is, why it\'s important, and a simple tutorial of running and interacting with a node on your local machine!","sidebar":"defaultSidebar"},"Node Operators/transfering-setup-ownership":{"id":"Node Operators/transfering-setup-ownership","title":"Transfering setup ownership","description":"A step-by-step guide to transfer the ownership of the Fleek Network Lightning CLI and service setup","sidebar":"defaultSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/fa69a7f4.54f0c913.js b/assets/js/fa69a7f4.54f0c913.js deleted file mode 100644 index e42de4664..000000000 --- a/assets/js/fa69a7f4.54f0c913.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[6798],{2469:e=>{e.exports=JSON.parse('{"pluginId":"guides","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"defaultSidebar":[{"type":"link","label":"About guides","href":"/guides/","docId":"index"},{"type":"category","label":"Node Operators","collapsible":false,"collapsed":false,"items":[{"type":"link","label":"Getting Started","href":"/guides/Node Operators/getting-started","docId":"Node Operators/getting-started-guide"},{"type":"link","label":"Migrate ownership of node setup to user","href":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user","docId":"Node Operators/migrate-ownership-to-user"}]}]},"docs":{"index":{"id":"index","title":"About guides","description":"The guides provide step-by-step instructions and descriptions to help understand how and why you\'d have to do or execute certain commands or processes.","sidebar":"defaultSidebar"},"Node Operators/getting-started-guide":{"id":"Node Operators/getting-started-guide","title":"Getting Started","description":"A first look at what Fleek Network is, why it\'s important, and a simple tutorial of running and interacting with a node on your local machine!","sidebar":"defaultSidebar"},"Node Operators/migrate-ownership-to-user":{"id":"Node Operators/migrate-ownership-to-user","title":"Migrate ownership of node setup to user","description":"A step-by-step guide to migrate the ownership of the Fleek Network Lightning CLI and service setup","sidebar":"defaultSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/fd2b74dc.8dd7faa7.js b/assets/js/fd2b74dc.5e571f47.js similarity index 97% rename from assets/js/fd2b74dc.8dd7faa7.js rename to assets/js/fd2b74dc.5e571f47.js index ad0450c93..fb2c7ab1c 100644 --- a/assets/js/fd2b74dc.8dd7faa7.js +++ b/assets/js/fd2b74dc.5e571f47.js @@ -1 +1 @@ -"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>y});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(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 i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),p=c(n),f=o,y=p["".concat(l,".").concat(f)]||p[f]||u[f]||s;return n?r.createElement(y,i(i({ref:t},d),{},{components:n})):r.createElement(y,i({ref:t},d))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=f;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,i[1]=a;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const s={title:"Keys not found",slug:"keys-not-found",hide_title:!0,tags:["keystore","lost keys","ownership","file permissions"]},i=void 0,a={unversionedId:"Lightning CLI/keys-not-found",id:"Lightning CLI/keys-not-found",title:"Keys not found",description:"Node key does not exist",source:"@site/references/Lightning CLI/keys-not-found.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/keys-not-found",permalink:"/references/Lightning CLI/keys-not-found",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/keys-not-found.md",tags:[{label:"keystore",permalink:"/references/tags/keystore"},{label:"lost keys",permalink:"/references/tags/lost-keys"},{label:"ownership",permalink:"/references/tags/ownership"},{label:"file permissions",permalink:"/references/tags/file-permissions"}],version:"current",lastUpdatedAt:1694537862,formattedLastUpdatedAt:"Sep 12, 2023",frontMatter:{title:"Keys not found",slug:"keys-not-found",hide_title:!0,tags:["keystore","lost keys","ownership","file permissions"]},sidebar:"defaultSidebar",previous:{title:"File permissions and Ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership"},next:{title:"Permission denied (os error 13)",permalink:"/references/Lightning CLI/permission-denied-os-error-13"}},l={},c=[{value:"Node key does not exist",id:"node-key-does-not-exist",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"node-key-does-not-exist"},"Node key does not exist"),(0,o.kt)("p",null,'When watching the Fleek Network Lightning service log output, you find the "Node key does not exist" message placed recursively. As follows:'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"thread 'main' panicked at 'Node key does not exist. Use CLI to generate keys.', core/node/src/testnet_sync.rs:126:9\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\nthread 'main' panicked at 'Node key does not exist. Use CLI to generate keys.', core/node/src/testnet_sync.rs:126:9\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n")),(0,o.kt)("p",null,"If you haven't deleted the keystore and can locate it, it's due to how the service is being run. As a user can delegate (sudo) the execution of the process to ",(0,o.kt)("strong",{parentName:"p"},"root"),", the location of the keystore differs on runtime."),(0,o.kt)("p",null,"To learn more about how file permissions and ownership work, you're advised to read the reference document ",(0,o.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[4846],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>y});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(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 i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=r.createContext({}),c=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},d=function(e){var t=c(e.components);return r.createElement(l.Provider,{value:t},e.children)},p="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},f=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,d=a(e,["components","mdxType","originalType","parentName"]),p=c(n),f=o,y=p["".concat(l,".").concat(f)]||p[f]||u[f]||s;return n?r.createElement(y,i(i({ref:t},d),{},{components:n})):r.createElement(y,i({ref:t},d))}));function y(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,i=new Array(s);i[0]=f;var a={};for(var l in t)hasOwnProperty.call(t,l)&&(a[l]=t[l]);a.originalType=e,a[p]="string"==typeof e?e:o,i[1]=a;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(7462),o=(n(7294),n(3905));const s={title:"Keys not found",slug:"keys-not-found",hide_title:!0,tags:["keystore","lost keys","ownership","file permissions"]},i=void 0,a={unversionedId:"Lightning CLI/keys-not-found",id:"Lightning CLI/keys-not-found",title:"Keys not found",description:"Node key does not exist",source:"@site/references/Lightning CLI/keys-not-found.md",sourceDirName:"Lightning CLI",slug:"/Lightning CLI/keys-not-found",permalink:"/references/Lightning CLI/keys-not-found",draft:!1,editUrl:"https://github.com/fleek-network/fleek-network-docs/edit/main/references/Lightning CLI/keys-not-found.md",tags:[{label:"keystore",permalink:"/references/tags/keystore"},{label:"lost keys",permalink:"/references/tags/lost-keys"},{label:"ownership",permalink:"/references/tags/ownership"},{label:"file permissions",permalink:"/references/tags/file-permissions"}],version:"current",lastUpdatedAt:1694603279,formattedLastUpdatedAt:"Sep 13, 2023",frontMatter:{title:"Keys not found",slug:"keys-not-found",hide_title:!0,tags:["keystore","lost keys","ownership","file permissions"]},sidebar:"defaultSidebar",previous:{title:"File permissions and Ownership",permalink:"/references/Lightning CLI/file-permissions-and-ownership"},next:{title:"Permission denied (os error 13)",permalink:"/references/Lightning CLI/permission-denied-os-error-13"}},l={},c=[{value:"Node key does not exist",id:"node-key-does-not-exist",level:2}],d={toc:c},p="wrapper";function u(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h2",{id:"node-key-does-not-exist"},"Node key does not exist"),(0,o.kt)("p",null,'When watching the Fleek Network Lightning service log output, you find the "Node key does not exist" message placed recursively. As follows:'),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-sh"},"thread 'main' panicked at 'Node key does not exist. Use CLI to generate keys.', core/node/src/testnet_sync.rs:126:9\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\nthread 'main' panicked at 'Node key does not exist. Use CLI to generate keys.', core/node/src/testnet_sync.rs:126:9\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n")),(0,o.kt)("p",null,"If you haven't deleted the keystore and can locate it, it's due to how the service is being run. As a user can delegate (sudo) the execution of the process to ",(0,o.kt)("strong",{parentName:"p"},"root"),", the location of the keystore differs on runtime."),(0,o.kt)("p",null,"To learn more about how file permissions and ownership work, you're advised to read the reference document ",(0,o.kt)("a",{parentName:"p",href:"/references/Lightning%20CLI/file-permissions-and-ownership"},"here"),"."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.4c25d06d.js b/assets/js/main.4c25d06d.js deleted file mode 100644 index cc0d76fd1..000000000 --- a/assets/js/main.4c25d06d.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.4c25d06d.js.LICENSE.txt */ -(self.webpackChunkdocta=self.webpackChunkdocta||[]).push([[179],{830:(e,t,n)=>{"use strict";n.d(t,{W:()=>a});var r=n(7294);function a(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),s=n(6887);const l={"00309d1b":[()=>n.e(9335).then(n.t.bind(n,5219,19)),"~docs/default/tag-docs-tags-fleek-network-206.json",5219],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,4524)),"@theme/BlogTagsListPage",4524],"02f62b30":[()=>n.e(2170).then(n.t.bind(n,6037,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-plugin-content-docs/guides/plugin-route-context-module-100.json",6037],"0359c679":[()=>n.e(7649).then(n.t.bind(n,8511,19)),"~docs/references/tag-references-tags-sudoer-94d.json",8511],"07f20919":[()=>n.e(4327).then(n.t.bind(n,6444,19)),"~docs/references/tag-references-tags-root-1d1.json",6444],"08dd5264":[()=>n.e(9267).then(n.t.bind(n,9692,19)),"~docs/default/tag-docs-tags-snarks-8e6.json",9692],"09ac38f0":[()=>n.e(3343).then(n.t.bind(n,4764,19)),"~docs/references/tag-references-tags-delete-f8c.json",4764],"0db90029":[()=>n.e(6174).then(n.t.bind(n,2392,19)),"~docs/default/tag-docs-tags-cryptoeconomics-50b.json",2392],"0dffb83e":[()=>n.e(5075).then(n.bind(n,3208)),"@site/docs/roadmap.md",3208],"0e3f509c":[()=>n.e(7154).then(n.bind(n,4102)),"@site/docs/Core/services.md",4102],"0f4270c8":[()=>n.e(3238).then(n.bind(n,3567)),"@site/guides/Node Operators/migrate-ownership-to-user.md",3567],"0fbdd4ac":[()=>n.e(8934).then(n.t.bind(n,8944,19)),"~docs/guides/tag-guides-tags-ownership-c29.json",8944],"143de299":[()=>n.e(8427).then(n.t.bind(n,9162,19)),"~docs/default/tag-docs-tags-algorithms-8a4.json",9162],"153c226b":[()=>n.e(7249).then(n.t.bind(n,9141,19)),"~docs/default/tag-docs-tags-compile-66b.json",9141],"155c1e74":[()=>n.e(747).then(n.t.bind(n,8095,19)),"~docs/references/tag-references-tags-reference-379.json",8095],17896441:[()=>Promise.all([n.e(532),n.e(8105),n.e(7918)]).then(n.bind(n,8945)),"@theme/DocItem",8945],"179183ba":[()=>n.e(6601).then(n.t.bind(n,655,19)),"~docs/default/tag-docs-tags-protocol-8a8.json",655],"187c6361":[()=>n.e(6788).then(n.t.bind(n,1461,19)),"~docs/default/tag-docs-tags-edge-network-189.json",1461],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,9172)),"@theme/SearchPage",9172],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1c14429f":[()=>n.e(2702).then(n.bind(n,9587)),"@site/guides/Node Operators/getting-started-guide.md",9587],"1df93b7f":[()=>n.e(3237).then(n.bind(n,9754)),"@site/src/pages/index.tsx",9754],"2218035b":[()=>n.e(4530).then(n.t.bind(n,3769,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],"2730e145":[()=>n.e(7147).then(n.bind(n,9184)),"@site/references/Lightning CLI/permission-denied-os-error-13.md",9184],27528755:[()=>n.e(6926).then(n.t.bind(n,2578,19)),"~docs/references/tag-references-tags-uninstall-aa8.json",2578],"29b62a39":[()=>n.e(1498).then(n.bind(n,3129)),"@site/guides/index.md",3129],"2adfdcac":[()=>n.e(3189).then(n.t.bind(n,4723,19)),"~docs/default/tag-docs-tags-token-d9b.json",4723],"2baa5a9a":[()=>n.e(9021).then(n.t.bind(n,8704,19)),"~docs/guides/tag-guides-tags-configuration-48b.json",8704],"2e0a4d25":[()=>n.e(8132).then(n.t.bind(n,9073,19)),"~docs/references/tag-references-tags-systemctl-aa5.json",9073],"3290fbc2":[()=>n.e(2235).then(n.bind(n,1379)),"@site/docs/develop/client.md",1379],35230925:[()=>n.e(5602).then(n.bind(n,904)),"@site/docs/learn/developers.md",904],"35a7e2bf":[()=>n.e(4508).then(n.t.bind(n,8581,19)),"~docs/default/tag-docs-tags-contribute-7e0.json",8581],"3720c009":[()=>Promise.all([n.e(532),n.e(3751)]).then(n.bind(n,727)),"@theme/DocTagsListPage",727],"39574d2e":[()=>n.e(8747).then(n.t.bind(n,8270,19)),"~docs/default/tag-docs-tags-decentralization-674.json",8270],"399f21a8":[()=>n.e(2214).then(n.t.bind(n,2281,19)),"~docs/default/tag-docs-tags-rpc-9da.json",2281],"39e94577":[()=>n.e(1563).then(n.t.bind(n,3199,19)),"~docs/default/tag-docs-tags-build-2a2.json",3199],"3a6297ac":[()=>n.e(11).then(n.t.bind(n,2511,19)),"~docs/default/tag-docs-tags-sdk-70c.json",2511],"3b168dbd":[()=>n.e(469).then(n.t.bind(n,2832,19)),"~docs/guides/tag-guides-tags-edge-computing-c27.json",2832],"3f0cec70":[()=>n.e(9336).then(n.t.bind(n,4776,19)),"~docs/guides/tag-guides-tags-help-63e.json",4776],"3f3a03c1":[()=>n.e(4451).then(n.t.bind(n,1721,19)),"~blog/default/blog-tags-blog-476-list.json",1721],"3f90f51b":[()=>n.e(6669).then(n.bind(n,3726)),"@site/docs/learn/services.md",3726],"4035650f":[()=>n.e(2260).then(n.t.bind(n,9438,19)),"~blog/default/blog-tags-engineering-6ae.json",9438],"4061bfd3":[()=>n.e(3116).then(n.t.bind(n,7085,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-theme-search-algolia/default/plugin-route-context-module-100.json",7085],"40aeb86f":[()=>n.e(4402).then(n.bind(n,1054)),"@site/references/Lightning CLI/update-cli-from-source-code.md",1054],"41bffad9":[()=>n.e(7948).then(n.bind(n,9287)),"@site/docs/learn/ports.md",9287],"4247aede":[()=>n.e(2800).then(n.t.bind(n,4948,19)),"~docs/default/tag-docs-tags-consensus-a3b.json",4948],"433ff3d6":[()=>n.e(555).then(n.t.bind(n,2787,19)),"~docs/default/tag-docs-tags-rewards-1bb.json",2787],"43ee1886":[()=>n.e(5466).then(n.t.bind(n,653,19)),"~docs/references/tag-references-tags-idle-b08.json",653],"44969bae":[()=>n.e(4063).then(n.bind(n,7159)),"@site/docs/node/requirements.md",7159],"45c86e35":[()=>n.e(9847).then(n.t.bind(n,2316,19)),"~docs/default/tag-docs-tags-about-3bc.json",2316],"45e1a117":[()=>n.e(6696).then(n.t.bind(n,5382,19)),"~docs/references/tag-references-tags-frozen-e7d.json",5382],"469c924f":[()=>n.e(2240).then(n.t.bind(n,342,19)),"~docs/default/tag-docs-tags-roadmap-bd4.json",342],"48857ff6":[()=>n.e(2908).then(n.t.bind(n,1014,19)),"~docs/default/tag-docs-tags-open-source-3c0.json",1014],"48e81e49":[()=>n.e(173).then(n.t.bind(n,5121,19)),"~docs/default/tag-docs-tags-incentives-3eb.json",5121],"49b5e83d":[()=>n.e(402).then(n.t.bind(n,3969,19)),"~docs/default/tag-docs-tags-manual-b97.json",3969],"4a821728":[()=>n.e(9513).then(n.t.bind(n,9748,19)),"~docs/default/tag-docs-tags-whitepaper-2ec.json",9748],"4ba7e5a3":[()=>n.e(9735).then(n.bind(n,5380)),"@site/docs/contribute.md",5380],"4beaa780":[()=>n.e(5081).then(n.t.bind(n,380,19)),"~docs/default/tag-docs-tags-reputation-c14.json",380],"4c027320":[()=>n.e(9511).then(n.t.bind(n,2564,19)),"~docs/guides/tag-guides-tags-getting-started-812.json",2564],"4d7007b2":[()=>n.e(6272).then(n.bind(n,5926)),"@site/references/index.md",5926],"4ecc0a29":[()=>n.e(5280).then(n.t.bind(n,9577,19)),"~docs/default/tag-docs-tags-development-ba6.json",9577],"507ab7d0":[()=>n.e(6128).then(n.t.bind(n,1618,19)),"~docs/guides/tag-guides-tags-migration-f5a.json",1618],"50f02954":[()=>n.e(4826).then(n.t.bind(n,3900,19)),"~docs/references/tag-references-tags-systemd-aff.json",3900],"514cab6e":[()=>n.e(6410).then(n.bind(n,3474)),"@site/docs/Open-source/code-of-conduct.md",3474],"51d5b592":[()=>n.e(1984).then(n.bind(n,789)),"@site/docs/node/install.md",789],"51f2bfad":[()=>n.e(71).then(n.t.bind(n,3386,19)),"~docs/default/tag-docs-tags-server-240.json",3386],"53ca291c":[()=>n.e(3863).then(n.t.bind(n,4586,19)),"~docs/default/tag-docs-tags-economics-342.json",4586],"55960ee5":[()=>n.e(4121).then(n.t.bind(n,8070,19)),"~docs/default/tags-list-current-prop-15a.json",8070],"581d5240":[()=>n.e(5318).then(n.bind(n,3941)),"@site/docs/node/health-check.md",3941],"5b6134d1":[()=>n.e(9752).then(n.bind(n,5852)),"@site/references/Lightning CLI/file-permissions-and-ownership.md",5852],"5d08f08d":[()=>n.e(659).then(n.t.bind(n,340,19)),"~docs/guides/tag-guides-tags-guide-f01.json",340],"5d38c936":[()=>n.e(9804).then(n.t.bind(n,9797,19)),"~docs/default/tag-docs-tags-rust-dependencies-0a8.json",9797],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,6809)),"@generated/docusaurus.config",6809],"5ef0bdde":[()=>n.e(8567).then(n.t.bind(n,7778,19)),"~blog/default/blog-tags-content-routing-b90.json",7778],"616ee580":[()=>n.e(4749).then(n.t.bind(n,5736,19)),"~docs/references/tag-references-tags-remove-c35.json",5736],"631037e5":[()=>n.e(801).then(n.t.bind(n,7064,19)),"~blog/default/blog-tags-blog-476.json",7064],"64d03520":[()=>n.e(1138).then(n.t.bind(n,2217,19)),"~docs/default/tag-docs-tags-requirements-a99.json",2217],"665f164c":[()=>n.e(9320).then(n.bind(n,2760)),"@site/docs/node/testnet-onboarding.md",2760],"6875c492":[()=>Promise.all([n.e(532),n.e(8105),n.e(6048),n.e(8610)]).then(n.bind(n,1714)),"@theme/BlogTagsPostsPage",1714],"68b99ecd":[()=>n.e(4556).then(n.t.bind(n,1407,19)),"~docs/default/tag-docs-tags-standards-f96.json",1407],"6be32138":[()=>n.e(3396).then(n.bind(n,8198)),"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md",8198],"6cbb3cde":[()=>n.e(5136).then(n.t.bind(n,3860,19)),"~blog/default/blog-tags-engineering-6ae-list.json",3860],"6ccb158e":[()=>n.e(3218).then(n.t.bind(n,4391,19)),"~docs/references/tag-references-tags-keystore-d50.json",4391],"6e965365":[()=>n.e(4679).then(n.t.bind(n,8472,19)),"~docs/references/tag-references-tags-references-2ec.json",8472],"6f8964f3":[()=>n.e(7536).then(n.t.bind(n,9430,19)),"~docs/guides/tag-guides-tags-fleek-network-dce.json",9430],"719c0fd7":[()=>n.e(706).then(n.t.bind(n,6419,19)),"~docs/references/tag-references-tags-permissions-2fe.json",6419],"749619b5":[()=>n.e(6362).then(n.t.bind(n,5294,19)),"~docs/references/tag-references-tags-ownership-96b.json",5294],"74ec46b4":[()=>n.e(1263).then(n.t.bind(n,1337,19)),"~docs/default/tag-docs-tags-wizard-38b.json",1337],"763344b9":[()=>n.e(5094).then(n.t.bind(n,5772,19)),"~docs/default/tag-docs-tags-toolkit-735.json",5772],"779cc1e8":[()=>n.e(4).then(n.t.bind(n,761,19)),"~docs/references/tag-references-tags-update-c18.json",761],"7aba1839":[()=>n.e(554).then(n.t.bind(n,7177,19)),"~docs/default/tag-docs-tags-ports-99f.json",7177],"7b667a7f":[()=>n.e(5649).then(n.t.bind(n,5274,19)),"~docs/default/tag-docs-tags-git-514.json",5274],"7b9de75f":[()=>n.e(6353).then(n.t.bind(n,6378,19)),"~docs/default/tag-docs-tags-healthcheck-28a.json",6378],"7ddc4283":[()=>n.e(807).then(n.t.bind(n,5287,19)),"~docs/default/tag-docs-tags-contributing-315.json",5287],"814f3328":[()=>n.e(2535).then(n.t.bind(n,5641,19)),"~blog/default/blog-post-list-prop-default.json",5641],82893666:[()=>n.e(8005).then(n.t.bind(n,2220,19)),"~docs/default/tag-docs-tags-develop-1cf.json",2220],"8428fe34":[()=>n.e(5522).then(n.bind(n,6729)),"@site/docs/node/diagnostics.md",6729],"84cbd6c9":[()=>n.e(3336).then(n.t.bind(n,4793,19)),"~docs/guides/tags-list-current-prop-15a.json",4793],"84e08f43":[()=>n.e(8059).then(n.t.bind(n,3290,19)),"~docs/references/tag-references-tags-file-permissions-d5d.json",3290],"85d6e74d":[()=>n.e(4819).then(n.t.bind(n,5745,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"86c3bd1d":[()=>n.e(2421).then(n.t.bind(n,813,19)),"~docs/references/tag-references-tags-user-service-d6a.json",813],"8a92e787":[()=>n.e(2517).then(n.bind(n,2087)),"@site/references/Systemd/shutting-down-persistance.md",2087],"8cf21e85":[()=>n.e(6854).then(n.t.bind(n,90,19)),"~docs/default/tag-docs-tags-client-ceb.json",90],"8def2dd5":[()=>n.e(382).then(n.bind(n,8242)),"@site/docs/learn/index.md",8242],"8fe41007":[()=>n.e(1129).then(n.t.bind(n,9852,19)),"~docs/default/tag-docs-tags-snar-ks-885.json",9852],"933a69d3":[()=>n.e(7813).then(n.t.bind(n,1853,19)),"~docs/default/tag-docs-tags-getting-started-980.json",1853],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"93df2695":[()=>n.e(2386).then(n.bind(n,1569)),"@site/docs/learn/delivery-acknowledgements.md",1569],"94e6476d":[()=>n.e(6223).then(n.bind(n,5290)),"@site/docs/learn/network.md",5290],"95f4d37c":[()=>n.e(814).then(n.bind(n,9553)),"@site/docs/develop/index.md",9553],"9bca08cf":[()=>n.e(8318).then(n.t.bind(n,7618,19)),"~docs/references/tag-references-tags-upgrade-b60.json",7618],"9bd69ffc":[()=>n.e(6699).then(n.t.bind(n,9790,19)),"~docs/default/tag-docs-tags-node-status-a43.json",9790],"9cc140f3":[()=>n.e(5049).then(n.t.bind(n,429,19)),"~docs/default/tag-docs-tags-repository-b8c.json",429],"9e4087bc":[()=>n.e(3608).then(n.bind(n,3169)),"@theme/BlogArchivePage",3169],"9f1c3232":[()=>n.e(373).then(n.bind(n,3477)),"@site/docs/node/index.md",3477],a13e0645:[()=>n.e(7136).then(n.t.bind(n,3120,19)),"~docs/default/tag-docs-tags-codebase-878.json",3120],a50e2e4f:[()=>n.e(7796).then(n.t.bind(n,2752,19)),"~docs/default/tag-docs-tags-awards-c13.json",2752],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(8105),n.e(6048),n.e(3089)]).then(n.bind(n,3402)),"@theme/BlogListPage",3402],a7023ddc:[()=>n.e(1713).then(n.t.bind(n,3457,19)),"~blog/default/blog-tags-tags-4c2.json",3457],a9a76bf7:[()=>n.e(4356).then(n.t.bind(n,8826,19)),"~docs/default/tag-docs-tags-onboarding-2eb.json",8826],aa81941d:[()=>n.e(3012).then(n.t.bind(n,4350,19)),"~docs/default/tag-docs-tags-edge-platform-754.json",4350],af6a11bf:[()=>n.e(3503).then(n.t.bind(n,5296,19)),"~docs/references/tag-references-tags-help-9a8.json",5296],b02525a9:[()=>n.e(6980).then(n.t.bind(n,3993,19)),"~docs/guides/tag-guides-tags-guides-141.json",3993],b03a0ac1:[()=>n.e(4785).then(n.t.bind(n,2312,19)),"~docs/default/tag-docs-tags-cdn-fa9.json",2312],b2b675dd:[()=>n.e(533).then(n.t.bind(n,8017,19)),"~blog/default/blog-c06.json",8017],b2f554cd:[()=>n.e(1477).then(n.t.bind(n,10,19)),"~blog/default/blog-archive-80c.json",10],b35f1b7f:[()=>n.e(7706).then(n.bind(n,5733)),"@site/references/Systemd/user-service.md",5733],b40daf0f:[()=>n.e(2126).then(n.bind(n,6332)),"@site/docs/node/configuration.md",6332],b4f44b9b:[()=>n.e(551).then(n.t.bind(n,2960,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-plugin-content-docs/references/plugin-route-context-module-100.json",2960],b5954e33:[()=>n.e(2114).then(n.bind(n,4692)),"@site/docs/learn/token-and-economics.md",4692],b696d13b:[()=>n.e(327).then(n.t.bind(n,5212,19)),"~docs/default/tag-docs-tags-verification-caa.json",5212],b8466c91:[()=>n.e(4939).then(n.t.bind(n,942,19)),"~docs/guides/tag-guides-tags-setup-8ad.json",942],b8c37621:[()=>n.e(920).then(n.t.bind(n,3908,19)),"~docs/default/tag-docs-tags-guide-a32.json",3908],bd59af11:[()=>n.e(9188).then(n.t.bind(n,7522,19)),"~docs/default/tag-docs-tags-diagnostics-265.json",7522],bea6e15b:[()=>n.e(8754).then(n.t.bind(n,815,19)),"~docs/references/tag-references-tags-fix-c13.json",815],c222de09:[()=>n.e(7563).then(n.bind(n,5534)),"@site/docs/whitepaper.md",5534],c377a04b:[()=>n.e(6971).then(n.bind(n,6453)),"@site/docs/index.md",6453],c3f5dd14:[()=>n.e(1345).then(n.t.bind(n,9826,19)),"~docs/references/tag-references-tags-clean-55b.json",9826],c7bd8086:[()=>n.e(441).then(n.bind(n,990)),"@site/docs/Core/edge-nodes.md",990],caaedc90:[()=>n.e(572).then(n.t.bind(n,8988,19)),"~docs/references/tag-references-tags-unit-0cd.json",8988],cc8e0b88:[()=>n.e(6310).then(n.t.bind(n,2560,19)),"~docs/default/tag-docs-tags-pledge-e5c.json",2560],cc9d5bf1:[()=>n.e(3236).then(n.t.bind(n,300,19)),"~blog/default/blog-tags-fleek-network-995-list.json",300],ccc49370:[()=>Promise.all([n.e(532),n.e(8105),n.e(6048),n.e(6103)]).then(n.bind(n,5203)),"@theme/BlogPostPage",5203],ce321ae3:[()=>n.e(1837).then(n.t.bind(n,2141,19)),"~docs/default/tag-docs-tags-configuration-143.json",2141],ce4635d7:[()=>n.e(9395).then(n.t.bind(n,6062,19)),"~docs/references/tag-references-tags-lost-keys-940.json",6062],d16f6fc6:[()=>n.e(5530).then(n.t.bind(n,8316,19)),"~docs/references/tag-references-tags-clear-34f.json",8316],d1b78a4d:[()=>n.e(3023).then(n.bind(n,1850)),"@site/blog/bloom-and-cuckoo-filters-for-cache-summarization.md?truncated=true",1850],d1d29319:[()=>n.e(2027).then(n.t.bind(n,9887,19)),"~docs/references/tag-references-tags-service-error-f6a.json",9887],d464210a:[()=>n.e(2023).then(n.t.bind(n,4075,19)),"~docs/default/tag-docs-tags-code-of-conduct-379.json",4075],d8be0e5a:[()=>n.e(1706).then(n.bind(n,4458)),"@site/references/Lightning CLI/error-linking-with-cc-failed.md",4458],da002ab0:[()=>n.e(5888).then(n.t.bind(n,831,19)),"~blog/default/blog-tags-fleek-network-995.json",831],da8f35c6:[()=>n.e(4541).then(n.t.bind(n,4257,19)),"~blog/default/blog-tags-content-routing-b90-list.json",4257],dc2776f2:[()=>n.e(8644).then(n.bind(n,93)),"@site/docs/Open-source/repositories.md",93],df203c0f:[()=>n.e(9924).then(n.bind(n,491)),"@theme/DocTagDocListPage",491],e10957d6:[()=>n.e(4708).then(n.t.bind(n,4469,19)),"/home/runner/work/fleek-network-docs/fleek-network-docs/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",4469],e1f64676:[()=>n.e(3120).then(n.bind(n,1933)),"@site/references/Lightning CLI/uninstall-lightning-cli.md",1933],e26f0bf0:[()=>n.e(4534).then(n.bind(n,757)),"@site/docs/Core/developers.md",757],e331fbd7:[()=>n.e(9995).then(n.t.bind(n,7568,19)),"~docs/default/tag-docs-tags-permissionless-576.json",7568],ec98ad91:[()=>n.e(4034).then(n.t.bind(n,1323,19)),"~docs/default/tag-docs-tags-testnet-9cf.json",1323],ecfddbd4:[()=>n.e(7804).then(n.bind(n,3317)),"@site/docs/Open-source.md",3317],ed7afecf:[()=>n.e(6042).then(n.t.bind(n,2842,19)),"~docs/guides/tag-guides-tags-migrate-96d.json",2842],f02c0d6e:[()=>n.e(3707).then(n.t.bind(n,3422,19)),"~docs/default/tag-docs-tags-tokenomics-43c.json",3422],f3d7f34e:[()=>n.e(982).then(n.t.bind(n,9299,19)),"~docs/references/version-current-metadata-prop-751.json",9299],f3f8ecb0:[()=>n.e(6939).then(n.bind(n,2854)),"@site/docs/develop/service-development.md",2854],f4fd4511:[()=>n.e(6461).then(n.t.bind(n,6514,19)),"~docs/default/tag-docs-tags-phases-f9f.json",6514],f50a4147:[()=>n.e(4888).then(n.bind(n,260)),"@site/docs/Open-source/contributing.md",260],f6807fb4:[()=>n.e(4788).then(n.t.bind(n,9836,19)),"~docs/default/tag-docs-tags-architecture-68d.json",9836],f6a16de6:[()=>n.e(4371).then(n.t.bind(n,5293,19)),"~docs/default/tag-docs-tags-contributor-267.json",5293],f9537533:[()=>n.e(5347).then(n.t.bind(n,881,19)),"~docs/references/tags-list-current-prop-15a.json",881],fa69a7f4:[()=>n.e(6798).then(n.t.bind(n,2469,19)),"~docs/guides/version-current-metadata-prop-751.json",2469],fa7546af:[()=>n.e(1611).then(n.t.bind(n,7327,19)),"~docs/references/tag-references-tags-shutdown-0e6.json",7327],fcc63351:[()=>n.e(9743).then(n.t.bind(n,7495,19)),"~docs/default/tag-docs-tags-services-754.json",7495],fd2b74dc:[()=>n.e(4846).then(n.bind(n,6578)),"@site/references/Lightning CLI/keys-not-found.md",6578],ff80750d:[()=>n.e(2931).then(n.t.bind(n,8807,19)),"~docs/default/tag-docs-tags-repositories-c88.json",8807],ffc337e7:[()=>n.e(7310).then(n.t.bind(n,2110,19)),"~docs/default/tag-docs-tags-learn-579.json",2110],ffcb1b32:[()=>n.e(5120).then(n.bind(n,8730)),"@site/docs/develop/json-rpc.md",8730]};function c(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("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%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("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"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(9670),d=n(226);function f(e,t){if("*"===e)return i()({loading:c,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=s[`${e}-${t}`],f={},p=[],g=[],m=(0,u.Z)(o);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=l[n];r&&(f[t]=r[0],p.push(r[1]),g.push(r[2]))})),i().Map({loading:c,loader:f,modules:p,webpack:()=>g,render(t,n){const i=JSON.parse(JSON.stringify(o));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 o=i;const s=n.split(".");s.slice(0,-1).forEach((e=>{o=o[e]})),o[s[s.length-1]]=a}));const s=i.__comp;delete i.__comp;const l=i.__context;return delete i.__context,r.createElement(d.z,{value:l},r.createElement(s,(0,a.Z)({},i,n)))}})}const p=[{path:"/blog/",component:f("/blog/","951"),exact:!0},{path:"/blog/archive/",component:f("/blog/archive/","d54"),exact:!0},{path:"/blog/bloom-and-cuckoo-filters-for-cache-summarization/",component:f("/blog/bloom-and-cuckoo-filters-for-cache-summarization/","5a5"),exact:!0},{path:"/blog/tags/",component:f("/blog/tags/","f8d"),exact:!0},{path:"/blog/tags/blog/",component:f("/blog/tags/blog/","dc0"),exact:!0},{path:"/blog/tags/content-routing/",component:f("/blog/tags/content-routing/","f84"),exact:!0},{path:"/blog/tags/engineering/",component:f("/blog/tags/engineering/","6c6"),exact:!0},{path:"/blog/tags/fleek-network/",component:f("/blog/tags/fleek-network/","490"),exact:!0},{path:"/docs/tags/",component:f("/docs/tags/","070"),exact:!0},{path:"/docs/tags/about/",component:f("/docs/tags/about/","dcd"),exact:!0},{path:"/docs/tags/algorithms/",component:f("/docs/tags/algorithms/","cf8"),exact:!0},{path:"/docs/tags/architecture/",component:f("/docs/tags/architecture/","4de"),exact:!0},{path:"/docs/tags/awards/",component:f("/docs/tags/awards/","ef9"),exact:!0},{path:"/docs/tags/build/",component:f("/docs/tags/build/","cb8"),exact:!0},{path:"/docs/tags/cdn/",component:f("/docs/tags/cdn/","f22"),exact:!0},{path:"/docs/tags/client/",component:f("/docs/tags/client/","e82"),exact:!0},{path:"/docs/tags/code-of-conduct/",component:f("/docs/tags/code-of-conduct/","574"),exact:!0},{path:"/docs/tags/codebase/",component:f("/docs/tags/codebase/","73d"),exact:!0},{path:"/docs/tags/compile/",component:f("/docs/tags/compile/","610"),exact:!0},{path:"/docs/tags/configuration/",component:f("/docs/tags/configuration/","2ee"),exact:!0},{path:"/docs/tags/consensus/",component:f("/docs/tags/consensus/","f81"),exact:!0},{path:"/docs/tags/contribute/",component:f("/docs/tags/contribute/","daa"),exact:!0},{path:"/docs/tags/contributing/",component:f("/docs/tags/contributing/","78f"),exact:!0},{path:"/docs/tags/contributor/",component:f("/docs/tags/contributor/","f8e"),exact:!0},{path:"/docs/tags/cryptoeconomics/",component:f("/docs/tags/cryptoeconomics/","841"),exact:!0},{path:"/docs/tags/decentralization/",component:f("/docs/tags/decentralization/","d8a"),exact:!0},{path:"/docs/tags/develop/",component:f("/docs/tags/develop/","df2"),exact:!0},{path:"/docs/tags/development/",component:f("/docs/tags/development/","549"),exact:!0},{path:"/docs/tags/diagnostics/",component:f("/docs/tags/diagnostics/","354"),exact:!0},{path:"/docs/tags/economics/",component:f("/docs/tags/economics/","35c"),exact:!0},{path:"/docs/tags/edge-network/",component:f("/docs/tags/edge-network/","9a2"),exact:!0},{path:"/docs/tags/edge-platform/",component:f("/docs/tags/edge-platform/","3ff"),exact:!0},{path:"/docs/tags/fleek-network/",component:f("/docs/tags/fleek-network/","ed7"),exact:!0},{path:"/docs/tags/getting-started/",component:f("/docs/tags/getting-started/","5c5"),exact:!0},{path:"/docs/tags/git/",component:f("/docs/tags/git/","36d"),exact:!0},{path:"/docs/tags/guide/",component:f("/docs/tags/guide/","cdc"),exact:!0},{path:"/docs/tags/healthcheck/",component:f("/docs/tags/healthcheck/","b81"),exact:!0},{path:"/docs/tags/incentives/",component:f("/docs/tags/incentives/","8ff"),exact:!0},{path:"/docs/tags/learn/",component:f("/docs/tags/learn/","e71"),exact:!0},{path:"/docs/tags/manual/",component:f("/docs/tags/manual/","02d"),exact:!0},{path:"/docs/tags/node-status/",component:f("/docs/tags/node-status/","5b1"),exact:!0},{path:"/docs/tags/onboarding/",component:f("/docs/tags/onboarding/","140"),exact:!0},{path:"/docs/tags/open-source/",component:f("/docs/tags/open-source/","864"),exact:!0},{path:"/docs/tags/permissionless/",component:f("/docs/tags/permissionless/","86e"),exact:!0},{path:"/docs/tags/phases/",component:f("/docs/tags/phases/","743"),exact:!0},{path:"/docs/tags/pledge/",component:f("/docs/tags/pledge/","ec7"),exact:!0},{path:"/docs/tags/ports/",component:f("/docs/tags/ports/","fad"),exact:!0},{path:"/docs/tags/protocol/",component:f("/docs/tags/protocol/","5c7"),exact:!0},{path:"/docs/tags/repositories/",component:f("/docs/tags/repositories/","ba6"),exact:!0},{path:"/docs/tags/repository/",component:f("/docs/tags/repository/","835"),exact:!0},{path:"/docs/tags/reputation/",component:f("/docs/tags/reputation/","013"),exact:!0},{path:"/docs/tags/requirements/",component:f("/docs/tags/requirements/","7cb"),exact:!0},{path:"/docs/tags/rewards/",component:f("/docs/tags/rewards/","80e"),exact:!0},{path:"/docs/tags/roadmap/",component:f("/docs/tags/roadmap/","d25"),exact:!0},{path:"/docs/tags/rpc/",component:f("/docs/tags/rpc/","f75"),exact:!0},{path:"/docs/tags/rust-dependencies/",component:f("/docs/tags/rust-dependencies/","a0f"),exact:!0},{path:"/docs/tags/sdk/",component:f("/docs/tags/sdk/","b2b"),exact:!0},{path:"/docs/tags/server/",component:f("/docs/tags/server/","534"),exact:!0},{path:"/docs/tags/services/",component:f("/docs/tags/services/","f12"),exact:!0},{path:"/docs/tags/snar-ks/",component:f("/docs/tags/snar-ks/","4fa"),exact:!0},{path:"/docs/tags/snarks/",component:f("/docs/tags/snarks/","933"),exact:!0},{path:"/docs/tags/standards/",component:f("/docs/tags/standards/","440"),exact:!0},{path:"/docs/tags/testnet/",component:f("/docs/tags/testnet/","bc6"),exact:!0},{path:"/docs/tags/token/",component:f("/docs/tags/token/","e7b"),exact:!0},{path:"/docs/tags/tokenomics/",component:f("/docs/tags/tokenomics/","2b9"),exact:!0},{path:"/docs/tags/toolkit/",component:f("/docs/tags/toolkit/","e12"),exact:!0},{path:"/docs/tags/verification/",component:f("/docs/tags/verification/","c34"),exact:!0},{path:"/docs/tags/whitepaper/",component:f("/docs/tags/whitepaper/","798"),exact:!0},{path:"/docs/tags/wizard/",component:f("/docs/tags/wizard/","2b1"),exact:!0},{path:"/guides/tags/",component:f("/guides/tags/","f51"),exact:!0},{path:"/guides/tags/configuration/",component:f("/guides/tags/configuration/","84f"),exact:!0},{path:"/guides/tags/edge-computing/",component:f("/guides/tags/edge-computing/","cc1"),exact:!0},{path:"/guides/tags/fleek-network/",component:f("/guides/tags/fleek-network/","c44"),exact:!0},{path:"/guides/tags/getting-started/",component:f("/guides/tags/getting-started/","d87"),exact:!0},{path:"/guides/tags/guide/",component:f("/guides/tags/guide/","3ed"),exact:!0},{path:"/guides/tags/guides/",component:f("/guides/tags/guides/","597"),exact:!0},{path:"/guides/tags/help/",component:f("/guides/tags/help/","903"),exact:!0},{path:"/guides/tags/migrate/",component:f("/guides/tags/migrate/","c63"),exact:!0},{path:"/guides/tags/migration/",component:f("/guides/tags/migration/","a2c"),exact:!0},{path:"/guides/tags/ownership/",component:f("/guides/tags/ownership/","599"),exact:!0},{path:"/guides/tags/setup/",component:f("/guides/tags/setup/","cc1"),exact:!0},{path:"/references/tags/",component:f("/references/tags/","bb6"),exact:!0},{path:"/references/tags/clean/",component:f("/references/tags/clean/","84f"),exact:!0},{path:"/references/tags/clear/",component:f("/references/tags/clear/","2a0"),exact:!0},{path:"/references/tags/delete/",component:f("/references/tags/delete/","0a8"),exact:!0},{path:"/references/tags/file-permissions/",component:f("/references/tags/file-permissions/","f21"),exact:!0},{path:"/references/tags/fix/",component:f("/references/tags/fix/","ae4"),exact:!0},{path:"/references/tags/frozen/",component:f("/references/tags/frozen/","b33"),exact:!0},{path:"/references/tags/help/",component:f("/references/tags/help/","46c"),exact:!0},{path:"/references/tags/idle/",component:f("/references/tags/idle/","d4a"),exact:!0},{path:"/references/tags/keystore/",component:f("/references/tags/keystore/","160"),exact:!0},{path:"/references/tags/lost-keys/",component:f("/references/tags/lost-keys/","60c"),exact:!0},{path:"/references/tags/ownership/",component:f("/references/tags/ownership/","58e"),exact:!0},{path:"/references/tags/permissions/",component:f("/references/tags/permissions/","34d"),exact:!0},{path:"/references/tags/reference/",component:f("/references/tags/reference/","b27"),exact:!0},{path:"/references/tags/references/",component:f("/references/tags/references/","91e"),exact:!0},{path:"/references/tags/remove/",component:f("/references/tags/remove/","b0b"),exact:!0},{path:"/references/tags/root/",component:f("/references/tags/root/","9c4"),exact:!0},{path:"/references/tags/service-error/",component:f("/references/tags/service-error/","8d0"),exact:!0},{path:"/references/tags/shutdown/",component:f("/references/tags/shutdown/","193"),exact:!0},{path:"/references/tags/sudoer/",component:f("/references/tags/sudoer/","09d"),exact:!0},{path:"/references/tags/systemctl/",component:f("/references/tags/systemctl/","cdc"),exact:!0},{path:"/references/tags/systemd/",component:f("/references/tags/systemd/","0be"),exact:!0},{path:"/references/tags/uninstall/",component:f("/references/tags/uninstall/","019"),exact:!0},{path:"/references/tags/unit/",component:f("/references/tags/unit/","20e"),exact:!0},{path:"/references/tags/update/",component:f("/references/tags/update/","192"),exact:!0},{path:"/references/tags/upgrade/",component:f("/references/tags/upgrade/","ee8"),exact:!0},{path:"/references/tags/user-service/",component:f("/references/tags/user-service/","170"),exact:!0},{path:"/search/",component:f("/search/","2a3"),exact:!0},{path:"/docs/",component:f("/docs/","3c3"),routes:[{path:"/docs/",component:f("/docs/","e7a"),exact:!0,sidebar:"docs"},{path:"/docs/contribute/",component:f("/docs/contribute/","036"),exact:!0},{path:"/docs/Core/developers/",component:f("/docs/Core/developers/","9da"),exact:!0},{path:"/docs/Core/edge-nodes/",component:f("/docs/Core/edge-nodes/","326"),exact:!0},{path:"/docs/Core/services/",component:f("/docs/Core/services/","a77"),exact:!0},{path:"/docs/develop/client/",component:f("/docs/develop/client/","720"),exact:!0},{path:"/docs/develop/json-rpc/",component:f("/docs/develop/json-rpc/","3b0"),exact:!0},{path:"/docs/develop/overview/",component:f("/docs/develop/overview/","4ab"),exact:!0},{path:"/docs/develop/service-development/",component:f("/docs/develop/service-development/","a0d"),exact:!0},{path:"/docs/learn/delivery-acknowledgements/",component:f("/docs/learn/delivery-acknowledgements/","76f"),exact:!0,sidebar:"docs"},{path:"/docs/learn/developers/",component:f("/docs/learn/developers/","a5d"),exact:!0,sidebar:"docs"},{path:"/docs/learn/introduction/",component:f("/docs/learn/introduction/","0c9"),exact:!0,sidebar:"docs"},{path:"/docs/learn/ports/",component:f("/docs/learn/ports/","4c8"),exact:!0},{path:"/docs/learn/services/",component:f("/docs/learn/services/","095"),exact:!0,sidebar:"docs"},{path:"/docs/learn/the-network/",component:f("/docs/learn/the-network/","fe1"),exact:!0,sidebar:"docs"},{path:"/docs/learn/token-and-economics/",component:f("/docs/learn/token-and-economics/","ede"),exact:!0,sidebar:"docs"},{path:"/docs/node/configuration/",component:f("/docs/node/configuration/","191"),exact:!0},{path:"/docs/node/diagnostics/",component:f("/docs/node/diagnostics/","83b"),exact:!0},{path:"/docs/node/health-check/",component:f("/docs/node/health-check/","59e"),exact:!0,sidebar:"docs"},{path:"/docs/node/Install/",component:f("/docs/node/Install/","806"),exact:!0,sidebar:"docs"},{path:"/docs/node/overview/",component:f("/docs/node/overview/","603"),exact:!0,sidebar:"docs"},{path:"/docs/node/requirements/",component:f("/docs/node/requirements/","8ae"),exact:!0,sidebar:"docs"},{path:"/docs/node/testnet-onboarding/",component:f("/docs/node/testnet-onboarding/","2f1"),exact:!0,sidebar:"docs"},{path:"/docs/Open-source/",component:f("/docs/Open-source/","81b"),exact:!0},{path:"/docs/Open-source/code-of-conduct/",component:f("/docs/Open-source/code-of-conduct/","ff8"),exact:!0,sidebar:"docs"},{path:"/docs/Open-source/contributing/",component:f("/docs/Open-source/contributing/","27e"),exact:!0,sidebar:"docs"},{path:"/docs/Open-source/repositories/",component:f("/docs/Open-source/repositories/","93e"),exact:!0,sidebar:"docs"},{path:"/docs/roadmap/",component:f("/docs/roadmap/","532"),exact:!0,sidebar:"docs"},{path:"/docs/whitepaper/",component:f("/docs/whitepaper/","d8d"),exact:!0,sidebar:"docs"}]},{path:"/guides/",component:f("/guides/","53c"),routes:[{path:"/guides/",component:f("/guides/","ef7"),exact:!0,sidebar:"defaultSidebar"},{path:"/guides/Node Operators/getting-started/",component:f("/guides/Node Operators/getting-started/","a1f"),exact:!0,sidebar:"defaultSidebar"},{path:"/guides/Node Operators/migrate-ownership-of-node-setup-to-user/",component:f("/guides/Node Operators/migrate-ownership-of-node-setup-to-user/","29d"),exact:!0,sidebar:"defaultSidebar"}]},{path:"/references/",component:f("/references/","95d"),routes:[{path:"/references/",component:f("/references/","418"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1/",component:f("/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1/","bb4"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/file-permissions-and-ownership/",component:f("/references/Lightning CLI/file-permissions-and-ownership/","974"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/keys-not-found/",component:f("/references/Lightning CLI/keys-not-found/","45f"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/permission-denied-os-error-13/",component:f("/references/Lightning CLI/permission-denied-os-error-13/","eed"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/uninstall-lightning-cli/",component:f("/references/Lightning CLI/uninstall-lightning-cli/","d12"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Lightning CLI/update-cli-from-source-code/",component:f("/references/Lightning CLI/update-cli-from-source-code/","6a3"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Systemd/shutting-down-persistance/",component:f("/references/Systemd/shutting-down-persistance/","27f"),exact:!0,sidebar:"defaultSidebar"},{path:"/references/Systemd/user-service/",component:f("/references/Systemd/user-service/","9d7"),exact:!0,sidebar:"defaultSidebar"}]},{path:"/",component:f("/","a33"),exact:!0},{path:"*",component:f("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),s=n(412);const l=[n(2497),n(3310),n(8320),n(2295)];var c=n(723),u=n(6550),d=n(8790);function f(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var p=n(7462),g=n(5742),m=n(2263),h=n(4996),b=n(6668),v=n(833),y=n(4711),w=n(9727),k=n(3320),E=n(197);function _(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,m.Z)(),n=(0,y.l)();return r.createElement(g.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function S(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,m.Z)(),a=function(){const{siteConfig:{url:e}}=(0,m.Z)(),{pathname:t}=(0,u.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(g.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function x(){const{i18n:{currentLocale:e}}=(0,m.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(g.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(S,null),r.createElement(_,null),r.createElement(E.Z,{tag:k.HX,locale:e}),r.createElement(g.Z,null,t.map(((e,t)=>r.createElement("meta",(0,p.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(c.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var L=n(8934),A=n(8940);function R(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const O=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)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:a}),R("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function P(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(c.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class N extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?R("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=R("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),P(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 r.createElement(O,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=N,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",j="__docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${D}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[F]=!1}),[]),r.createElement(r.Fragment,null,!s.Z.canUseDOM&&r.createElement(g.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:D}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,m.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,m.Z)(),i=(0,h.Z)(e),{htmlLang:s,direction:l}=o[a];return r.createElement(g.Z,null,r.createElement("html",{lang:s,dir:l}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var q=n(4763);function H(){const e=(0,d.H)(c.Z),t=(0,u.TH)();return r.createElement(q.Z,null,r.createElement(A.M,null,r.createElement(L.t,null,r.createElement(f,null,r.createElement($,null),r.createElement(x,null),r.createElement(U,null),r.createElement(I,{location:T(t)},e)))))}var G=n(6887);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 a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.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 V=n(9670);const W=new Set,K=new Set,Y=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!Y()&&!K.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(c.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(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=>!Y()&&!K.has(e))(e)&&(K.add(e),P(e))},X=Object.freeze(Q);if(s.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;P(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>u,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-google-tag-manager":{"default":{"containerId":"GTM-PC422SF","id":"default"}},"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"index","docs":[{"id":"contribute","path":"/docs/contribute"},{"id":"Core/developers","path":"/docs/Core/developers"},{"id":"Core/edge-nodes","path":"/docs/Core/edge-nodes"},{"id":"Core/services","path":"/docs/Core/services"},{"id":"develop/client","path":"/docs/develop/client"},{"id":"develop/index","path":"/docs/develop/overview"},{"id":"develop/json-rpc","path":"/docs/develop/json-rpc"},{"id":"develop/service-development","path":"/docs/develop/service-development"},{"id":"index","path":"/docs/","sidebar":"docs"},{"id":"learn/delivery-acknowledgements","path":"/docs/learn/delivery-acknowledgements","sidebar":"docs"},{"id":"learn/developers","path":"/docs/learn/developers","sidebar":"docs"},{"id":"learn/index","path":"/docs/learn/introduction","sidebar":"docs"},{"id":"learn/network","path":"/docs/learn/the-network","sidebar":"docs"},{"id":"learn/ports","path":"/docs/learn/ports"},{"id":"learn/services","path":"/docs/learn/services","sidebar":"docs"},{"id":"learn/token-and-economics","path":"/docs/learn/token-and-economics","sidebar":"docs"},{"id":"node/configuration","path":"/docs/node/configuration"},{"id":"node/diagnostics","path":"/docs/node/diagnostics"},{"id":"node/health-check","path":"/docs/node/health-check","sidebar":"docs"},{"id":"node/index","path":"/docs/node/overview","sidebar":"docs"},{"id":"node/install","path":"/docs/node/Install","sidebar":"docs"},{"id":"node/requirements","path":"/docs/node/requirements","sidebar":"docs"},{"id":"node/testnet-onboarding","path":"/docs/node/testnet-onboarding","sidebar":"docs"},{"id":"Open-source","path":"/docs/Open-source"},{"id":"Open-source/code-of-conduct","path":"/docs/Open-source/code-of-conduct","sidebar":"docs"},{"id":"Open-source/contributing","path":"/docs/Open-source/contributing","sidebar":"docs"},{"id":"Open-source/repositories","path":"/docs/Open-source/repositories","sidebar":"docs"},{"id":"roadmap","path":"/docs/roadmap","sidebar":"docs"},{"id":"whitepaper","path":"/docs/whitepaper","sidebar":"docs"}],"draftIds":[],"sidebars":{"docs":{"link":{"path":"/docs/","label":"index"}}}}],"breadcrumbs":true},"guides":{"path":"/guides","versions":[{"name":"current","label":"Next","isLast":true,"path":"/guides","mainDocId":"index","docs":[{"id":"index","path":"/guides/","sidebar":"defaultSidebar"},{"id":"Node Operators/getting-started-guide","path":"/guides/Node Operators/getting-started","sidebar":"defaultSidebar"},{"id":"Node Operators/migrate-ownership-to-user","path":"/guides/Node Operators/migrate-ownership-of-node-setup-to-user","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/guides/","label":"index"}}}}],"breadcrumbs":false},"references":{"path":"/references","versions":[{"name":"current","label":"Next","isLast":true,"path":"/references","mainDocId":"index","docs":[{"id":"index","path":"/references/","sidebar":"defaultSidebar"},{"id":"Lightning CLI/error-linking-with-cc-failed","path":"/references/Lightning CLI/error-linking-with-cc-failed-exist-status-1","sidebar":"defaultSidebar"},{"id":"Lightning CLI/file-permissions-and-ownership","path":"/references/Lightning CLI/file-permissions-and-ownership","sidebar":"defaultSidebar"},{"id":"Lightning CLI/keys-not-found","path":"/references/Lightning CLI/keys-not-found","sidebar":"defaultSidebar"},{"id":"Lightning CLI/permission-denied-os-error-13","path":"/references/Lightning CLI/permission-denied-os-error-13","sidebar":"defaultSidebar"},{"id":"Lightning CLI/uninstall-lightning-cli","path":"/references/Lightning CLI/uninstall-lightning-cli","sidebar":"defaultSidebar"},{"id":"Lightning CLI/update-cli-from-source-code","path":"/references/Lightning CLI/update-cli-from-source-code","sidebar":"defaultSidebar"},{"id":"Systemd/shutting-down-persistance","path":"/references/Systemd/shutting-down-persistance","sidebar":"defaultSidebar"},{"id":"Systemd/user-service","path":"/references/Systemd/user-service","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/references/","label":"index"}}}}],"breadcrumbs":false}}}'),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(7529);const l=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"2.4.1"},"docusaurus-plugin-google-tag-manager":{"type":"package","name":"@docusaurus/plugin-google-tag-manager","version":"2.4.1"}}}'),c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},u=r.createContext(c);function d(e){let{children:t}=e;return r.createElement(u.Provider,{value:c},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(412),o=n(5742),i=n(8780),s=n(8888);function l(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(c,{error:t}))}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function u(e){let{error:t,tryAgain:n}=e;return r.createElement(f,{fallback:()=>r.createElement(l,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(s.Z,null,r.createElement(l,{error:t,tryAgain:n})))}const d=e=>r.createElement(u,e);class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.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??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),s=n(2263),l=n(3919),c=n(412);const u=a.createContext({collectLink:()=>{}});var d=n(4996);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,s.Z)(),{withBaseUrl:k}=(0,d.C)(),E=(0,a.useContext)(u),_=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>_.current));const S=f||p;const x=(0,l.Z)(S),C=S?.replace("pathname://","");let T=void 0!==C?(L=C,b&&(e=>e.startsWith("/"))(L)?k(L):L):void 0;var L;T&&x&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const A=(0,a.useRef)(!1),R=n?o.OL:o.rU,O=c.Z.canUseIntersectionObserver,P=(0,a.useRef)(),N=()=>{A.current||null==T||(window.docusaurus.preload(T),A.current=!0)};(0,a.useEffect)((()=>(!O&&x&&null!=T&&window.docusaurus.prefetch(T),()=>{O&&P.current&&P.current.disconnect()})),[P,T,O,x]);const I=T?.startsWith("#")??!1,D=!T||!x||I;return D||h||E.collectLink(T),D?a.createElement("a",(0,r.Z)({ref:_,href:T},S&&!x&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(R,(0,r.Z)({},v,{onMouseEnter:N,onTouchStart:N,innerRef:e=>{_.current=e,O&&e&&x&&(P.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(P.current.unobserve(e),P.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),P.current.observe(e))},to:T},n&&{isActive:m,activeClassName:g}))}const p=a.forwardRef(f)},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>s});var r=n(7294);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 o=n(7529);function i(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 o[t??n]??n??t}function s(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const s=i({message:t,id:n});return r.createElement(r.Fragment,null,a(s,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(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:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>b,gA:()=>p,WS:()=>g,_r:()=>d,Jo:()=>v,zh:()=>f,yW:()=>h,gB:()=>m});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}function c(e,t){const n=l(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},d=()=>i("docusaurus-plugin-content-docs")??u,f=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function p(e){void 0===e&&(e={});const t=d(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&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 o}(t,n,e)}function g(e){void 0===e&&(e={});const t=p(e),{pathname:n}=(0,r.TH)();if(!t)return;return{activePlugin:t,activeVersion:l(t.pluginData,n)}}function m(e){return f(e).versions}function h(e){const t=f(e);return s(t)}function b(e){const t=f(e),{pathname:n}=(0,r.TH)();return c(t,n)}function v(e){const t=f(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("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"}))}},8888:(e,t,n)=>{"use strict";n.d(t,{Z:()=>At});var r=n(7294),a=n(6010),o=n(4763),i=n(833),s=n(7462),l=n(6550),c=n(5999),u=n(5936);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,l.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const g=(0,c.I)({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 m(e){const t=e.children??g,{containerRef:n,onClick:a}=p();return r.createElement("div",{ref:n,role:"region","aria-label":g},r.createElement("a",(0,s.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(m,{className:v.skipToContent})}var w=n(6668),k=n(9689);function E(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...l}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 15 15",width:t,height:n},l),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const _={closeButton:"closeButton_CVFx"};function S(e){return r.createElement("button",(0,s.Z)({type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",_.closeButton,e.className)}),r.createElement(E,{width:14,height:14,strokeWidth:3.1}))}const x={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,s.Z)({},e,{className:(0,a.Z)(x.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function L(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(S,{onClick:n,className:T.announcementBarClose}))}var A=n(3163),R=n(2466);var O=n(902),P=n(3102);const N=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,A.e)(),t=(0,P.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,O.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(N.Provider,{value:n},t)}function D(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(N);if(!e)throw new O.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,P.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:D(o)})),[a,o,t])}function j(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var F=n(2949),B=n(2389);function z(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("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 U(e){return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("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 $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const s=(0,B.Z)(),l=(0,c.I)({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"===o?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!s&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!s,title:l,"aria-label":l,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const H=r.memo(q),G={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,F.I)();return a?null:r.createElement(H,{className:t,buttonClassName:"dark"===n?G.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,A.e)();return r.createElement("button",{type:"button","aria-label":(0,c.I)({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()},r.createElement(E,{color:"var(--ifm-color-emphasis-600)"}))}function Y(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(K,null))}var Q=n(9960),X=n(4996),J=n(3919),ee=n(8022),te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:l,isDropdownLink:c,prependBaseUrlToHref:u,...d}=e;const f=(0,X.Z)(a),p=(0,X.Z)(t),g=(0,X.Z)(o,{forcePrependBaseUrl:!0}),m=i&&o&&!(0,J.Z)(o),h=l?{dangerouslySetInnerHTML:{__html:l}}:{children:r.createElement(r.Fragment,null,i,m&&r.createElement(te.Z,c&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,s.Z)({href:u?g:o},d,h)):r.createElement(Q.Z,(0,s.Z)({to:f,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?(0,ee.F)(n,t.pathname):t.pathname.startsWith(p)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,s.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,s.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,s.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),se=n(8596),le=n(2263);function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!(0,ee.F)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:o,onClick:i,...l}=e;const c=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!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]),r.createElement("div",{ref:c,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(ne,(0,s.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:l.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},l,{onClick:l.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),l.children??l.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(qe,(0,s.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...c}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,le.Z)(),{pathname:t}=(0,l.TH)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:g}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&g(!d)}),[u,d,g]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":f})},r.createElement(ne,(0,s.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},c,{onClick:e=>{e.preventDefault(),p()}}),c.children??c.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f},t.map(((e,t)=>r.createElement(qe,(0,s.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function fe(e){let{mobile:t=!1,...n}=e;const a=t?de:ue;return r.createElement(a,n)}var pe=n(4711);function ge(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,s.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("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 me="iconLanguage_nlXk";function he(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var be=n(830),ve=["translations"];function ye(){return ye=Object.assign||function(e){for(var t=1;te.length)&&(t=e.length);for(var n=0,r=new Array(t);n=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var _e="Ctrl";var Se=r.forwardRef((function(e,t){var n=e.translations,a=void 0===n?{}:n,o=Ee(e,ve),i=a.buttonText,s=void 0===i?"Search":i,l=a.buttonAriaLabel,c=void 0===l?"Search":l,u=we((0,r.useState)(null),2),d=u[0],f=u[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?f("\u2318"):f(_e))}),[]),r.createElement("button",ye({type:"button",className:"DocSearch DocSearch-Button","aria-label":c},o,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(be.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},s)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==d&&r.createElement(r.Fragment,null,r.createElement("kbd",{className:"DocSearch-Button-Key"},d===_e?r.createElement(he,null):d),r.createElement("kbd",{className:"DocSearch-Button-Key"},"K"))))})),xe=n(5742),Ce=n(6177),Te=n(239),Le=n(3320);var Ae=n(3935);const Re={button:{buttonText:(0,c.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,c.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,c.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,c.I)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,c.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,c.I)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,c.I)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,c.I)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,c.I)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,c.I)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,c.I)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,c.I)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,c.I)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,c.I)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,c.I)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,c.I)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,c.I)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,c.I)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,c.I)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Oe=null;function Pe(e){let{hit:t,children:n}=e;return r.createElement(Q.Z,{to:t.url},n)}function Ne(e){let{state:t,onClose:n}=e;const a=(0,Ce.M)();return r.createElement(Q.Z,{to:a(t.query),onClick:n},r.createElement(c.Z,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits}},"See all {count} results"))}function Ie(e){let{contextualSearch:t,externalUrlRegex:a,...o}=e;const{siteMetadata:i}=(0,le.Z)(),c=(0,Te.l)(),u=function(){const{locale:e,tags:t}=(0,Le._q)();return[`language:${e}`,t.map((e=>`docusaurus_tag:${e}`))]}(),d=o.searchParameters?.facetFilters??[],f=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(u,d):d,p={...o.searchParameters,facetFilters:f},g=(0,l.k6)(),m=(0,r.useRef)(null),h=(0,r.useRef)(null),[b,v]=(0,r.useState)(!1),[y,w]=(0,r.useState)(void 0),k=(0,r.useCallback)((()=>Oe?Promise.resolve():Promise.all([n.e(1426).then(n.bind(n,1426)),Promise.all([n.e(532),n.e(6945)]).then(n.bind(n,6945)),Promise.all([n.e(532),n.e(8894)]).then(n.bind(n,8894))]).then((e=>{let[{DocSearchModal:t}]=e;Oe=t}))),[]),E=(0,r.useCallback)((()=>{k().then((()=>{m.current=document.createElement("div"),document.body.insertBefore(m.current,document.body.firstChild),v(!0)}))}),[k,v]),_=(0,r.useCallback)((()=>{v(!1),m.current?.remove()}),[v]),S=(0,r.useCallback)((e=>{k().then((()=>{v(!0),w(e.key)}))}),[k,v,w]),x=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.F)(a,t)?window.location.href=t:g.push(t)}}).current,C=(0,r.useRef)((e=>o.transformItems?o.transformItems(e):e.map((e=>({...e,url:c(e.url)}))))).current,T=(0,r.useMemo)((()=>e=>r.createElement(Ne,(0,s.Z)({},e,{onClose:_}))),[_]),L=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",i.docusaurusVersion),e)),[i.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,a=e.onClose,o=e.onInput,i=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?a():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),i&&i.current===document.activeElement&&o&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&o(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,a,o,i])}({isOpen:b,onOpen:E,onClose:_,onInput:S,searchButtonRef:h}),r.createElement(r.Fragment,null,r.createElement(xe.Z,null,r.createElement("link",{rel:"preconnect",href:`https://${o.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})),r.createElement(Se,{onTouchStart:k,onFocus:k,onMouseOver:k,onClick:E,ref:h,translations:Re.button}),b&&Oe&&m.current&&(0,Ae.createPortal)(r.createElement(Oe,(0,s.Z)({onClose:_,initialScrollY:window.scrollY,initialQuery:y,navigator:x,transformItems:C,hitComponent:Pe,transformSearchClient:L},o.searchPagePath&&{resultsFooterComponent:T},o,{searchParameters:p,placeholder:Re.placeholder,translations:Re.modal})),m.current))}function De(){const{siteConfig:e}=(0,le.Z)();return r.createElement(Ie,e.themeConfig.algolia)}const Me={searchBox:"searchBox_ZlJk"};function je(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,Me.searchBox)},t)}var Fe=n(143),Be=n(2802);var ze=n(373);const Ue=e=>e.docs.find((t=>t.id===e.mainDocId));const $e={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,le.Z)(),f=(0,pe.l)(),{search:p,hash:g}=(0,l.TH)(),m=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${g}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(fe,(0,s.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(ge,{className:me}),h),items:m}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(je,{className:n},r.createElement(De,null))},dropdown:fe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const s=i?"li":"div";return r.createElement(s,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,Fe.Iw)(a),l=(0,Be.vY)(t,a);return null===l?null:r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.path===l.path||!!i?.sidebar&&i.sidebar===l.sidebar,label:n??l.id,to:l.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,Fe.Iw)(a),l=(0,Be.oz)(t,a).link;if(!l)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,s.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??l.label,to:l.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,Be.lO)(a)[0],l=t??i.label,c=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,s.Z)({},o,{label:l,to:c}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:f}=(0,l.TH)(),p=(0,Fe.Iw)(n),g=(0,Fe.gB)(n),{savePreferredVersionName:m}=(0,ze.J)(n),h=[...o,...g.map((e=>{const t=p.alternateDocVersions[e.name]??Ue(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...i],b=(0,Be.lO)(n)[0],v=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Ue(b).path;return h.length<=1?r.createElement(oe,(0,s.Z)({},u,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(fe,(0,s.Z)({},u,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function qe(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=$e[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function He(){const e=(0,A.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(qe,(0,s.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ge(e){return r.createElement("button",(0,s.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(c.Z,{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)"},"\u2190 Back to main menu"))}function Ze(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ge,{onClick:()=>t.hide()}),t.content)}function Ve(){const e=(0,A.e)();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?r.createElement(j,{header:r.createElement(Y,null),primaryMenu:r.createElement(He,null),secondaryMenu:r.createElement(Ze,null)}):null}const We={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Ke(e){return r.createElement("div",(0,s.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Ye(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,A.e)(),{navbarRef:s,isNavbarVisible:l}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,R.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+c{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:s,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[We.navbarHideable,!l&&We.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(Ke,{onClick:i.toggle}),r.createElement(Ve,null))}const Qe="right";function Xe(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,s.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function Je(){const{toggle:e,shown:t}=(0,A.e)();return r.createElement("button",{onClick:e,"aria-label":(0,c.I)({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"},r.createElement(Xe,null))}const et={colorModeToggle:"colorModeToggle_x44X"};function tt(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(qe,(0,s.Z)({},e,{key:t})))))}function nt(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function rt(){const e=(0,A.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Qe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(nt,{left:r.createElement(r.Fragment,null,r.createElement("div",null,!e.disabled&&r.createElement(Je,null),r.createElement(W,null),r.createElement(tt,{items:n})),r.createElement("div",null,!o&&r.createElement(je,null,r.createElement(De,null)))),right:r.createElement(r.Fragment,null,r.createElement(tt,{items:a}),r.createElement(Z,{className:et.colorModeToggle}))})}function at(){return r.createElement(Ye,null,r.createElement(rt,null))}function ot(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...l}=t,c=(0,X.Z)(n),u=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,s.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:c},l),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function it(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(ot,{item:t}))}function st(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(it,{key:t,item:e})))))}function lt(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(st,{key:t,column:e}))))}function ct(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function ut(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(ot,{item:t})}function dt(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(ut,{item:e}),t.length!==n+1&&r.createElement(ct,null))))))}function ft(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(lt,{columns:t}):r.createElement(dt,{links:t})}var pt=n(941);const gt={footerLogoLink:"footerLogoLink_BH7S"};function mt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(pt.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function ht(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:gt.footerLogoLink,target:t.target},r.createElement(mt,{logo:t})):r.createElement(mt,{logo:t})}function bt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function vt(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--left"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function yt(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(vt,{style:o,links:n&&n.length>0&&r.createElement(ft,{links:n}),logo:a&&r.createElement(ht,{logo:a}),copyright:t&&r.createElement(bt,{copyright:t})})}const wt=r.memo(yt),kt=(0,O.Qc)([F.S,k.pl,R.OC,ze.L5,i.VC,function(e){let{children:t}=e;return r.createElement(P.n2,null,r.createElement(A.M,null,r.createElement(I,null,t)))}]);function Et(e){let{children:t}=e;return r.createElement(kt,null,t)}var _t=n(8780);const St={errorBoundaryError:"errorBoundaryError_a6uf"};function xt(e){return r.createElement("button",(0,s.Z)({type:"button"},e),r.createElement(c.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function Ct(e){let{error:t}=e;const n=(0,_t.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:St.errorBoundaryError},n)}r.Component;function Tt(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(xt,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(Ct,{error:t})))))}const Lt={mainWrapper:"mainWrapper_z2l0"};function At(e){const{children:t,noFooter:n,wrapperClassName:s,title:l,description:c}=e;return(0,b.t)(),r.createElement(Et,null,r.createElement(i.d,{title:l,description:c}),r.createElement(y,null),r.createElement(L,null),r.createElement(at,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,Lt.mainWrapper,s)},r.createElement(o.Z,{fallback:e=>r.createElement(Tt,e)},t)),!n&&r.createElement(wt,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),s=n(2263),l=n(6668),c=n(941);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},s=a.createElement(c.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},s):s}function d(e){const{siteConfig:{title:t}}=(0,s.Z)(),{navbar:{title:n,logo:c}}=(0,l.L)(),{imageClassName:d,titleClassName:f,...p}=e,g=(0,i.Z)(c?.href||"/"),m=n?"":t,h=c?.alt??m;return a.createElement(o.Z,(0,r.Z)({to:g},p,c?.target&&{target:c.target}),c&&a.createElement(u,{logo:c,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:f},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),s=n(2949);const l={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function c(e){const t=(0,i.Z)(),{colorMode:n}=(0,s.I)(),{sources:c,className:u,alt:d,...f}=e,p=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,p.map((e=>a.createElement("img",(0,r.Z)({key:e,src:c[e],alt:d,className:(0,o.Z)(l.themedImage,l[`themedImage--${e}`],u)},f)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>l,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const s="ease-in-out";function l(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?c:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??s}`,height:`${t}px`}}function l(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function p(e){if(!o.Z.canUseDOM)return e?c:u}function g(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:s,disableSSRStyle:l}=e;const c=(0,a.useRef)(null);return f({collapsibleRef:c,collapsed:n,animation:o}),a.createElement(t,{ref:c,style:l?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(c.current,n),i?.(n))},className:s},r)}function m(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[s,l]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&l(t)}),[o,t]),o?a.createElement(g,(0,r.Z)({},n,{collapsed:s})):null}function h(e){let{lazy:t,...n}=e;const r=t?m:g;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>g,pl:()=>p});var r=n(7294),a=n(2389),o=n(12),i=n(902),s=n(6668);const l=(0,o.WA)("docusaurus.announcement.dismiss"),c=(0,o.WA)("docusaurus.announcement.id"),u=()=>"true"===l.get(),d=e=>l.set(String(e)),f=r.createContext(null);function p(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{o(u())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&d(!1),!r&&u()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(f.Provider,{value:n},t)}function g(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>m});var r=n(7294),a=n(412),o=n(902),i=n(12),s=n(6668);const l=r.createContext(void 0),c="theme",u=(0,i.WA)(c),d={light:"light",dark:"dark"},f=e=>e===d.dark?d.dark:d.light,p=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),g=e=>{u.set(f(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[a,o]=(0,r.useState)(p(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&g(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=u.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(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||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(l.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(l);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h,Oh:()=>y});var r=n(7294),a=n(143),o=n(9935),i=n(6668),s=n(2802),l=n(902),c=n(12);const u=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,c.WA)(u(e),{persistence:t}).set(n)},read:(e,t)=>(0,c.WA)(u(e),{persistence:t}).get(),clear:(e,t)=>{(0,c.WA)(u(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function g(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=g();return r.createElement(p.Provider,{value:n},t)}function h(e){let{children:t}=e;return s.cE?r.createElement(m,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(p);if(!e)throw new l.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{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,a._r)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:a}=t[n];return r.versions.find((e=>e.name===a))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>s});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function s(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function l(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},3163:(e,t,n)=>{"use strict";n.d(t,{M:()=>d,e:()=>f});var r=n(7294),a=n(3102),o=n(7524),i=n(1980),s=n(6668),l=n(902);const c=r.createContext(void 0);function u(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[l,c]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(l)return c(!1),!1}));const u=(0,r.useCallback)((()=>{c((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&c(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:l})),[e,n,u,l])}function d(e){let{children:t}=e;const n=u();return r.createElement(c.Provider,{value:n},t)}function f(){const e=r.useContext(c);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>s,Zo:()=>l,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function s(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,s]=i,l=(0,a.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},6177:(e,t,n)=>{"use strict";n.d(t,{K:()=>s,M:()=>l});var r=n(7294),a=n(2263),o=n(1980);const i="q";function s(){return(0,o.Nc)(i)}function l(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,a.Z)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${i}=${encodeURIComponent(t)}`),[e,n])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>c});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const l=!1;function c(){const[e,t]=(0,r.useState)((()=>l?"ssr":s()));return(0,r.useEffect)((()=>{function e(){t(s())}const n=l?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-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",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:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>f,_F:()=>m,cE:()=>d,hI:()=>k,lO:()=>v,vY:()=>w,oz:()=>y,s1:()=>b});var r=n(7294),a=n(6550),o=n(8790),i=n(143),s=n(373),l=n(1116);function c(e){return Array.from(new Set(e))}var u=n(8596);const d=!!i._r;function f(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=f(t);if(e)return e}}}const p=(e,t)=>void 0!==e&&(0,u.Mg)(e,t),g=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?p(e.href,t):"category"===e.type&&(p(e.href,t)||g(e.items,t))}function h(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,u.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,u.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function b(){const e=(0,l.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?h({sidebarItems:e.items,pathname:t}):null}function v(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>c([t,n,a].filter(Boolean))),[t,n,a])}function y(e,t){const n=v(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 w(e,t){const n=v(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- ${c(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function k(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,s=i.find((e=>(0,a.LX)(r.pathname,e)));if(!s)return null;const l=s.sidebar,c=l?n.docsSidebars[l]:void 0;return{docElement:(0,o.H)(i),sidebarName:l,sidebarItems:c}}},2128:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(2263);function a(e){const{siteConfig:t}=(0,r.Z)(),{title:n,titleDelimiter:a}=t;return e?.trim().length?`${e.trim()} ${a} ${n}`:n}},1980:(e,t,n)=>{"use strict";n.d(t,{Nc:()=>c,Rb:()=>s});var r=n(7294),a=n(6550),o=n(1688),i=n(902);function s(e){!function(e){const t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function l(e){return function(e){const t=(0,a.k6)();return(0,o.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}function c(e){const t=l(e)??"",n=function(){const e=(0,a.k6)();return(0,r.useCallback)(((t,n,r)=>{const a=new URLSearchParams(e.location.search);n?a.set(t,n):a.delete(t),(r?.push?e.push:e.replace)({search:a.toString()})}),[e])}();return[t,(0,r.useCallback)(((t,r)=>{n(e,t,r)}),[n,e])]}},833:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>u,VC:()=>p});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function s(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(4996),c=n(2128);function u(e){let{title:t,description:n,keywords:a,image:i,children:s}=e;const u=(0,c.p)(t),{withBaseUrl:d}=(0,l.C)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),s)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:s},r.createElement(o.Z,null,r.createElement("html",{className:s})),n)}function p(e){let{children:t}=e;const n=s(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>c,Ql:()=>l,i6:()=>s,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class s extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\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 c(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8022:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{F:()=>r})},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>l,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const s=r.createContext(void 0);function l(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 r.createElement(s.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(s);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const u=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(u()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"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 a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>i,_q:()=>l,os:()=>s});var r=n(143),a=n(2263),o=n(373);const i="default";function s(e,t){return`docs-${e}-${t}`}function l(){const{i18n:e}=(0,a.Z)(),t=(0,r._r)(),n=(0,r.WS)(),l=(0,o.Oh)();const c=[i,...Object.keys(t).map((function(e){const r=n?.activePlugin.pluginId===e?n.activeVersion:void 0,a=l[e],o=t[e].versions.find((e=>e.isLast));return s(e,(r??a??o).name)}))];return{locale:e.currentLocale,tags:c}}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>l});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"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,i||(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),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){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}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),s=o===n?e:e.replace(`/${o}/`,"/"),l=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${s}`:`${s}${e}/`}(r)}${l}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},6278:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){const{siteConfig:{themeConfig:e}}=(0,r.Z)();return e}},239:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(7294),a=n(8022),o=n(4996),i=n(6278);function s(){const{withBaseUrl:e}=(0,o.C)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,i.L)();return(0,r.useCallback)((r=>{const o=new URL(r);if((0,a.F)(t,o.href))return r;const i=`${o.pathname+o.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(i,n))}),[e,t,n])}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>p,PP:()=>L,Ep:()=>f});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!c)for(;d--;d)i.unshift("..");!c||""===i[0]||i[0]&&a(i[0])||i.unshift("");var g=i.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var s=n(8776);function l(e){return"/"===e.charAt(0)?e:"/"+e}function c(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 d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!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;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,m(),w.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={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 l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var c=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var a=p(n);a&&a!==g&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=l(t),m=l(n),h=0;h{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var c=[n,r,a,o,i,s],u=0;(l=new Error(t.replace(/%s/g,(function(){return c[u++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;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:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}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=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),c=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(c,i(e,u,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{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)*a(Math.random()*t,.1,.95)),t=a(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 a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),c=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),c!=document.body&&u(c,"nprogress-custom-parent"),c.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(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()}}(),l=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,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function c(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;c(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);c(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);_+=E.value.length,E=E.next){var S=E.value;if(t.length>e.length)return;if(!(S instanceof a)){var x,C=1;if(v){if(!(x=o(k,_,e,b))||x.index>=e.length)break;var T=x.index,L=x.index+x[0].length,A=_;for(A+=E.value.length;T>=A;)A+=(E=E.next).value.length;if(_=A-=E.value.length,E.value instanceof a)continue;for(var R=E;R!==t.tail&&(Ad.reach&&(d.reach=I);var D=E.prev;if(P&&(D=l(t,D,P),_+=P.length),c(t,D,C),E=l(t,D,new a(f,h?r.tokenize(O,h):O,y,O)),N&&l(t,E,N),C>1){var M={cause:f+","+g,reach:I};i(e,t,n,E.prev,_,M),d&&M.reach>d.reach&&(d.reach=M.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 l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function c(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\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://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"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.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:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,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+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},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|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|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|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 a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.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|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.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},a.languages.c.string],char:a.languages.c.char,comment:a.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:a.languages.c}}}}),a.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 a.languages.c.boolean,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(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//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+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//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"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,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;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;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("\\[(?:[^[\\]\"']|"+n.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":[n,{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}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={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|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:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.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}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.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:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.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:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.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:a.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"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.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")),a.languages.js=a.languages.javascript,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}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),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(o),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}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;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("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),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__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\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(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.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",quot:'"'},l=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.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:a.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+/},a.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;n0)){var s=f(/^\{$/,/^\}$/);if(-1===s)continue;for(var l=n;l=0&&p(c,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\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,a=r.inside["interpolation-punctuation"],o=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(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function l(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function c(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,l(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=l(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=s(i++,r)););return u[n]=a,n})).join(""),n,r),f=Object.keys(u);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,s=o.indexOf(a);if(-1!==s){++i;var l=o.substring(0,s),d=c(u[a]),p=o.substring(s+a.length),g=[];if(l&&g.push(l),g.push(d),p){var m=[p];e(m),g.push.apply(g,m)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(g)),n+=g.length-1):r.content=g}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,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 d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,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}(a),function(e){function t(e,t){return RegExp(e.replace(//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*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\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*)#?/.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*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\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:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},s=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var l=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(l=i(t[r-1])+l,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",l,null,l)}a.content&&"string"!=typeof a.content&&s(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||s(e.tokens)}))}(a),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],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,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})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.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/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var c=s[l];if("string"==typeof c||c.content&&"string"==typeof c.content){var u=o[a],d=n.tokenStack[u],f="string"==typeof c?c:c.content,p=t(r,u),g=f.indexOf(p);if(g>-1){++a;var m=f.substring(0,g),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(g+p.length),v=[];m&&v.push.apply(v,i([m])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof c?s.splice.apply(s,[l,1].concat(v)):c.content=v}}else c.content&&i(c.content)}return s}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.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"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.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 a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.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:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.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/}),a.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 a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?: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|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)\b/i,{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,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var s={},l=e[r];if(l){function c(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in s))for(var i in a(t,o),s[t]=!0,n[t])s[i]=!0}t(l.require,c),t(l.optional,c),t(l.modify,c)}n[r]=s,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,s){var l=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),c=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(l);i=i.map(c),s=(s||[]).map(c);var u=n(i),d=n(s);i.forEach((function e(n){var r=l[n];t(r&&r.require,(function(t){t in d||(u[t]=!0,e(t))}))}));for(var f,p=r(l),g=u;a(g);){for(var m in f={},g){var h=l[m];t(h&&h.modify,(function(e){e in d&&(f[e]=!0)}))}for(var b in d)if(!(b in u))for(var v in p(b))if(v in u){f[b]=!0;break}for(var y in g=f)u[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,s={},l={};function c(e){if(e in s)return s[e];l[e]=!0;var a,u=[];for(var d in t(e))d in n&&u.push(d);if(0===u.length)a=r(e);else{var f=i(u.map((function(e){var t=c(e);return delete l[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return s[e]=a}for(var u in n)c(u);var d=[];for(var f in l)d.push(s[f]);return i(d)}(p,u,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,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:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n